From f23d23f2cffd268b7248b463b2432b618294d717 Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Sat, 23 Nov 2019 20:48:55 -0500 Subject: [PATCH 1/3] Use global coordinates when computing tab shapes This is allows shapes to come from multiple different bodies/parts by transforming them all into the global coordinate system before performing interlock computations. --- lasercut/helper.py | 16 +++++++++++++++- lasercut/tabproperties.py | 7 ++++++- panel/multiplejoins.py | 3 +++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lasercut/helper.py b/lasercut/helper.py index 2982c7c..3ad40bf 100644 --- a/lasercut/helper.py +++ b/lasercut/helper.py @@ -129,6 +129,12 @@ def transform_part(tab_to_add, face): def check_intersect(tab_to_add, face, part_interactor_properties): tab_to_add_transformed = transform_part(tab_to_add, face) part_shape_transformed = part_interactor_properties.freecad_object.Shape + + geo_group = part_interactor_properties.freecad_object.getParentGeoFeatureGroup() + while geo_group is not None: + part_shape_transformed = part_shape_transformed.transformGeometry(geo_group.Placement.toMatrix()) + geo_group = geo_group.getParentGeoFeatureGroup() + #print "volume %f" % part_shape_transformed.common(tab_to_add_transformed).Volume return part_shape_transformed.common(tab_to_add_transformed).Volume > 0.001, tab_to_add_transformed @@ -505,6 +511,14 @@ def __init__(self, properties): self.toAdd = [] self.toRemove = [] + # Relocate the shape into global coordinate space + self.global_shape = properties.freecad_object.Shape + + transform_group = properties.freecad_object.getParentGeoFeatureGroup() + while transform_group is not None: + self.global_shape = self.global_shape.transformGeometry(transform_group.Placement.toMatrix()) + transform_group = transform_group.getParentGeoFeatureGroup() + def reset_add_remove(self): self.toAdd = [] self.toRemove = [] @@ -520,7 +534,7 @@ def get_shape(self, fast_assemble=False): part = assemble_list_element(self.toAdd) else: part = assemble_list_element_fast(self.toAdd) - new_shape = self.properties.freecad_object.Shape + new_shape = self.global_shape if part is not None: new_shape = new_shape.fuse(part) part = assemble_list_element(self.toRemove) diff --git a/lasercut/tabproperties.py b/lasercut/tabproperties.py index 120ef19..bee61a8 100644 --- a/lasercut/tabproperties.py +++ b/lasercut/tabproperties.py @@ -104,4 +104,9 @@ def recomputeInit(self, freecad_obj, freecad_face): x_local, y_length, thickness = helper.get_local_axis(freecad_face) self.thickness = thickness.Length self.y_length = y_length.Length - self.transform_matrix = helper.get_matrix_transform(freecad_face) \ No newline at end of file + self.transform_matrix = helper.get_matrix_transform(freecad_face) + + transform_group = freecad_obj.getParentGeoFeatureGroup() + while transform_group is not None: + self.transform_matrix = transform_group.Placement.toMatrix() * self.transform_matrix + transform_group = transform_group.getParentGeoFeatureGroup() diff --git a/panel/multiplejoins.py b/panel/multiplejoins.py index 9303d20..114a550 100644 --- a/panel/multiplejoins.py +++ b/panel/multiplejoins.py @@ -99,6 +99,8 @@ def preview(self, fp): freecad_obj = document.getObject(cp_part.name) cp_part.recomputeInit(freecad_obj) parts.append(cp_part) + FreeCAD.Console.PrintMessage("Will use part " + cp_part.name + "\n") + FreeCAD.Console.PrintMessage(" Transform is " + str(cp_part.freecad_object.Placement) + " vs " + str(part) + "\n") for tab in fp.faces.lst: cp_tab = copy.deepcopy(tab) @@ -106,6 +108,7 @@ def preview(self, fp): freecad_face = document.getObject(cp_tab.freecad_obj_name).Shape.getElement(cp_tab.face_name) cp_tab.recomputeInit(freecad_obj, freecad_face) tabs.append(cp_tab) + FreeCAD.Console.PrintMessage("Will create tab on face " + cp_tab.freecad_obj_name + "::" + cp_tab.face_name + "\n") computed_parts = make_tabs_joins(parts, tabs) for part in computed_parts: From a00882bc22f97f7d6c1f4a2e77dcc4960f8c0c4d Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Sat, 23 Nov 2019 20:50:31 -0500 Subject: [PATCH 2/3] Use get_local_axis_normalized instead of handrolling it --- lasercut/helper.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lasercut/helper.py b/lasercut/helper.py index 3ad40bf..0cf1941 100644 --- a/lasercut/helper.py +++ b/lasercut/helper.py @@ -154,9 +154,7 @@ def transform(part, referentiel_face, transform_matrix=None, y_invert = False): # http://gamedev.stackexchange.com/questions/20097/how-to-calculate-a-3x3-rotation-matrix-from-2-direction-vectors # http://www.freecadweb.org/api/Vector.html def get_matrix_transform(face): - x_local, y_local_not_normalized, z_local_not_normalized = get_local_axis(face) - y_local = y_local_not_normalized.normalize() - z_local = z_local_not_normalized.normalize() + x_local, y_local, z_local = get_local_axis_normalized(face) m = FreeCAD.Matrix() if z_local is not None: From f0c0c23632fd013d45e8a80828bf4e432b337eec Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Sat, 23 Nov 2019 20:51:03 -0500 Subject: [PATCH 3/3] Print warning when a tab job does no work TODO: this should be fleshed out more if we end up actually wanting it --- lasercut/join.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lasercut/join.py b/lasercut/join.py index 3b9a12d..4557856 100644 --- a/lasercut/join.py +++ b/lasercut/join.py @@ -162,6 +162,7 @@ def tab_join_create_tab_on_face(material_face, material_plane, width, pos_y, tab def make_tab_join(tab, tab_part, other_parts): slots_pos = get_slot_positions(tab) + did_any_work = False for i, y in enumerate(slots_pos): for part_interactor in other_parts: tab_to_add, tab_dog_bone = tab_join_create_tab_on_face(tab_part.properties, part_interactor.properties, @@ -170,6 +171,7 @@ def make_tab_join(tab, tab_part, other_parts): part_interactor.properties) if intersect_test: + did_any_work = True tab_part.toAdd.append(tab_to_add_transformed) if tab_dog_bone: tab_part.toRemove.append(helper.transform_part(tab_dog_bone, tab)) @@ -177,6 +179,9 @@ def make_tab_join(tab, tab_part, other_parts): part_interactor.properties, tab.dog_bone) part_interactor.toRemove.append(helper.transform_part(hole, tab)) break + + if not did_any_work: + FreeCAD.Console.PrintWarning("Tab on part " + tab_part.get_name() + " did not apply\n") return