Tu sei qui

Revit e Python 2

Prima di rimettere mano alla famiglia SezioneSeduta ecco un aggiornamento su ciò che ho tratto dallo studio della shell RevitPython. Ma ancora prima una breve lista degli accorgimenti utilizzati e trovati con più o meno difficoltà sul web.

Precedentemente ho scritto che come console sarebbe il caso di utilizzare quella fornita da IronPython. In realtà anche questa si è utilizzata nel corso delle mie elucubrazioni in materia addirittura meno efficace di quella fornita dalla shell RevitPython.
Ho trovato due soluzioni altrettanto valide riguardo l'utilizzo di una IDE esterna (software che in fase di programmazione aiuta nello sviluppo del codice) che sono VisualStudio 2010 e SharpDevelop 4.3 (ora in versione beta), scaricabili rispettivamente alle pagine http://www.microsoft.com/en-us/download/details.aspx?id=115 e  http://www.icsharpcode.net/OpenSource/SD/Download/#SharpDevelop4x (file di installazione di 165 e 14.7 MB). Consiglio di installarli entrambi perchè sebbene simili possono presentare più o meno affinità col modus operandi dell'utente: per dare un qualche giudizio quanto più oggettivo VisualStudio presenta una maggiore affinità al progetto IronPython in quanto esiste una add-in di supporto specifica http://pytools.codeplex.com/releases/view/76091, si presenta molto più intuitivo e user-friendly e infine permette la modifica di file senza creare necessariamente un archivio project; SharpDevelop tuttavia presenta dei tool molto interessante per chi è affine alla programmazione C# o VB.NET in quanto permette la conversione in linguaggio Python.

Dopo questa lunga e noiosa digressione apro una piccola parentesi sui tutorial trovati alla pagina TheProvingGround: Nathan's Revit API Notebook del blogger Nathan Miller, responsabile della sezione Development and implementation of computational design systems della NBBJ che tra i suoi motti in homepage presenta la frase "build, faster, smarter and more efficiently".

#consiglio di inserire questo script all'interno di InitScript all'interno della schermata Configure di
InteractivePython Shell poichè inizializza il programma e importa le librerie base. Tuttavia forse è meglio
dichiarare il tuttogni volta o creare un file con l'inizializzazione da aprire ad hoc

import clr
import math
clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.DB import *

app = __revit__.Application

doc = __revit__.ActiveUIDocument.Document

#questa invece rappresenta la struttura base di ogni script, si definisce e descrive una Transaction con nome t
t=Transaction(doc, 'Descrizione')
#si avvia quindi la Transaction t nel database di Revit
t.Start()
#tutto il codice si aggiunge in questa area come ad esempio
print "Hello world!"
#si affida la Transaction t al database di Revit
t.Commit()

http://thebuildingcoder.typepad.com/files/cp3837-l_scripting_revitpythonshell_handout.pdf è una guida molto semplice ma efficace per comprendere la logica dei comandi IronPython per Revit

PS: la funzione  __window__.Close() non funziona correttamente. Poco male sarebbe servita solo a chiudere la console una volta eseguito il codice


Apriamo una nuova Conceptual Mass e quindi la shell di IronPython. Per comodità non dichiarerò più l'inizializzazione dandola per metabolizzata.

Questo primo codice propone la creazione di un singolo punto. Successivamente modificherò il codice tra la riga t.Start() e t.Commit().

t = Transaction(doc, 'Crea punti nella massa concettuale')
t.Start()
 
#definisco variabili arbitrarie per la posizione di x,y e z
x = 10
y = 10
z = 0
 
#e le aggiungo ad una variabile di tipo XYZ
myXYZ = XYZ(x,y,z)
 
#uso questa per definire il reference point
refPoint = doc.FamilyCreate.NewReferencePoint(myXYZ)
 
t.Commit()

Realizzato il punto ho verificato la collocazione nel piano e si osserva che la distanza dagli assi non è 10 bensi 3048. Perchè? Molto semplice la misura è passata in feet. Si risolve dividendo per un fattore di 3048 myXYZ, oppure moltiplicandolo per una serie di variabili precedentemente dichiarate del tipo mm=1/3048, cm=1/304.8, m=1/3.048. Anche queste d'ora in poi le darò per assimilate. Il codice diventa per myXYZ (ipotizzando la misura in cm) myXYZ = XYZ(x,y,z)*cm


Passiamo quindi a qualcosa di più complicato realizzando un doppio ciclo for per la realizzazione di una superficie sinusoidale definita su una griglia x,y con z variabile. Molto importante risulta l'indentatura (latabulazione del codice che si esegue col pulsante TAB) poichè in python non sono previste parentesi graffe come ad esempio per i codici C e Java based

#esegue un ciclo per j crescente fino al grado precisione assegnato all'interno di un altro per i.
Vuol dire che divide in 30 intervalli la larghezza e la lunghezza
larghezza = 1
lunghezza = 1
altezza = 1
precisione=30
seni=10
for i in range(0,precisione):
	for j in range(0,precisione):
		x = i * larghezza/precisione
		y = j * lunghezza/precisione
		z = (altezza*math.cos(i*seni*math.pi/precisione)) + (altezza*math.sin(j*seni*math.pi/precisione))
		#moltiplichiamo nuovamente per cm
		myXYZ = XYZ(x,y,z)*m
		refPoint = doc.FamilyCreate.NewReferencePoint(myXYZ)

 

PS: sembra che IronPython sia sensibile all'ordine dei fattori. Se divido per "precisione" all'inizio (come logico che sia) per il numero i/j che incrementa, sembra come se per la shell il numero diviso sia talmente piccolo da essere assimilabile a 0. Consiglio dunque di dividere sempre quanto più possibile alla fine delle operazioni

 

 

CATEGORIE: 
Technology: 

Commenti

a breve un post specifico sull'interazione con le famiglie. per ora massima priorità alla consegna

E se provassi anche a integrare le riflessioni "pratiche" su Python
con quelle per la consegna?  O a mettere qualcosa dentro?

Diciamo che secondo quanto ho visto fino ad ora questa sarebbe
davvero l'obiettivo ultimo per te, una sintesi intima tra riflessioni
tecniche e "architettoniche". Spero che le letture ti indichino esempi
di questo tipo di integrazione, che è la più preziosa, e se vogliamo
è il "cuore" del corso.

Bravissimo comunque, aspettiamo curiosi!