Manual:Creating parametric objects/it

Nel precedente capitolo, abbiamo visto come creare una geometria Parte, e come visualizzarla sullo schermo, collegandola ad un document object "muto" (non parametrico). Questo è noioso quando vogliamo cambiare la forma di tale oggetto. Dovremmo creare una nuova forma, poi attribuirla di nuovo al nostro oggetto.

Ma, in tutti i capitoli precedenti di questo manuale abbiamo visto anche quanto sono potenti gli oggetti parametrici. Basta cambiare una loro proprietà, e la forma viene ricalcolata al volo.

Internamente, gli oggetti parametrici non fanno nulla di diverso da quello che abbiamo appena fatto: essi ricalcolano i contenuti delle loro proprietà Shape, più e più volte, ogni volta che viene cambiata una proprietà.

FreeCAD fornisce un sistema molto vantaggioso per costruire questi oggetti parametrici completamente in Python. Esso consiste in una semplice classe Python, che definisce tutte le proprietà di cui l'oggetto ha bisogno, e che cosa succede quando una di queste proprietà cambia. La struttura di questo oggetto parametrico è semplice come questa:

class myParametricObject: def __init__(self,obj): obj.Proxy = self obj.addProperty("App::PropertyFloat","MyLength") ...  def execute(self,obj): print ("Recalculating the shape...") print ("The value of MyLength is:") print (obj.MyLength) ...

Tutte le classi Python di solito hanno un metodo __init__. Ciò che è all'interno di tale metodo viene eseguito quando tale classe viene istanziata (il che significa, in gergo di programmazione, che da quella classe è stato creato un Object Python. Pensate a una classe come a un "modello" per creare copie dal vivo di esso). Nella nostra funzione __init__  qui facciamo due cose importanti: 1- memorizzare la nostra classe stessa nell'attributo "Proxy" del nostro oggetto del documento di FreeCAD, vale a dire, l'oggetto documento FreeCAD conterrà questo codice al suo interno, and 2- creare tutte le proprietà necessarie all'oggetto. Sono disponibili molti tipi di proprietà, è possibile ottenere l'elenco completo digitando questo codice:

FreeCAD.ActiveDocument.addObject("Part::FeaturePython","dummy").supportedProperties

Then, the second important part is the execute method. Any code in this method will be executed when the object is marked to be recomputed, which will happen when a property has been changed. That is all there is to it. Inside execute, you need to do all that needs to be done, that is, calculating a new shape, and attributing to the object itself with something like obj.Shape = myNewShape. That is why the execute method takes an "obj" argument, which will be the FreeCAD document object itself, so we can manipulate it inside our python code.

Un'ultima cosa importante da ricordare: se si creano questi oggetti parametrici in un documento di FreeCAD, quando si salva il file, il codice Python di cui sopra non viene memorizzato nel file. Questo viene fatto per motivi di sicurezza. Se un file di FreeCAD contenesse del codice, sarebbe possibile che qualcuno distribuisca dei file di FreeCAD contenenti del codice dannoso che potrebbe danneggiare i computer di altri. Quindi, se si distribuisce un file che contiene degli oggetti realizzati con il codice di cui sopra, tale codice deve essere presente anche sul computer che apre il file. Il modo più semplice per raggiungere questo obiettivo è di solito quello di salvare il codice di cui sopra in una macro, e poi distribuire la macro insieme con il file FreeCAD o condividere la macro nel FreeCAD macros repository dove chiunque può scaricarlo.

Ora faremo un piccolo esercizio, costruiremo un oggetto parametrico composto da una semplice faccia rettangolare parametrica. Esempi più complessi sono disponibili negli esempi di oggetti parametrici e nello stesso codice sorgente di FreeCAD.

Diamo al nostro oggetto due proprietà: Length e Width, che useremo per costruire un rettangolo. Poi, dato che l'oggetto ha già una proprietà Placement pre-costruita (tutti gli oggetti geometrici ne hanno una di default, quindi non è necessario aggiungerla), collochiamo il rettangolo nella posizione e rotazione impostata in Placement, per fare in modo che l'utente possa poi essere in grado di spostare il rettangolo ovunque desideri modificando solo la proprietà Placement.

class ParametricRectangle: def __init__(self,obj): obj.Proxy = self obj.addProperty("App::PropertyFloat","Length") obj.addProperty("App::PropertyFloat","Width") def execute(self,obj): # we need to import the FreeCAD module here too, because we might be running out of the Console # (in a macro, for example) where the FreeCAD module has not been imported automatically import Part,FreeCAD # first we need to make sure the values of Length and Width are not 0 # otherwise the Part.Line will complain that both points are equal if (obj.Length == 0) or (obj.Width == 0): # if yes, exit this method without doing anything return # we create 4 points for the 4 corners v1 = FreeCAD.Vector(0,0,0) v2 = FreeCAD.Vector(obj.Length,0,0) v3 = FreeCAD.Vector(obj.Length,obj.Width,0) v4 = FreeCAD.Vector(0,obj.Width,0) # we create 4 edges e1 = Part.Line(v1,v2).toShape e2 = Part.Line(v2,v3).toShape e3 = Part.Line(v3,v4).toShape e4 = Part.Line(v4,v1).toShape # we create a wire w = Part.Wire([e1,e2,e3,e4]) # we create a face f = Part.Face(w) # All shapes have a Placement too. We give our shape the value of the placement # set by the user. This will move/rotate the face automatically. f.Placement = obj.Placement # all done, we can attribute our shape to the object! obj.Shape = f

Invece di incollare il codice precedente nella console Python, è meglio salvarlo da qualche parte, in modo da poterlo riutilizzare e modificare in un secondo tempo. Per esempio in una nuova macro (menu Strumenti -> Macro -> Crea). Dargli un nome, ad esempio, "ParamRectangle". Le macro FreeCAD vengono salvate con estensione .FCMacro, che però Python non riconosce quando si utilizza l'importazione. Quindi, prima di utilizzare il codice di cui sopra, bisogna rinominare il file ParamRectangle.FCMacro in ParamRectangle.py. Questo può essere fatto semplicemente, navigando con il file explorer nella cartella delle macro indicata nel menu Strumenti -> Macro.

Dopo, nella console Python possiamo fare questo:

import ParamRectangle

Esplorando i contenuti di ParamRectangle, possiamo verificare che contenga la nostra classe ParamRectangle.

Per creare un nuovo oggetto parametrico utilizzando la nostra classe ParametricRectangle, usiamo il seguente codice. Notare che usiamo Part::FeaturePython invece di Part::Feature che abbiamo usato nei capitoli precedenti (The Python version allows to define our own parametric behaviour):

myObj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Rectangle") ParamRectangle.ParametricRectangle(myObj) myObj.ViewObject.Proxy = 0 # this is mandatory unless we code the ViewProvider too FreeCAD.ActiveDocument.recompute

Sullo schermo non appare ancora nulla perché le proprietà lunghezza e larghezza sono 0, e questo attiva la condizione "do-nothing" (non fare nulla) dentro execute. Basta cambiare i valori di lunghezza e larghezza, e magicamente appare il nostro oggetto ricalcolato al-volo.

Naturalmente è noioso dover digitare queste 4 righe di codice Python ogni volta che si vuole creare un nuovo rettangolo parametrico. Un modo molto semplice per risolvere questo consiste nel mettere le 4 righe di cui sopra all'interno del file ParamRectangle.py, alla fine, dopo la fine della classe ParametricRectange (Possiamo farlo dall'editor delle Macro).

Ora, quando si digita import ParamRectangle, viene automaticamente creato un nuovo rettangolo parametrico. Ancora meglio, siamo in grado di aggiungere un pulsante della barra degli strumenti che faccia proprio questo:


 * Aprire il menu Strumenti -> Personalizza
 * Nella scheda "Macro", selezionare la macro ParamRectangle.py, compilare la descrizione come si desidera, e premere "Aggiungi":


 * Nella scheda Barra degli strumenti, creare una nuova barra degli strumenti personalizzata in un ambiente a scelta (o in quello globale), selezionare la macro e aggiungerla alla barra degli strumenti:




 * Questo è tutto, ora nella barra degli strumenti abbiamo un nuovo pulsante che, se cliccato, crea un rettangolo parametrico.

Remember, if you want to distribute files created with this new tool to other people, they must have the ParamRectangle.py macro installed on their computer too.

Approfondimenti


 * Il repositorio delle macro di FreeCAD
 * Esempi di oggetti parametrici
 * Altri esempi nel codice di FreeCAD