Assembly : Initial implementation of 'create joint' command.

This commit is contained in:
Paddle
2023-09-14 16:18:28 +02:00
parent c0185ad95c
commit 04a951aeb3
9 changed files with 1165 additions and 6 deletions

View File

@@ -54,3 +54,185 @@ def isDocTemporary(doc):
except AttributeError:
temp = False
return temp
def getObject(full_name):
# full_name is "Assembly.Assembly1.Assembly2.Assembly3.Box.Edge16"
# or "Assembly.Assembly1.Assembly2.Assembly3.Body.pad.Edge16"
# We want either Body or Box.
parts = full_name.split(".")
doc = App.ActiveDocument
if len(parts) < 3:
App.Console.PrintError(
"getObject() in UtilsAssembly.py the object name is too short, at minimum it should be something like 'Assembly.Box.edge16'. It shouldn't be shorter"
)
return None
obj = doc.getObject(parts[-3]) # So either 'Body', or 'Assembly'
if not obj:
return None
if obj.TypeId == "PartDesign::Body":
return obj
elif obj.TypeId == "App::Link":
linked_obj = obj.getLinkedObject()
if linked_obj.TypeId == "PartDesign::Body":
return obj
else: # primitive, fastener, gear ... or link to primitive, fastener, gear...
return doc.getObject(parts[-2])
def getElementName(full_name):
# full_name is "Assembly.Assembly1.Assembly2.Assembly3.Box.Edge16"
# We want either Edge16.
parts = full_name.split(".")
if len(parts) < 3:
# At minimum "Assembly.Box.edge16". It shouldn't be shorter
return ""
return parts[-1]
def getObjsNamesAndElement(obj_name, sub_name):
# if obj_name = "Assembly" and sub_name = "Assembly1.Assembly2.Assembly3.Box.Edge16"
# this will return ["Assembly","Assembly1","Assembly2","Assembly3","Box"] and "Edge16"
parts = sub_name.split(".")
# The last part is always the element name even if empty
element_name = parts[-1]
# The remaining parts are object names
obj_names = parts[:-1]
obj_names.insert(0, obj_name)
return obj_names, element_name
def getFullObjName(obj_name, sub_name):
# if obj_name = "Assembly" and sub_name = "Assembly1.Assembly2.Assembly3.Box.Edge16"
# this will return "Assembly.Assembly1.Assembly2.Assembly3.Box"
objs_names, element_name = getObjsNamesAndElement(obj_name, sub_name)
return ".".join(objs_names)
def getFullElementName(obj_name, sub_name):
# if obj_name = "Assembly" and sub_name = "Assembly1.Assembly2.Assembly3.Box.Edge16"
# this will return "Assembly.Assembly1.Assembly2.Assembly3.Box.Edge16"
return obj_name + "." + sub_name
def extract_type_and_number(element_name):
element_type = ""
element_number = ""
for char in element_name:
if char.isalpha():
# If the character is a letter, it's part of the type
element_type += char
elif char.isdigit():
# If the character is a digit, it's part of the number
element_number += char
else:
break
if element_type and element_number:
element_number = int(element_number)
return element_type, element_number
else:
return None, None
def findElementClosestVertex(selection_dict):
elt_type, elt_index = extract_type_and_number(selection_dict["element_name"])
if elt_type == "Vertex":
return selection_dict["element_name"]
elif elt_type == "Edge":
edge = selection_dict["object"].Shape.Edges[elt_index - 1]
curve = edge.Curve
if curve.TypeId == "Part::GeomCircle":
# For centers, as they are not shape vertexes, we return the element name.
# For now we only allow selecting the center of arcs / circles.
return selection_dict["element_name"]
edge_points = getPointsFromVertexes(edge.Vertexes)
closest_vertex_index, _ = findClosestPointToMousePos(
edge_points, selection_dict["mouse_pos"]
)
vertex_name = findVertexNameInObject(
edge.Vertexes[closest_vertex_index], selection_dict["object"]
)
return vertex_name
elif elt_type == "Face":
face = selection_dict["object"].Shape.Faces[elt_index - 1]
# Handle the circle/arc edges for their centers
center_points = []
center_points_edge_indexes = []
edges = face.Edges
for i, edge in enumerate(edges):
curve = edge.Curve
if curve.TypeId == "Part::GeomCircle":
center_points.append(curve.Location)
center_points_edge_indexes.append(i)
if len(center_points) > 0:
closest_center_index, closest_center_distance = findClosestPointToMousePos(
center_points, selection_dict["mouse_pos"]
)
# Hendle the face vertexes
face_points = getPointsFromVertexes(face.Vertexes)
closest_vertex_index, closest_vertex_distance = findClosestPointToMousePos(
face_points, selection_dict["mouse_pos"]
)
if len(center_points) > 0:
if closest_center_distance < closest_vertex_distance:
# Note the index here is the index within the face! Not the object.
index = center_points_edge_indexes[closest_center_index] + 1
return "Edge" + str(index)
vertex_name = findVertexNameInObject(
face.Vertexes[closest_vertex_index], selection_dict["object"]
)
return vertex_name
return ""
def getPointsFromVertexes(vertexes):
points = []
for vtx in vertexes:
points.append(vtx.Point)
return points
def findClosestPointToMousePos(candidates_points, mousePos):
closest_point_index = None
point_min_length = None
for i, point in enumerate(candidates_points):
length = (mousePos - point).Length
if closest_point_index is None or length < point_min_length:
closest_point_index = i
point_min_length = length
return closest_point_index, point_min_length
def findVertexNameInObject(vertex, obj):
for i, vtx in enumerate(obj.Shape.Vertexes):
if vtx.Point == vertex.Point:
return "Vertex" + str(i + 1)
return ""