| Descrizione |
|---|
| Crea una copia di ciascun oggetto selezionato e imposta le sue proprietà su un'espressione collegata all'oggetto originale, rendendolo un clone esplicito e modificabile. Versione macro: 0.1 Ultima modifica: 15-12-2018 Versione FreeCAD: 18 e successive Download: ToolBar Icon Autore: Raph82 |
| Autore |
| Raph82 |
| Download |
| ToolBar Icon |
| Link |
| Raccolta di macro Come installare le macro Personalizzare la toolbar |
| Versione macro |
| 0.1 |
| Data ultima modifica |
| 15-12-2018 |
| Versioni di FreeCAD |
| 18 e successive |
| Scorciatoia |
| Nessuna |
| Vedere anche |
| Espressioni |
Questa macro crea una copia di ciascun oggetto selezionato e imposta le sue proprietà su un'espressione collegata all'oggetto originale, rendendolo un clone esplicito e modificabile.
Questo clone è una copia dell'oggetto originale, come nel comando Modifica → Duplica selezione, ma le sue proprietà sono definite da espressioni.
"Esplicito" perché tutte le proprietà dell'oggetto originale sono visibili. In un oggetto Clone di un Cubo, è possibile vedere la sua Altezza, ad esempio? Quando si utilizza un'espressione per un oggetto Clone, è possibile accedere facilmente alle sue proprietà padre?
"Modificabile" perché, a differenza di un oggetto Clone, è possibile modificare l'espressione di qualsiasi proprietà. Quindi è possibile che l'oggetto cloni solo alcune proprietà del suo genitore, modificando le altre.
Macro_clone_explicit.FCMacro
__Title__ = "clone_explicit"
__Author__ = "Raph82"
__URL__ = "https://freecad.org/index-fr.html"
__Version__ = "0.1"
__Date__ = "2018-12-15" #YYYY-MM-DD
__Comment__ = "This macro creates a copy of the selected objects and sets their properties to an expression linking to the original object, making it an explicit and editable clone"
__Web__ = "https://freecad.org/"
__Wiki__ = "https://wiki.freecad.org/index.php?title=Macro_clone_explicit"
__Icon__ = "https://wiki.freecad.org/images/a/ab/Macro_clone_explicit.png"
__IconW__ = "C:/Users/User Name/AppData/Roaming/FreeCAD/Macro_clone_explicit.png"
__Help__ = "Select at least one object and run the macro to make explicit and editable clone(s)"
__Status__ = "dev"
__Requires__ = "All FreeCAD"
__Communication__ = "https://wiki.freecad.org/index.php?title=User:raph82"
#IMPORTS:
import sys
##################################################
def set_expression(obj, property_to_set, expression):
""""""
try:
print type(obj)
obj.setExpression(property_to_set, expression)
# except 'Base.FreeCADError':
except Exception as detail:
print detail
print type(detail)
if detail['swhat'] == 'Property not found':
App.Console.PrintMessage('Object "{obj}" has no property "{prop}"\r\n'.format(obj=obj.Name, prop=property_to_set))
else:
raise
##################################################
def clone_explicit(mode):
"""Copy the selected objects and sets their properties to an expression, making it an explicit and editable clone.
This clone is called "explicit and editable" because the link with its parent is visible and can be changed in the object properties.
The link to the original object can be either "direct" or "transient", depending on the mode argument:
- a direct clone has expressions pointing to its parent: clone.Length = parent.Length
- a transient clone has expressions pointing to its ancestor. Say parent.Length = Box001.Length. With a transient clone, clone.Length = Box001.Length, whereas with a direct clone, clone.Length = parent.Length.
This indirect link to Box001 (via the parent object) could be severed, accidentally or not, depending on what relationship you're looking for.
If you're lost, try with a direct clone first."""
App.Console.PrintMessage("Start of clone_explicit macro"+"\r\n")
#Current selection check:
sel = FreeCADGui.Selection.getSelection()
App.Console.PrintMessage(str(len(sel))+" object(s) selected\r\n")
if len(sel) != 0:
for i in range(len(sel)):
obj=sel[i]
#copying current object:
App.Console.PrintMessage('Copying "'+obj.Label+'" ('+obj.Name+')\r\n')
obj_copy=App.ActiveDocument.copyObject(obj, False) #https://freecad.org/api/d8/d3e/classApp_1_1Document.html#a08f1d7d90f4a7276a02918fb6445a04a
App.Console.PrintMessage('"'+obj_copy.Label+'" ('+obj_copy.Name+') created\r\n')
if mode == 'direct':
#defining expressions pointing to the original object:
set_expression(obj_copy, 'Placement.Base.x', obj.Name+u'.Placement.Base.x')
set_expression(obj_copy, 'Placement.Base.y', obj.Name+u'.Placement.Base.y')
set_expression(obj_copy, 'Placement.Base.z', obj.Name+u'.Placement.Base.z')
set_expression(obj_copy, 'Placement.Rotation.Angle', obj.Name+u'.Placement.Rotation.Angle')
set_expression(obj_copy, 'Placement.Rotation.Axis.x', obj.Name+u'.Placement.Rotation.Axis.x')
set_expression(obj_copy, 'Placement.Rotation.Axis.y', obj.Name+u'.Placement.Rotation.Axis.y')
set_expression(obj_copy, 'Placement.Rotation.Axis.z', obj.Name+u'.Placement.Rotation.Axis.z')
set_expression(obj_copy, 'Length', obj.Name+u'.Length')
set_expression(obj_copy, 'Width', obj.Name+u'.Width')
set_expression(obj_copy, 'Height', obj.Name+u'.Height')
elif mode == 'transient':
#defining expressions pointing to the utmost original object:
define_transient_expression(obj, obj_copy, 'Placement.Base.x')
define_transient_expression(obj, obj_copy, 'Placement.Base.y')
define_transient_expression(obj, obj_copy, 'Placement.Base.z')
define_transient_expression(obj, obj_copy, 'Placement.Rotation.Angle')
define_transient_expression(obj, obj_copy, 'Placement.Rotation.Axis.x')
define_transient_expression(obj, obj_copy, 'Placement.Rotation.Axis.y')
define_transient_expression(obj, obj_copy, 'Placement.Rotation.Axis.z')
define_transient_expression(obj, obj_copy, 'Length')
define_transient_expression(obj, obj_copy, 'Width')
define_transient_expression(obj, obj_copy, 'Height')
else:
App.Console.PrintError('Programming error: mode value not recognized.\r\n')
App.Console.PrintMessage('('+obj_copy.Label+'" ('+obj_copy.Name+') expressions set\r\n')
FreeCAD.ActiveDocument.recompute()
App.Console.PrintMessage('End of clone_explicit macro\r\n')
else:
App.Console.PrintError('Select at least one object first\r\n')
sel = ""
obj = ""
obj_copy = ""
##################################################
def find_expression(source_object, property_to_define):
""""""
for var_tuple in source_object.ExpressionEngine: #https://forum.freecad.org/viewtopic.php?f=22&t=21950
# .ExpressionEngine returns tuple like [('Placement.Base.z', 'Length')], see https://docs.python.org/2.7/tutorial/datastructures.html#tuples-and-sequences
App.Console.PrintMessage('var_tuple[0]='+var_tuple[0]+'\r\n')
if var_tuple[0] == property_to_define:
return var_tuple[1]
##################################################
def define_transient_expression(source_object, target_object, property_to_define):
""""""
expressions = source_object.ExpressionEngine #https://forum.freecad.org/viewtopic.php?f=22&t=21950
# returns tuple like [('Placement.Base.z', 'Length')], see https://docs.python.org/2.7/tutorial/datastructures.html#tuples-and-sequences
expression = find_expression(source_object, property_to_define)
if expression != None:
# App.Console.PrintMessage("target_object.Name="+target_object.Name+"\r\n")
# App.Console.PrintMessage("property_to_define="+property_to_define+"\r\n")
# App.Console.PrintMessage("expressions[property_to_define]="+expressions[property_to_define]+"\r\n")
set_expression(target_object, property_to_define, expression)
else:
set_expression(target_object, property_to_define, source_object.Name+'.'+property_to_define)
expressions = ""
##################################################
clone_explicit('direct')
#clone_explicit('transient')
Era prevista un'opzione mode. Non è ancora stata implementata. Ora sembra molto più complessa di quanto inizialmente pensato, forse troppo complessa da implementare per me.
L'idea è che si potrebbe preferire uno di questi due comportamenti:
direct,transient.Si noti l'enfasi sulla parola "expressions". Un'espressione è un livello di astrazione su un valore.
Per esempio. Si supponga che l'oggetto padre (quello selezionato prima di eseguire la macro) abbia la proprietà Height impostata sull'espressione Object3.Height * 2.
direct:
Clone.Height = Parent.Height,Object3.Height influenzerebbero sia l'oggetto padre che quello clone,Parent.Height anche' influenzerebbero entrambi gli oggetti:
Parent.Height = Object4.Height * 2 eClone.Height = Parent.Height ancora. * Quando eseguito in modalità transient:Clone.Height = Object3.Height * 2,Object3.Height avrebbero effetto sia sull'oggetto padre che sull'oggetto clone,Parent.Height avrebbero effetto solo sull'oggetto padre:
Parent.Height = Object4.Height * 2 eClone.Height = Object3.Height * 2 ancora.Per ora, la macro viene eseguita con il parametro mode impostato su direct e non viene proposta alcuna scelta all'utente.
Property not found.