I have the user to select certain objects, then I get the selected objects as follows:
Code: Select all
obj = FreeCADGui.Selection.getSelectionEx()[0].SubObjects[0]
My question is, is it possible to store obj as a property of a scripted object?
Code: Select all
obj = FreeCADGui.Selection.getSelectionEx()[0].SubObjects[0]
Yes I did. The thing is that in this case the selected objects are faces or edges, and these do not have a shape property...TheMarkster wrote: ↑Tue Nov 30, 2021 4:34 pm Did you try using Part::PropertyPartShape property types?
Code: Select all
[(obj,subobjectname),(obj2,subobjectname)]
LSL = [(FreeCAD.getDocument('fingerjoint_test').getObject('Sketch003'),u'Edge1'),(FreeCAD.getDocument('fingerjoint_test').getObject('Sketch003'),u'Edge2'),(FreeCAD.getDocument('fingerjoint_test').getObject('Body003'),u'Sketch003.Wire1'),]
Code: Select all
import FreeCAD,FreeCADGui
import Draft
from sympy import Point3D, Line3D
class Revolutepin:
def __init__(self, obj, label, node, reference1, reference2):
#Get the center of mass or the center of the two references
try:
x2 = FreeCAD.Units.Quantity(reference1.Curve.Center[0],FreeCAD.Units.Unit('mm'))
y2 = FreeCAD.Units.Quantity(reference1.Curve.Center[1],FreeCAD.Units.Unit('mm'))
z2 = FreeCAD.Units.Quantity(reference1.Curve.Center[2],FreeCAD.Units.Unit('mm'))
except:
x2 = FreeCAD.Units.Quantity(reference1.CenterOfMass[0],FreeCAD.Units.Unit('mm'))
y2 = FreeCAD.Units.Quantity(reference1.CenterOfMass[1],FreeCAD.Units.Unit('mm'))
z2 = FreeCAD.Units.Quantity(reference1.CenterOfMass[2],FreeCAD.Units.Unit('mm'))
try:
x3 = FreeCAD.Units.Quantity(reference2.Curve.Center[0],FreeCAD.Units.Unit('mm'))
y3 = FreeCAD.Units.Quantity(reference2.Curve.Center[1],FreeCAD.Units.Unit('mm'))
z3 = FreeCAD.Units.Quantity(reference2.Curve.Center[2],FreeCAD.Units.Unit('mm'))
except:
x3 = FreeCAD.Units.Quantity(reference2.CenterOfMass[0],FreeCAD.Units.Unit('mm'))
y3 = FreeCAD.Units.Quantity(reference2.CenterOfMass[1],FreeCAD.Units.Unit('mm'))
z3 = FreeCAD.Units.Quantity(reference2.CenterOfMass[2],FreeCAD.Units.Unit('mm'))
#Calculate the joint´s absolute position:
x = (x2+x3)/2
y = (y2+y3)/2
z = (z2+z3)/2
#Calculate the joint possition relative to it's node (relative offset):
x1 = x-node.absolute_position_X
y1 = y-node.absolute_position_Y
z1 = z-node.absolute_position_Z
obj.addExtension("App::GroupExtensionPython")
#Create scripted object:
obj.addProperty("App::PropertyString","label","Revolute pin","label",1).label = label
obj.addProperty("App::PropertyString","node_label","Revolute pin","node_label",1).node_label = node.label
obj.addProperty("App::PropertyString","joint","Revolute pin","joint",1).joint = 'revolute pin'
obj.addProperty("App::PropertyString","plugin_variables","Revolute pin","plugin_variables",1).plugin_variables = "none"
#pin possition relative to it's node:
obj.addProperty("App::PropertyDistance","relative_offset_X","Relative offset","relative_offset_X",1).relative_offset_X = x1
obj.addProperty("App::PropertyDistance","relative_offset_Y","Relative offset","relative_offset_Y",1).relative_offset_Y = y1
obj.addProperty("App::PropertyDistance","relative_offset_Z","Relative offset","relative_offset_Z",1).relative_offset_Z = z1
#Absolute pin position:
obj.addProperty("App::PropertyDistance","absolute_pin_position_X","Absolute pin position","absolute_pin_position_X",1).absolute_pin_position_X = x
obj.addProperty("App::PropertyDistance","absolute_pin_position_Y","Absolute pin position","absolute_pin_position_Y",1).absolute_pin_position_Y = y
obj.addProperty("App::PropertyDistance","absolute_pin_position_Z","Absolute pin position","absolute_pin_position_Z",1).absolute_pin_position_Z = z
#Animation parameters:
obj.addProperty("App::PropertyEnumeration","animate","Animation","animate")
obj.animate=['false','true']
obj.addProperty("App::PropertyEnumeration","frame","Animation","frame")
obj.frame=['global','local']
obj.addProperty("App::PropertyFloat","force vector multiplier","Animation","force vector multiplier").force_vector_multiplier = 1.0
obj.Proxy = self
#Add joint´s rotation axis. This axis determines the "absolute_pin_orientation_matrix":
p1 = FreeCAD.Vector(x2, y2, z2)
p2 = FreeCAD.Vector(x3, y3, z3)
#Create the rotation axis:
l = Draft.makeLine(p1, p2)
l.Label = 'z: joint: '+ label
l.ViewObject.LineColor = (0.00,0.00,1.00)
l.ViewObject.PointColor = (0.00,0.00,1.00)
l.ViewObject.DrawStyle = u"Dashed"
l.ViewObject.LineWidth = 1.00
l.ViewObject.PointSize = 1.00
#Add the vector to visualize reaction forces
Llength = FreeCAD.Units.Quantity(FreeCAD.ActiveDocument.getObjectsByLabel("X")[0].End[0]/4,FreeCAD.Units.Unit('mm'))
p1 = FreeCAD.Vector(x, y, z)
p2 = FreeCAD.Vector(x+Llength, y+Llength, z+Llength)
d = Draft.makeLine(p1, p2)
d.ViewObject.LineColor = (1.00,0.00,0.00)
d.ViewObject.PointColor = (1.00,0.00,0.00)
d.ViewObject.LineWidth = 1.00
d.ViewObject.PointSize = 1.00
d.ViewObject.EndArrow = True
d.ViewObject.ArrowType = u"Arrow"
d.ViewObject.ArrowSize = str(Llength/75)#+' mm'
d.Label = "jf: "+ label
#absolute orientation:
obj.addProperty("App::PropertyString","absolute_pin_orientation_matrix","Orientation","absolute_pin_orientation_matrix",1).absolute_pin_orientation_matrix = ""#"3, " + str(l1.direction[0]) + ", "+ str(l1.direction[1]) + ", " + str(l1.direction[2]) + ", " +"2, guess"
#relative orientation:
obj.addProperty("App::PropertyString","relative_orientation_matrix","Orientation","relative_orientation_matrix",1).relative_orientation_matrix = ""#"3, " + str(l1.direction[0]) +", "+ str(l1.direction[1]) + ", " + str(l1.direction[2]) + ", " +"2, guess"
def execute(self, fp):
#precission = int(FreeCAD.ActiveDocument.getObjectsByLabel('MBDyn')[0].precision)#Max number of decimal places
##############################################################################Calculate the new absolute orientation:
ZZ = FreeCAD.ActiveDocument.getObjectsByLabel("z: joint: "+fp.label)[0]#get the joint´s rotation axis
#Two 3D points that define the joint´s line:
p1, p2 = Point3D(ZZ.Start[0], ZZ.Start[1], ZZ.Start[2]), Point3D(ZZ.End[0], ZZ.End[1], ZZ.End[2])
l1 = Line3D(p1, p2)#Line that defines the joint
magnitude = (l1.direction[0]**2+l1.direction[1]**2+l1.direction[2]**2)**0.5#Calculate the vector´s magnitude
#generate the orientation matrix:
fp.absolute_pin_orientation_matrix = "3, "+ str(l1.direction[0]/magnitude) +", "+ str(l1.direction[1]/magnitude) + ", " + str(l1.direction[2]/magnitude) + ", " +"2, guess"
##############################################################################Recalculate the offset, in case the node was moved:
#get and update the absolute pin position:
x = FreeCAD.Units.Quantity((ZZ.Start[0] + ZZ.End[0])/2,FreeCAD.Units.Unit('mm'))
y = FreeCAD.Units.Quantity((ZZ.Start[1] + ZZ.End[1])/2,FreeCAD.Units.Unit('mm'))
z = FreeCAD.Units.Quantity((ZZ.Start[2] + ZZ.End[2])/2,FreeCAD.Units.Unit('mm'))
fp.absolute_pin_position_X = x
fp.absolute_pin_position_Y = y
fp.absolute_pin_position_Z = z
#get the node:
node = FreeCAD.ActiveDocument.getObjectsByLabel("structural: "+fp.node_label)[0]
#Re-calculate the joint possition relative to it's node (relative offset)
x1 = x - node.absolute_position_X
y1 = y - node.absolute_position_Y
z1 = z - node.absolute_position_Z
#Update the offset:
fp.relative_offset_X = x1
fp.relative_offset_Y = y1
fp.relative_offset_Z = z1
##############################################################################Calculate the new relative orientation:
zz = FreeCAD.ActiveDocument.getObjectsByLabel("z: joint: "+fp.label)[0]
p11, p22 = Point3D(zz.Start[0], zz.Start[1], zz.Start[2]), Point3D(zz.End[0], zz.End[1], zz.End[2])
l11 = Line3D(p11, p22)
zzmagnitude1 = (l11.direction[0]**2+l11.direction[1]**2+l11.direction[2]**2)**0.5
#generate the relative orientation matrix:
#fp.relative_orientation_matrix = "3, "+ str(round(l1.direction[0]/zzmagnitude,precission)) +", "+ str(round(l1.direction[1]/zzmagnitude,precission)) + ", " + str(round(l1.direction[2]/zzmagnitude,precission)) + ", " +"2, "+ str(round(l2.direction[0]/yymagnitude,precission)) +", "+ str(round(l2.direction[1]/yymagnitude,precission)) + ", " + str(round(l2.direction[2]/yymagnitude,precission))
fp.relative_orientation_matrix = "3, "+ str(l11.direction[0]/zzmagnitude1) +", "+ str(l11.direction[1]/zzmagnitude1) + ", " + str(l11.direction[2]/zzmagnitude1) + ", " +"2, guess"#+ str(round(l2.direction[0]/yymagnitude,precission)) +", "+ str(round(l2.direction[1]/yymagnitude,precission)) + ", " + str(round(l2.direction[2]/yymagnitude,precission))
FreeCAD.Console.PrintMessage("REVOLUTE PIN JOINT: " +fp.label+" successful recomputation...\n")
Code: Select all
obj.addProperty("Part::PropertyPartShape","reference_1","References","reference_1").reference_1 = reference1
obj.addProperty("Part::PropertyPartShape","reference_2","References","reference_2").reference_2 = reference2
Code: Select all
class FP:
def __init__(self,obj):
obj.addProperty("App::PropertyLinkSub","Edges")
obj.Proxy = self
def execute(self,fp):
if not fp.Edges:
return
object = fp.Edges[0]
edges = fp.Edges[1]
FreeCAD.Console.PrintMessage(f"Object name: {object.Name}, edges: {edges}\n")
subs = [object.getSubObject(sub) for sub in edges]
comp = FreeCAD.ActiveDocument.getObject("Shape")
comp.Shape = Part.makeCompound(subs)
if not FreeCAD.ActiveDocument:
FreeCAD.newDocument()
fp = FreeCAD.ActiveDocument.addObject("App::FeaturePython","FP")
FP(fp)
box = FreeCAD.ActiveDocument.addObject("Part::Box","box")
box.ViewObject.Visibility = False
fp.Edges = (box,["Edge1","Edge2","Face2"])
comp = FreeCAD.ActiveDocument.addObject("Part::Feature","Shape")
FreeCAD.ActiveDocument.recompute()
Code: Select all
class FP:
def __init__(self, obj):
obj.addProperty("App::PropertyLinkSub","reference_1","References","reference_1")
obj.addProperty("App::PropertyLinkSub","reference_2","References","reference_2")
obj.Proxy = self
Code: Select all
fp = FreeCAD.ActiveDocument.addObject("App::FeaturePython","FP")
FP(fp)
Code: Select all
fp.reference_1 = (FreeCADGui.Selection.getSelection()[0],FreeCADGui.Selection.getSelectionEx()[0].SubElementNames[0])
fp.reference_2 = (FreeCADGui.Selection.getSelection()[0],FreeCADGui.Selection.getSelectionEx()[0].SubElementNames[1])