fix(assembly): extend findPlacement() datum and origin handling (#55) #83
@@ -49,7 +49,9 @@ def activePartOrAssembly():
|
||||
|
||||
def activeAssembly():
|
||||
active_assembly = activePartOrAssembly()
|
||||
if active_assembly is not None and active_assembly.isDerivedFrom("Assembly::AssemblyObject"):
|
||||
if active_assembly is not None and active_assembly.isDerivedFrom(
|
||||
"Assembly::AssemblyObject"
|
||||
):
|
||||
if active_assembly.ViewObject.isInEditMode():
|
||||
return active_assembly
|
||||
|
||||
@@ -59,7 +61,9 @@ def activeAssembly():
|
||||
def activePart():
|
||||
active_part = activePartOrAssembly()
|
||||
|
||||
if active_part is not None and not active_part.isDerivedFrom("Assembly::AssemblyObject"):
|
||||
if active_part is not None and not active_part.isDerivedFrom(
|
||||
"Assembly::AssemblyObject"
|
||||
):
|
||||
return active_part
|
||||
|
||||
return None
|
||||
@@ -120,7 +124,9 @@ def number_of_components_in(assembly):
|
||||
def isLink(obj):
|
||||
# If element count is not 0, then its a link group in which case the Link
|
||||
# is a container and it's the LinkElement that is linking to external doc.
|
||||
return (obj.TypeId == "App::Link" and obj.ElementCount == 0) or obj.TypeId == "App::LinkElement"
|
||||
return (
|
||||
obj.TypeId == "App::Link" and obj.ElementCount == 0
|
||||
) or obj.TypeId == "App::LinkElement"
|
||||
|
||||
|
||||
def isLinkGroup(obj):
|
||||
@@ -375,7 +381,9 @@ def getGlobalPlacement(ref, targetObj=None):
|
||||
if not isRefValid(ref, 1):
|
||||
return App.Placement()
|
||||
|
||||
if targetObj is None: # If no targetObj is given, we consider it's the getObject(ref)
|
||||
if (
|
||||
targetObj is None
|
||||
): # If no targetObj is given, we consider it's the getObject(ref)
|
||||
targetObj = getObject(ref)
|
||||
if targetObj is None:
|
||||
return App.Placement()
|
||||
@@ -520,11 +528,17 @@ def findElementClosestVertex(ref, mousePos):
|
||||
|
||||
for i, edge in enumerate(edges):
|
||||
curve = edge.Curve
|
||||
if curve.TypeId == "Part::GeomCircle" or curve.TypeId == "Part::GeomEllipse":
|
||||
if (
|
||||
curve.TypeId == "Part::GeomCircle"
|
||||
or curve.TypeId == "Part::GeomEllipse"
|
||||
):
|
||||
center_points.append(curve.Location)
|
||||
center_points_edge_indexes.append(i)
|
||||
|
||||
elif _type == "Part::GeomCylinder" and curve.TypeId == "Part::GeomBSplineCurve":
|
||||
elif (
|
||||
_type == "Part::GeomCylinder"
|
||||
and curve.TypeId == "Part::GeomBSplineCurve"
|
||||
):
|
||||
# handle special case of 2 cylinder intersecting.
|
||||
for j, facej in enumerate(obj.Shape.Faces):
|
||||
surfacej = facej.Surface
|
||||
@@ -553,7 +567,9 @@ def findElementClosestVertex(ref, mousePos):
|
||||
if _type == "Part::GeomCylinder" or _type == "Part::GeomCone":
|
||||
centerOfG = face.CenterOfGravity - surface.Center
|
||||
centerPoint = surface.Center + centerOfG
|
||||
centerPoint = centerPoint + App.Vector().projectToLine(centerOfG, surface.Axis)
|
||||
centerPoint = centerPoint + App.Vector().projectToLine(
|
||||
centerOfG, surface.Axis
|
||||
)
|
||||
face_points.append(centerPoint)
|
||||
else:
|
||||
face_points.append(face.CenterOfGravity)
|
||||
@@ -623,7 +639,8 @@ def color_from_unsigned(c):
|
||||
|
||||
def getJointsOfType(asm, jointTypes):
|
||||
if not (
|
||||
asm.isDerivedFrom("Assembly::AssemblyObject") or asm.isDerivedFrom("Assembly::AssemblyLink")
|
||||
asm.isDerivedFrom("Assembly::AssemblyObject")
|
||||
or asm.isDerivedFrom("Assembly::AssemblyLink")
|
||||
):
|
||||
return []
|
||||
|
||||
@@ -763,7 +780,9 @@ def getSubMovingParts(obj, partsAsSolid):
|
||||
|
||||
if isLink(obj):
|
||||
linked_obj = obj.getLinkedObject()
|
||||
if linked_obj.isDerivedFrom("App::Part") or linked_obj.isDerivedFrom("Part::Feature"):
|
||||
if linked_obj.isDerivedFrom("App::Part") or linked_obj.isDerivedFrom(
|
||||
"Part::Feature"
|
||||
):
|
||||
return [obj]
|
||||
|
||||
return []
|
||||
@@ -996,7 +1015,7 @@ def findPlacement(ref, ignoreVertex=False):
|
||||
vtx = getElementName(ref[1][1])
|
||||
|
||||
if not elt or not vtx:
|
||||
# case of whole parts such as PartDesign::Body or App/PartDesign::CordinateSystem/Point/Line/Plane.
|
||||
# Origin objects (App::Line, App::Plane, App::Point)
|
||||
if obj.TypeId == "App::Line":
|
||||
if obj.Role == "X_Axis":
|
||||
return App.Placement(App.Vector(), App.Rotation(0.5, 0.5, 0.5, 0.5))
|
||||
@@ -1005,9 +1024,25 @@ def findPlacement(ref, ignoreVertex=False):
|
||||
if obj.Role == "Z_Axis":
|
||||
return App.Placement(App.Vector(), App.Rotation(-0.5, 0.5, -0.5, 0.5))
|
||||
|
||||
# PartDesign datum planes (including ZTools datums like ZPlane_Mid, ZPlane_Offset)
|
||||
if obj.TypeId == "App::Plane":
|
||||
if obj.Role == "XY_Plane":
|
||||
return App.Placement()
|
||||
if obj.Role == "XZ_Plane":
|
||||
return App.Placement(
|
||||
App.Vector(), App.Rotation(App.Vector(1, 0, 0), -90)
|
||||
)
|
||||
if obj.Role == "YZ_Plane":
|
||||
return App.Placement(
|
||||
App.Vector(), App.Rotation(App.Vector(0, 1, 0), 90)
|
||||
)
|
||||
return App.Placement()
|
||||
|
||||
if obj.TypeId == "App::Point":
|
||||
return App.Placement()
|
||||
|
||||
# PartDesign datum planes
|
||||
if obj.isDerivedFrom("PartDesign::Plane"):
|
||||
if hasattr(obj, "Shape") and obj.Shape.Faces:
|
||||
if hasattr(obj, "Shape") and not obj.Shape.isNull() and obj.Shape.Faces:
|
||||
face = obj.Shape.Faces[0]
|
||||
surface = face.Surface
|
||||
plc = App.Placement()
|
||||
@@ -1015,9 +1050,28 @@ def findPlacement(ref, ignoreVertex=False):
|
||||
if hasattr(surface, "Rotation") and surface.Rotation is not None:
|
||||
plc.Rotation = App.Rotation(surface.Rotation)
|
||||
return obj.Placement.inverse() * plc
|
||||
return obj.Placement
|
||||
|
||||
# PartDesign datum lines
|
||||
if obj.isDerivedFrom("PartDesign::Line"):
|
||||
if hasattr(obj, "Shape") and not obj.Shape.isNull() and obj.Shape.Edges:
|
||||
edge = obj.Shape.Edges[0]
|
||||
points = getPointsFromVertexes(edge.Vertexes)
|
||||
mid = (points[0] + points[1]) * 0.5
|
||||
direction = round_vector(edge.Curve.Direction)
|
||||
plane = Part.Plane(App.Vector(), direction)
|
||||
plc = App.Placement()
|
||||
plc.Base = mid
|
||||
plc.Rotation = App.Rotation(plane.Rotation)
|
||||
return obj.Placement.inverse() * plc
|
||||
return obj.Placement
|
||||
|
||||
# PartDesign datum points
|
||||
if obj.isDerivedFrom("PartDesign::Point"):
|
||||
if hasattr(obj, "Shape") and not obj.Shape.isNull() and obj.Shape.Vertexes:
|
||||
plc = App.Placement()
|
||||
plc.Base = obj.Shape.Vertexes[0].Point
|
||||
return obj.Placement.inverse() * plc
|
||||
return obj.Placement
|
||||
|
||||
return App.Placement()
|
||||
@@ -1080,9 +1134,14 @@ def findPlacement(ref, ignoreVertex=False):
|
||||
if surface.TypeId == "Part::GeomCylinder":
|
||||
centerOfG = face.CenterOfGravity - surface.Center
|
||||
centerPoint = surface.Center + centerOfG
|
||||
centerPoint = centerPoint + App.Vector().projectToLine(centerOfG, surface.Axis)
|
||||
centerPoint = centerPoint + App.Vector().projectToLine(
|
||||
centerOfG, surface.Axis
|
||||
)
|
||||
plc.Base = centerPoint
|
||||
elif surface.TypeId == "Part::GeomTorus" or surface.TypeId == "Part::GeomSphere":
|
||||
elif (
|
||||
surface.TypeId == "Part::GeomTorus"
|
||||
or surface.TypeId == "Part::GeomSphere"
|
||||
):
|
||||
plc.Base = surface.Center
|
||||
elif surface.TypeId == "Part::GeomCone":
|
||||
plc.Base = surface.Apex
|
||||
@@ -1100,7 +1159,8 @@ def findPlacement(ref, ignoreVertex=False):
|
||||
plc.Base = (center_point.x, center_point.y, center_point.z)
|
||||
|
||||
elif (
|
||||
surface.TypeId == "Part::GeomCylinder" and curve.TypeId == "Part::GeomBSplineCurve"
|
||||
surface.TypeId == "Part::GeomCylinder"
|
||||
and curve.TypeId == "Part::GeomBSplineCurve"
|
||||
):
|
||||
# handle special case of 2 cylinder intersecting.
|
||||
plc.Base = findCylindersIntersection(obj, surface, edge, elt_index)
|
||||
@@ -1394,13 +1454,16 @@ def generatePropertySettings(documentObject):
|
||||
commands.append(f"obj.{propertyName} = {propertyValue:.5f}")
|
||||
elif propertyType == "App::PropertyInt" or propertyType == "App::PropertyBool":
|
||||
commands.append(f"obj.{propertyName} = {propertyValue}")
|
||||
elif propertyType == "App::PropertyString" or propertyType == "App::PropertyEnumeration":
|
||||
elif (
|
||||
propertyType == "App::PropertyString"
|
||||
or propertyType == "App::PropertyEnumeration"
|
||||
):
|
||||
commands.append(f'obj.{propertyName} = "{propertyValue}"')
|
||||
elif propertyType == "App::PropertyPlacement":
|
||||
commands.append(
|
||||
f"obj.{propertyName} = App.Placement("
|
||||
f"App.Vector({propertyValue.Base.x:.5f},{propertyValue.Base.y:.5f},{propertyValue.Base.z:.5f}),"
|
||||
f"App.Rotation(*{[round(n,5) for n in propertyValue.Rotation.getYawPitchRoll()]}))"
|
||||
f"App.Rotation(*{[round(n, 5) for n in propertyValue.Rotation.getYawPitchRoll()]}))"
|
||||
)
|
||||
elif propertyType == "App::PropertyXLinkSubHidden":
|
||||
commands.append(
|
||||
|
||||
Reference in New Issue
Block a user