Nuova versione Guida allo Scripting

Forum per le domande e le discussioni in Italiano
Forum rules
regole del forum e le informazioni utili

Importante: PRIMA di chiedere aiuto leggete qui!
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Nuova versione Guida allo Scripting

Post by onekk »

in che senso?

vuoi passare le coordinate alla ffunzione placement?

Code: Select all

import Part
class Document():
	def __init__(self, doc):
		self.doc = doc
	def create(self):
		App.newDocument()
		App.setActiveDocument("" + self.doc + "")
		App.ActiveDocument=App.getDocument("" + self.doc + "")
		Gui.ActiveDocument=Gui.getDocument("" + self.doc + "")
	def refresh(self):
		App.ActiveDocument.recompute()
		Gui.SendMsgToActiveView("ViewFit")
		Gui.activeDocument().activeView().viewIsometric()

class box():
	def __init__(self, name):
		self.name = name
		self.obj = None
	def create(self, height, length, width):	
		box = App.ActiveDocument.addObject("Part::Box", self.name)
		box.Height = height
		box.Length = length
		box.Width = width
		self.obj = box
	def placement(self, placement=App.Placement(App.Vector(1,1,1),App.Rotation(0,0,0,1))):
		self.obj.Placement = placement

doc = Document("Unnamed")
doc.create()
box1 = box("box1")
box1.create(10,20,60)
box1.placement(FreeCAD.Placement(App.Vector(10,10,10), App.Rotation(45,0,0)))
doc.refresh()

Nel modo con cui lo hai scritto tu self.obj era la stringa che passavi alla funzione cioè il nome, ora è il riferimento all'oggetto.

La posizione di default è usata se non specifichi un placement alternativo.

qui python2 e python3 proprio non c'entrano nulla.

Spero di aver capito il tuo quesito

Saluti

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Luixx
Posts: 213
Joined: Thu Jan 25, 2018 9:12 am

Re: Nuova versione Guida allo Scripting

Post by Luixx »

ok ti ringrazio molto proprio quello che mi serviva .. vado avanti con altre funzioni.. ti ringrazio molto e ora studio le modifiche che mi hai fatto.
grazie mille e buona serata.


EDIT: ho acquistato un corso su python su udemy .. mi studio anche quello e più avanti faccio il mio progetto.
ti ringrazio di nuovo.
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Nuova versione Guida allo Scripting

Post by onekk »

Python è molto complesso, il problema però è che nella sua incarnazione usata in FreCAD, la parte "complicata" non è la programmazione Python in se stessa, piuttosto la parte delle API esposte di FreeCAD.

Da capire è la sua suddivisione in App e Gui, che molte volte genera incomprensioni e difficoltà perché "quello che vedi" è una "interpolazione" della rappresentazione interna del solido fatta dal motore di modellazione.

Altro punto "ostico" che richiede una certa pratica e abitudine è la divisione tra oggetto "Documento" e oggetto del modellatore, che non è proprio semplice semplice da spiegare e alcune volte crea problemi perché un oggetto Documento non sempre espone tutta la parte che un oggetto del modellatore espone.

Ad esempio nella Guida che da il titolo a questo post, l'approccio principale è fatto usando oggetti "Documento" per la semplice ragione che sono più maneggevoli e non devono essere convertiti e "mostrati" esplicitamente alla fine.

Nella revisione avanzata, non appena mi sono accorto della differenza intrinseca e dei problemi dell'approccio basato sugli oggetti "Documento" usati in maniera esclusiva, ho cercato di introdurre e di spiegare sicuramente in modo incompleto e probabilmente anche contorto la distinzione tra i due approcci.

Altro punto critico è la differenza di approccio che trovi nella modellazione CSG e nella modellazione BREP, e qui il discorso si fa ancora più complesso.

Usando la modellazione BREP devi definire ogni faccia dell'oggetto, e qui l'uso di Python si rivela molto utile in quanto molto potente e con funzioni che permettono di scrivere "cose complesse in modo conciso", ad esempio la sua capacità di rappresentare tutto come un "oggetto" e quindi di contenere in una variabile addirittura l'intero disegno.

Tutto questo però si scontra con il fatto che le API non sempre espongono tutta la potenza del modellatore a Python per cui alcune volte sei "limitato" oppure hai difficoltà a implementare quello che deisderi in quanto la funzione che ti servirebbe, semplicemente non c'è ancora nell'API esposta.

Se hai dubbi chiedi pure, lo studio del codice è comunque la cosa migliore, l'uso dei "trucchi" per analizzare quello che è esposto dall'APi risulta molto utile, sia in console python che in uno script.

Dovrai sempre sperimentare e provare perché purtroppo la "documentazione ufficiale" non è affatto completa, in primis perché non siamo ancora arrivati ad una versione "stabile 1.0" di FreeCAD, per cui un dettagliato lavoro rischia di essere tempo speso male.

Secondo aspetto è che molte cose sono legate al motore di modellazione, cioè OCCT e a volte devi andare sulla sua documentazione per capire come "funziona veramente".

Un giretto su https://www.opencascade.com/doc/occt-7. ... orial.html, nei vari esempi e descrizioni a volte risulta molto utile per capire quello che succede dietro le quinte.

Saluti

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Luixx
Posts: 213
Joined: Thu Jan 25, 2018 9:12 am

Re: Nuova versione Guida allo Scripting

Post by Luixx »

ok, va bene.. in tanto studio.. ora ho scritto cosi un'altra classe .. cilindro ma ottengo errore NoneType su Placement.
Ti posto il codice.
un'altra cosa come faccio fare che le due classi box, cilindro sono figlie della classe Document che poi la chiamerò FreeCADzero
Ti posto il codice:

Code: Select all

import FreeCAD
import Part
class Document():
    def __init__(self, doc):
        self.doc = doc
    def create(self):
        App.newDocument()
        App.setActiveDocument("" + self.doc + "")
        App.ActiveDocument=App.getDocument("" + self.doc + "")
        Gui.ActiveDocument=Gui.getDocument("" + self.doc + "")
    def refresh(self):
        App.ActiveDocument.recompute()
        Gui.SendMsgToActiveView("ViewFit")
        Gui.activeDocument().activeView().viewIsometric()

class box():
 	   def __init__(self, name):
 	       self.name = name
 	       self.obj = None
 	   def create(self, height, length, width):    
 	       box = App.ActiveDocument.addObject("Part::Box", self.name)
 	       box.Height = height
 	       box.Length = length
 	       box.Width = width
 	       self.obj = box
 	   def placement(self, placement=App.Placement(App.Vector(1,1,1),App.Rotation(0,0,0,1))):
 	       self.obj.Placement = placement

class cylinder():
	def __init__(self, name):
		self.name  = name
		self.obj = None
	def create(self, radius , height , angle):
		 cylinder = App.ActiveDocument.addObject("Part::Cylinder", self.name)
		 cylinder.Radius = radius
		 cylinder.Height = height
		 cylinder.Angle  = angle
	def placement(self, placement=App.Placement(App.Vector(1,1,1),App.Rotation(0,0,0,1))):
 	       self.obj.Placement = placement
		

doc = Document("Unnamed")
doc.create()
box1 = box("box1")
box1.create(10,20,60)
box1.placement(FreeCAD.Placement(App.Vector(10,10,10), App.Rotation(45,0,0)))

cylinder1 = cylinder("cylinder1")
cylinder1.create(20,10,360)
cylinder1.placement(FreeCAD.Placement(App.Vector(10,10,10), App.Rotation(45,0,0))) # qui errore NoneType di placement
doc.refresh()
grazie mille e buona fine settimana.
Luixx
Posts: 213
Joined: Thu Jan 25, 2018 9:12 am

Re: Nuova versione Guida allo Scripting

Post by Luixx »

risolto avevo scordato : self.obj = cylinder

e poi mi e riuscito fare classe padre e classi figlie.

+ avanti metto il tool fusion e boolean .

grazie mille.
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Nuova versione Guida allo Scripting

Post by onekk »

Vabbeh capita a tutti di scordare le cose.

Una volta capito il trucco non è poi così complicato.

Al solito nel dubbio, chiedi pure, magari non sono fulmineo nella risposta ma leggo il forum almeno ogni paio di giorni.

Saluti

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Luixx
Posts: 213
Joined: Thu Jan 25, 2018 9:12 am

Re: Nuova versione Guida allo Scripting

Post by Luixx »

ok, ti ringrazio .. ultima cosa per il fuse.

sto leggendo il codice aereo.py e mettendolo nel mio.
Ma non riesco ad trascrivere la classe BoolTool e funzione mfuse_obj.
Scrivo cosi:

Code: Select all

import FreeCAD
import Part
class Document():
    def __init__(self, doc):
        self.doc = doc
    def create(self):
        App.newDocument()
        App.setActiveDocument("" + self.doc + "")
        App.ActiveDocument=App.getDocument("" + self.doc + "")
        Gui.ActiveDocument=Gui.getDocument("" + self.doc + "")
    def refresh(self):
        App.ActiveDocument.recompute()
        Gui.SendMsgToActiveView("ViewFit")
        Gui.activeDocument().activeView().viewIsometric()

class box():
 	   def __init__(self, name):
 	       self.name = name
 	       self.obj = None
 	   def create(self, height, length, width):    
 	       box = App.ActiveDocument.addObject("Part::Box", self.name)
 	       box.Height = height
 	       box.Length = length
 	       box.Width = width
 	       self.obj = box
 	   def placement(self, placement=App.Placement(App.Vector(1,1,1),App.Rotation(0,0,0,1))):
 	       self.obj.Placement = placement

class cylinder():
	def __init__(self, name):
		self.name  = name
		self.obj = None
	def create(self, radius , height , angle):
		 cylinder = App.ActiveDocument.addObject("Part::Cylinder", self.name)
		 cylinder.Radius = radius
		 cylinder.Height = height
		 cylinder.Angle  = angle
		 self.obj = cylinder
	def placement(self, placement=App.Placement(App.Vector(1,1,1),App.Rotation(0,0,0,1))):
 	       self.obj.Placement = placement

class BoolTool():
        def mfuse_obj(nome, objs):
            obj = DOC.addObject("Part::MultiFuse", nome)
            obj.Shapes = objs
            obj.Refine = True
            App.ActiveDocument.recompute()
            self.obj = obj
            return obj

doc = Document("Unnamed")
doc.create()
box1 = box("box1")
box1.create(10,20,60)
box1.placement(FreeCAD.Placement(App.Vector(10,10,10), App.Rotation(45,0,0)))

cylinder1 = cylinder("cylinder1")
cylinder1.create(20,10,360)
cylinder1.placement(FreeCAD.Placement(App.Vector(10,10,10), App.Rotation(45,0,0)))

bool1 =  BoolTool()

objs = (box1, cylinder1)

bool1.mfuse_obj('fuse1',objs)

doc.refresh()
Mi da errore cosi:

Code: Select all

17:28:31  Traceback (most recent call last):
  File "D:/nb-desktop/luigi/Documents/FreeCAD/freecadzero.py", line 65, in <module>
    bool1.mfuse_obj('fuse1',objs)
<class 'TypeError'>: mfuse_obj() takes 2 positional arguments but 3 were given
cosa devo fare?
Grazie mille e buona serata.
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Nuova versione Guida allo Scripting

Post by onekk »

Code: Select all

class BoolTool():
        def mfuse_obj(self, nome, objs):
            obj = App.ActiveDocument.addObject("Part::MultiFuse", nome)
            shapes = []
            for name in objs:
                shape = App.ActiveDocument.getObject(name)
                shapes.append(shape)
            obj.Shapes = shapes
            obj.Refine = True
            App.ActiveDocument.recompute()
            self.obj = obj
            return obj

doc = Document("Unnamed")
doc.create()
box1 = box("box1")
box1.create(10,20,60)
box1.placement(FreeCAD.Placement(App.Vector(10,10,10), App.Rotation(45,0,0)))

cylinder1 = cylinder("cylinder1")
cylinder1.create(20,10,360)
cylinder1.placement(FreeCAD.Placement(App.Vector(10,10,10), App.Rotation(45,0,0)))

print(box)

bool1 =  BoolTool()

objs = ("box1", "cylinder1")

bool1.mfuse_obj('fuse1', objs)

Allora, devi passare degli oggetti documento alla funzione obj = App.ActiveDocument.addObject("Part::MultiFuse", nome) nella sua proprietà Shapes.

Per fare questo la via più breve è quella di ricavare l'oggetto documento a partire dal nome, le tue classi non "espongono" l'oggetto documento, per cui lo devi trovare in qualche modo.

Questa implementazione funziona, almeno sulla versione 0.19.

Però implementare delle classi per questo uso mi sembra molto "complicato"

Non mi è chiaro lo scopo di tutto questo.

Se lo scopo finale è quello di creare oggetti, l'approccio che ho illustrato è più maneggevole, se vuoi oggetti complessi da manipolare in modo semplice, ad esempio forme composte, puoi usare semplicemente la creazione di "oggetti shape" che poi accorpi in un oggetto documento come risultante delle operazioni boleane, l'oggetto è quello e bon.

Occupa meno memoria in quanto le "forme originali" sono perse una volta create, rimane in memoria solo "l'oggetto documento" come un oggetto "Part::Feature" che è molto semplice e

Code: Select all

compound = DOC.addObject("Part::Feature", "unione colonne")
compound.Shape = Part.makeCompound(objs)
ha come uniche proprietà Label e Placement, il suo Placement di default è (0,0,0) per cui se lo costruisci accuratamente poi lo manipoli come vuoi.

Accuratamente in teoria sarebbe con il "baricentro" in (0,0,0) che è il modo più "comodo" per poi manipolare gli oggetti.

Altrimenti se hai "oggetti documento" cioè aggiunti al documento con addObjects, questi hanno le proprie caratteristiche e se sono ad esempio un compound puoi ricavare gli "oggetti documento" originali e manipolarle come vuoi.

La differenza sta nell'occupazione di memoria perché il motore di FreeCAD mantiene in memoria gli oggetti solo se sono creati come "oggetto documento".

Un oggetto documento ha la sua proprietà "Shape" che è salvata, se questa è oggetto di operazioni booleane, solo il risultato di queste operazioni è salvato in shape, le "forme originali", una volta usate non sono più disponibili.

O meglio, una volta che crei le "forme" queste sono mantenute in memoria fino a che non le distruggi, ma se le metti all'interno di un metodo (funzione), una volta terminato il metodo tutte le forme create all'interno del metodo e che non passi come oggetto con return vengono dimenticate, le puoi recuperare o come riferimento passato ad esempio con return, oppure se le "consolidi" in un "oggetto documento".

A volte è utile mantenere i componenti di un oggetto complesso altre volte lo è di meno e ti crea solo problemi di intasamento della memoria e di conseguenza di lentezza nell'elaborazione del documento, di ingombro in termini di dimensioni del file.

Altre volte ad esempio se stai sperimentando risulta utile averli a disposizione ad esempio per visualizzarli e capire come vengono creati in origine.

sta a te trovare la strada che ti è più utile.

potresti pensare di costruire la classe di creazione con un metodo debug che crei gli "oggetti documento", quando setti deug=True e non li crei se setti debug=False.

in questo modo hai la possibilità di scegliere al momento dell'esecuzione se avere le "forme originali" visualizzate ad esempio con

Code: Select all

if debug is True:
        ox = lung * 0.5
        oy = larg * 0.5
        V0 = Vector(ox * -1, oy * -1, 0)
        V1 = Vector(ox, oy * -1, 0)
        V2 = Vector(ox, oy, 0)
        V3 = Vector(ox * -1, oy, 0)
        ref_box = Part.makePolygon((V0, V1, V2, V3, V0))
        Part.show(ref_box)
ma questa è una tua scelta.

Spero di non essere stato troppo contorto nella spiegazione.

Saluti

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Luixx
Posts: 213
Joined: Thu Jan 25, 2018 9:12 am

Re: Nuova versione Guida allo Scripting

Post by Luixx »

ok ti posto tutto .. ottengo dei errori :

Code: Select all

13:17:22  <class '__main__.box'>
13:17:22  270.64 <App> Document.cpp(3151): The graph must be a DAG.
13:17:22  <Exception> Input shape is null
13:17:22  270.66 <App> Document.cpp(3151): The graph must be a DAG.
13:17:22  <Exception> Input shape is null
13:17:22  270.711 Tree.cpp(297): [ComboView] duplicate child item Unnamed#bool1.bool1
13:17:22  270.711 Tree.cpp(3412): [ComboView] Cyclic dependency in Unnamed#bool1.Unnamed#bool1
13:17:22  270.711 Tree.cpp(3412): [ComboView] Cyclic dependency in Unnamed#bool1.Unnamed#bool1
13:17:22  270.711 Tree.cpp(297): [ComboView] duplicate child item Unnamed#bool1.bool1
e il codice modificato è questo:

Code: Select all

import FreeCAD
import Part
class Document():
    def __init__(self, doc):
        self.doc = doc
    def create(self):
        App.newDocument()
        App.setActiveDocument("" + self.doc + "")
        App.ActiveDocument=App.getDocument("" + self.doc + "")
        Gui.ActiveDocument=Gui.getDocument("" + self.doc + "")
    def refresh(self):
        App.ActiveDocument.recompute()
        Gui.SendMsgToActiveView("ViewFit")
        Gui.activeDocument().activeView().viewIsometric()

class box():
 	   def __init__(self, name):
 	       self.name = name
 	       self.obj = None
 	   def create(self, height, length, width):    
 	       box = App.ActiveDocument.addObject("Part::Box", self.name)
 	       box.Height = height
 	       box.Length = length
 	       box.Width = width
 	       self.obj = box
 	   def placement(self, placement=App.Placement(App.Vector(1,1,1),App.Rotation(0,0,0,1))):
 	       self.obj.Placement = placement

class cylinder():
	def __init__(self, name):
		self.name  = name
		self.obj = None
	def create(self, radius , height , angle):
		 cylinder = App.ActiveDocument.addObject("Part::Cylinder", self.name)
		 cylinder.Radius = radius
		 cylinder.Height = height
		 cylinder.Angle  = angle
		 self.obj = cylinder
	def placement(self, placement=App.Placement(App.Vector(1,1,1),App.Rotation(0,0,0,1))):
 	       self.obj.Placement = placement

class BoolTool():
         def __init__(self, name):
            self.name = name
            self.obj = None
         def mfuse_obj(self, objs):
            obj = App.ActiveDocument.addObject("Part::MultiFuse", self.name)
            shapes = []
            for name in objs:
                shape = App.ActiveDocument.getObject(self.name)
                shapes.append(shape)
            obj.Shapes = shapes
            obj.Refine = True
            App.ActiveDocument.recompute()
            self.obj = obj
            return obj

doc = Document("Unnamed")
doc.create()
box1 = box("box1")
box1.create(10,20,60)
box1.placement(FreeCAD.Placement(App.Vector(10,10,10), App.Rotation(45,0,0)))

cylinder1 = cylinder("cylinder1")
cylinder1.create(20,10,360)
cylinder1.placement(FreeCAD.Placement(App.Vector(10,10,10), App.Rotation(45,0,0)))

print(box)

bool1 =  BoolTool("bool1")

objs = (box1, cylinder1)

bool1.mfuse_obj(objs)

doc.refresh()

hai mica l'idea? .grazie mille e scusa del ritardo ma fuori c'è il sole.
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Nuova versione Guida allo Scripting

Post by onekk »

Ripeto la domanda, qual'è lo scopo di usare classi costruite come le tue per creare oggetti, si introduce un carico di riferimenti a oggetti in Python totalmente inutile.

Non serve nemmeno a ridurre la quantità di linee di codice, usare una classe, poi è solo una complicazione, negli esempi della guida la creazione di oggetti è illustrata usando i metodi, secondo me bastano quelli.

Alla fine:

- crei "oggetti documento" e bon tutto lì, li hai disponibile e li manipoli cercandoli con le funzioni interne in base al nome, oppure alla Label.

- crei "forme" ovverro oggetti del motore interno, che poi devi mantenere in una "variabile" da usare come "mattoncino lego", oppure la mostri con show() e allora viene trasformata in un "oggetto documento".

Le operazioni intermedie anche complesse, le fai usando funzioni, non ti serve istanziare classi, che sono persistenti e consumano memoria inutilmente.

Una classe in python serve al massimo per creare "nuovi" oggetti documento con caratteristiche proprie, questo non lo ho trattato nella guida, anche perché non ne vedo l'utilità se scrivi "script per la creazione di oggetti".

Se vuoi estendere FreeCAD ad esempio creare un nuovo ogetto, un uovo, creerai la classe "uovo" che esporrà nella GUI i valori da modificare, ma questo esula dallo scopo dello scripting e attiene ai plugin oppure alle macro che sono una cosa "leggermente diversa".

La programmazione in genere "filosoficamente parlando" è molto legata "al fine ultimo" del programma.

Nei miei esempi mi sembra che sia chiaro che il fine ultimo è:

- creare oggetti 3D cercando di automatizzare il più possibile le operazioni ripetitive e generando oggetti complessi dal punto di vista di "solido 3D", non di programma.

Forse però al solito ho intepretato male.

Se mi fai un esempio di quello che vuoi ottenere, lavoriamo su qualcosa di concreto.

al solito se vuoi vedere dove genera errori, usa dei print come nell'esempio.

Ti posso passare il codice funzionante, ho segnato con dei commenti i punti critici eaggiunto alcuni check in giro, solo come esempio possibile di debugging.

Code: Select all

import FreeCAD
import Part

class Document():
    def __init__(self, doc):
        self.doc = doc
    def create(self):
        App.newDocument()
        App.setActiveDocument("" + self.doc + "")
        App.ActiveDocument=App.getDocument("" + self.doc + "")
        Gui.ActiveDocument=Gui.getDocument("" + self.doc + "")

    def refresh(self):
        App.ActiveDocument.recompute()
        Gui.SendMsgToActiveView("ViewFit")
        Gui.activeDocument().activeView().viewIsometric()

class box():
 	   def __init__(self, name):
 	       self.name = name
 	       self.obj = None

 	   def create(self, height, length, width):    
 	       box = App.ActiveDocument.addObject("Part::Box", self.name)
 	       box.Height = height
 	       box.Length = length
 	       box.Width = width

 	       self.obj = box

 	   def placement(self, placement=App.Placement(App.Vector(1,1,1),App.Rotation(0,0,0,1))):
 	       self.obj.Placement = placement

class cylinder():
	def __init__(self, name):
		self.name  = name
		self.obj = None

	def create(self, radius , height , angle):
		 cylinder = App.ActiveDocument.addObject("Part::Cylinder", self.name)
		 cylinder.Radius = radius
		 cylinder.Height = height
		 cylinder.Angle  = angle
		 self.obj = cylinder
	def placement(self, placement=App.Placement(App.Vector(1,1,1),App.Rotation(0,0,0,1))):
 	       self.obj.Placement = placement

class BoolTool():
         def __init__(self, name):
            self.name = name
            self.obj = None

         def mfuse_obj(self, objs):
            shapes = []
            for name in objs:
                shape = App.ActiveDocument.getObject(name) ##Stai passando i nomi non self.name che è nel caso d'esempio "bool1"
                if shape is None:
                    pass
                else:
                    shapes.append(shape)
            print(shapes)
            if shapes is []:
                print("operazione non riuscita, controlla i nomi passati")
                return None
            else:
                obj = App.ActiveDocument.addObject("Part::MultiFuse", self.name)
                obj.Shapes = shapes
                obj.Refine = True
                App.ActiveDocument.recompute()
                self.obj = obj
                return obj

doc = Document("Unnamed")
doc.create()

box1 = box("box1")
print("init box")
box1.create(10,20,60)
print("create box")
box1.placement(FreeCAD.Placement(App.Vector(10,10,10), App.Rotation(45,0,0)))
print("place box")
doc.refresh()
print("refresh1")

cylinder1 = cylinder("cylinder1")
print("init cyl")
cylinder1.create(20,10,360)
print("create cyl")
cylinder1.placement(FreeCAD.Placement(App.Vector(10,10,10), App.Rotation(45,0,0)))
print("place cyl")

bool1 =  BoolTool("bool1")
print("init bool")
objs = ("box1", "cylinder1") ## questi sono i nomi degli oggetti che devi recuperare poi con la funzione App.ActiveDocument.getObject(name) 
bool1.mfuse_obj(objs)
print("fuse objs")

doc.refresh()
print("refresh2")

Saluti

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Post Reply