Wednesday, May 25, 2011

Object Material Tool 0.8

Eccomi con uno script per 3DStudioMax che costituisce la raccolta di alcune funzioni che uso normalmente nel mio workflow. Il risultato è questa simpatica (?) pulsantiera con menù a tendina :)


Nel dettaglio:
- "select by instance" seleziona le istanze dell'oggetto selezionato
- "select by material" una shortcut per la funzione già presente ma lentissima
- "select by modifier" seleziona tutti gli oggetti a cui è applicata l'istanza del modificatore selezionato
- "copy modifier" copia un'istanza del modificatore selezionato a tutti gli oggetti con lo stesso materiale
- "rmmod by material" elimina le istanze del modificatore selezionato da tutti gli oggetti con lo stesso materiale
- "rmmod (all instances)" elimina le istanze del modificatore selezionato da tutti gli oggetti in scena
- "rmmod all" elimina il modificatore (anche non istanziato) selezionato da tutti gli oggetti in scena

L'installazione non è ancora implementata, io per ora mi limito a trascinare lo script nella toolbar creando un pulsante ad hoc. Si accettano suggerimenti...

saluti,
pietro

Tuesday, March 29, 2011

Aggiornamento: script per automatizzare il lavoro di VRIMG2EXR

Eccomi qui!
Sono riuscito a rendere lo script indipendente dal file batch e ho pulito un po' il codice...
Cambiamenti:
- si lancia dalla riga di comando con python vrconv.py [nomefile.vrimg]
- è possibile utilizzare caratteri jolly e lo script si occupa da solo di trovare i frames e processarli tutti
- ogni file viene rinominato con nomefile+nomecanale+numeroframe.exr per poter essere facilmente rintracciato
- all'uscita cancella il file di testo utilizzato per la comunicazione con vrimg2exr.exe
- nel caso non aveste vrimg2exr nel PATH, o lo inserite o modificate la riga "vrimg2exr=" con il path completo del file.

ecco il file pronto all'uso: vrconv.zip
Per eseguirlo avete bisogno di Python 3.2

ciao!

Script per automatizzare il lavoro di VRIMG2EXR

Sono di fretta ma posto questo script che ho fatto in python per estrarre in un colpo solo tutti i canali da un file VRIMG. Per ora è lanciato tramite un batch perchè non sono ferratissimo in python e avevo necessità di farlo funzionare, sono aperto a qualunque miglioramento :)
Funziona da interfaccia per vrimg2exr.exe, ora sono proprio di corsa ma posto il codice perchè lo sto usando in questo momento e lavora da dio.

vrconv.bat:
@echo off
rem VRCONV: automatize vrimg conversion to exr,
rem finding all channels and separing them
rem -------- (C) 2011 Pietro Grandi -----------

rem Put here your ../vrimg2exr.exe complete path to find it
set VRAY2EXR=vrimg2exr.exe

rem Requiring info
%VRAY2EXR% -info %1 > %1.INFO.txt
if errorlevel 1 (goto:error)

rem Generate info file
set VRCONV_FILE=%1.INFO.txt
echo cmd: File has been saved as %VRCONV_FILE%
python vrconv.py %VRCONV_FILE%
goto:eof

:error
echo Some error occurred with %VRAY2EXR%


vrconv.py
import sys
import string
import os

name="vrconv"
info_file=sys.argv[1]
vrimg2exr=os.environ["VRAY2EXR"]

print("{1}: Assuming {0} as info file...".format(info_file, name))
print("{0}: vrimg2exr is located in {1}".format(name, vrimg2exr))
f = open(info_file)
k=0

current=f.readline()
v_channels=[()]

# Isolating info between quotes...
while current :
index=current.find('"')
if index!=-1 :
rev_index=current.find('"',index+1)+1 # +1 is to keep quotes
v_channels.append(current[index:rev_index])
k+=1
current=f.readline()

print("{0}: {1} channels found. Extracting...".format(name, k-1))

filename_vrimg=v_channels[1].strip('"')
filename_basic=filename_vrimg.strip('vrimg')

for i in range(2,k) :
print("{0}: Working on {1} channel".format(name,v_channels[i]))
os.system(vrimg2exr+" "+filename_vrimg+" "+"-channel "+v_channels[i])
filename_new=filename_basic+v_channels[i].strip('"')+".exr"
print("{0}: {1} is now {2}".format(name,filename_basic+"exr",filename_new))
os.rename((filename_basic+"exr"),filename_new)

Sunday, February 27, 2011

Blender: il selettore di istanze cresce...

Continua il lavoro sullo script... per quello che serve a me in realtà è già finito.
Ora viene definito un operatore che è possibile utilizzare come shortcut (screen.select_instances()) e che io ho assegnato a "SHIFT+I"
C'è un controllo sulla selezione attiva e un report in console e sulla finestra principale di blender.

Cose da fare: selezionare in base al nome. Non voglio in ogni caso farlo diventare un tool pesante con finestre ed altro: è una piccola utility per uso interno i cui pregi devono essere rapidità e leggerezza.
Chiedo scusa per la scrittura un po' raffazzonata ma ho studiato python giovedì scorso e le API di blender venerdì, tra l'altro le API sono soggette a continui cambiamenti e tanti esempi sul sito non funzionano sempre.

Ecco qui il codice ampliato:


#!BPY
"""
Name: 'Select object instances'
Blender: 256
Group: 'Object'
Tooltip: 'Select object instances'
"""
#author: Pietro Grandi (pietro909.blogspot.com)
#
#Release 0.4
# - now the script is an operator that can be added as a shortcut
# under Preferences->Input->Screen
# - the script performs a control in order to check if there is something active
# - messages are printed in console (verbose output) and as report on the top
#
# TODO: select by name, i'd like to have a popup to choose the selection type.
#


import bpy
class SelectInstances(bpy.types.Operator):
bl_idname = "screen.select_instances"
bl_label = "Select Instances"
def execute(self, context):
top = '[si-0.4]' #intestazione per i messaggi in console
scena = bpy.context.scene #punta alla scena attiva

i = 0 #contatore ciclo for
k = 0 #contatore di oggetti selezionati

sel_obj = bpy.context.active_object #oggetto attivo
if sel_obj == None: #se non ci sono oggetti attivi
print(top+'Error: no object selected') #segnala errore in console
self.report({'ERROR'}, 'no object selected') #segnala nel report
return{'CANCELLED'} #ed esci

#se invece la selezione e' valida continua#
sel_obj_type = sel_obj.data.name #tipo di oggetto selezionato
sel_obj_name = sel_obj.name #nome dell'oggetto selezionato


print(top+'Active object: '+sel_obj_name+' -> '+sel_obj_type)
print('Instances:')

for object in scena.objects: #per ogni oggetto in scena
current_obj = scena.objects[i] #prendi il nome dell'oggetto
if current_obj.data.name == sel_obj_type: #controlla se è del tipo selezionato
print('Selected '+current_obj.name) #stampalo
current_obj.select = True #selezionalo
k+=1
i+=1 #avanza il contatore
print('Total objects found and selected: '+str(k)) #stampa il risultato in console
report_string=str(k)+' instances of '+sel_obj_type+' found'
self.report({'INFO'}, report_string) #e nel report
return {'FINISHED'} #fine

if __name__ == "__main__":
bpy.ops.screen.select_instances()

EDIT: lo script è stato testato con una scena di oltre 2700000 poligoni e circa 8000 istanze per oggetto (cubi, coni, sfere, parallelepipedi)

Friday, February 25, 2011

Blender Script: Selezionare gli oggetti istanziati

Eccomi qui, dopo una lunga pausa.
Finalmente (e dico davvero: FINALMENTE!) ho integrato blender nel mio flusso produttivo, utilizzandolo come software principale in un lavoro nuovo che sto seguendo.

Appena avrò più tempo a disposizione ho intenzione di pubblicare un piccolo studio riguardante l'organizzazione della nuova pipeline, ma per ora sono pieno e soprattutto sto valutando quale motore di rendering entrerà a far parte della squadra una volta pensionato definitivamente 3DStudioMax (Thea e VRay sono i candidati per via dello stato di avanzamento degli exporter di blender).

Comunque... perchè scrivo?
Perchè lavorando con Blender su una scena con numerose istanze ho notato che l'outliner putroppo non ha tutte le funzioni di selezione che offre invece Max. Quindi, in piena filosofia open source, ho deciso di scrivermi degli script per fare questo lavoro :)

Questo è una "beta" di un selettore di istanze: cerca le istanze dell'oggetto attivo e le seleziona. Molto semplice, molto stupido se volete ma anche moooolto comodo.
Appena saprò usare meglio le API di Blender 2.6 voglio espanderlo ed integrare un pop-up.

Naturalmente è a disposizione di chiunque, rilasciato sotto licenza GPL:

# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####


#!BPY
"""
Name: 'Select object instances'
Blender: 256
Group: 'Object'
Tooltip: 'Select object instances'
"""
#author: Pietro Grandi (pietro909.blogspot.com)
#inspired by "atylmo" (http://atylmo.wordpress.com)
#

import bpy

scena = bpy.context.scene #punta alla scena attiva

i = 0 #contatore ciclo for

sel_obj = bpy.context.active_object #oggetto attivo
sel_obj_type = sel_obj.data.name #tipo di oggetto selezionato
sel_obj_name = sel_obj.name #nome dell'oggetto selezionato


print("E' attivo l'oggetto "+sel_obj_name+" di tipo "+sel_obj_type)
print("Istanze:")

for object in scena.objects: #per ogni oggetto in scena
current_obj = scena.objects[i] #prendi il nome dell'oggetto
if current_obj.data.name == sel_obj_type: #controlla se è del tipo selezionato
print("Selezionato "+current_obj.name) #stampalo
current_obj.select = True #selezionalo
i+=1 #avanza il contatore



Sunday, November 7, 2010

Problema di file bloccati sotto Windows 7


Ciao,
scrivo perchè ho appena risolto un problema che non mi ha fatto dormire per una settimana.

Ho appena effettuato l'upgrade (su portatile e fisso) da Windows Vista Ultimate x64 a Windows 7 Home Premium. Non ho mantenuto l'edizione Ultimate per via del costo esagerato, avendo
verificato che le opzioni di utilizzo all'interno di un gruppo di lavoro erano sufficienti per me.

Da qui il problema: dopo aver installato il sistema operativo mi sono ritrovato nell'impossibilità di eseguire il backup (uso Sync'n'Go) e di lavorare su alcuni dei miei files (non tutti). Durante la condivisione delle cartelle poi, non capivo più nulla tra crash, impossibilità a scrivere files, impossibilità a copiare... tutti errori apparentemente random.

L'errore riportato da Sync'n'Go è questo:


Mentre altri programmi (blender, gimp, illustrator) crashavano continuamente durante le operazioni di salvataggio ed importazione.
Premetto di aver cercato di cambiare proprietari, permessi, condivisione, .... ma nulla.

Come ho risolto
Fortunatamente nella mia "paranoia da backup" ho esportato e salvato in una cartella il certificato di crittografia del precedente sistema operativo: è stato sufficiente reimportarlo ed il sistema è tornato a funzionare meglio di prima!

1 - eseguire SEMPRE l'esportazione ed il backup dei certificati, di qualunque tipo! si tratta di semplici file di testo, piccoli ed insignificanti.
2 - avviare certmgr.msc tramite start -> cerca
3 - importare il certificato tramite azione -> tutte le attività -> importa (verrà richiesta la password)

da questo momento, funziona tutto come prima!

Ciao
Pietro

Tuesday, October 12, 2010

Configurare un AP wireless in cascata al modem/router di marche differenti

Nell'ultimo anno ho diviso lo studio con mio padre ed alcuni collaboratori: essendo arrivato per ultimo ho trovato la rete configurata in un certo modo, poco agibile per chi arriva da fuori e per i dispositivi che si dovessero collegare temporaneamente ad internet.

La rete nello specifico era così configurata:
1 modem/router Zyxel P600 collegato alla presa telefonica (ADSL) e dotato di 4 porte Ethernet
1 switch Dlink DES 1008D che prende la linea dal router e la distribuisce alle porte ethernet sparse per lo studio
1 switch/AP wireless Dlink DI-624 che prende la linea dal router tramite un cavo Ethernet di una decina di metri e fornisce la connessione wireless nell'abitazione al piano di sotto
1 server Altos che ospita le unità di archiviazione e backup (utilizzabile solo dai client connessi e configurati via cavo), equipaggiato con WindowsNTServer 2003
1 stampante multifunzione di rete utilizzabile solo dai client connessi e configurati via cavo (Olivetti DColor MF25plus)

La rete prevedeva indirizzi IP fissi e DNS inseriti manualmente in ogni client; questa è una soluzione discreta per le workstation ma ostica per i portatili, per chi usufruisce della linea dall'abitazione e per i collaboratori che temporaneamente si trovano a lavorare in studio. Inoltre le risorse "condivise" lo erano solo per i client connessi via cavo, per cui stampare da un portatile o modificare documenti condivisi era un'operazione inutilmente lunga.

Dopo diversi tentativi e discussioni sono riuscito a:
1 - impostare il DHCP per tutta la rete, tutto gestito dal modem Zyxel in cima alla piramide
2 - rendere visibile la stampante di rete a tutti i client della rete, anche ai dispositivi connessi via wireless
3 - rendere disponibili le risorse di rete (unità condivise sul server e sulla mia workstation) a tutti i client della rete

Questa cosa ha creato dei problemi di sicurezza che sono stati risolti applicando una password WPA all'AP DI624 che permette di navigare in internet e stampare o scannerizzare, e creando degli utenti appositi sul server in grado di accedere alle risorse condivise. In questo modo anche dal soggiorno di casa è possibile accedere alle cartelle di lavoro e modificarle (con i dovuti limiti imposti dal tipo di utente) semplicemente ricordando due password, che possono essere salvate.

Perchè lo sto scrivendo?
perchè ci sono impazzito due settimane: rete lenta, navigazione a singhiozzo, risorse invisibili, stampante nascosta... tutti i problemi erano causati da una configurazione errata dell'AP dlink DI624. Di fatto, non era in grado di riconoscersi client dello Zyxel e di conseguenza quando funzionava perdeva continuamente la linea e non ne voleva sapere di far parte della LAN dello studio! Se aggiungiamo che l'IP di fabbrica apparteneva ad una sottorete diversa dallo Zyxel, capirete perchè ora sono così contento che tutto funzioni :)

Come ho fatto?
il trick, semplicissimo, è il seguente:
1 è necessario attivare il DHCP sul modem/route (zyxel), inserire qui i DNS
2 ci si connette all'AP (dlink) e si cerca la configurazione LAN: qui va inserito un IP differente, appartenente alla sottorete del modem, ed il nome della rete interna allo studio
3 disattiviamo il DHCP dell'AP wireless
4 impostiamo una connessione con l'ISP ad IP dinamico sull'AP: questa cosa non l'ho capita benissimo ma funziona :D

Ora: come avrete capito ho proceduto principalmente a caso ma ha funzionato.