From 7afa56652c00058b1128d1ee60a3d6eebc824ef8 Mon Sep 17 00:00:00 2001 From: marioalexis Date: Thu, 28 Aug 2025 23:12:15 -0300 Subject: [PATCH] Fem: Add support for 2D geometries to Contact constraint - fixes #13280 --- src/Mod/Fem/Gui/TaskFemConstraintContact.cpp | 12 ++++++++---- src/Mod/Fem/femmesh/meshsetsgetter.py | 19 +++++++++---------- .../calculix/write_constraint_contact.py | 19 +++++++++++++++---- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/Mod/Fem/Gui/TaskFemConstraintContact.cpp b/src/Mod/Fem/Gui/TaskFemConstraintContact.cpp index 65019b1533..ddd0e47358 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintContact.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraintContact.cpp @@ -227,8 +227,10 @@ void TaskFemConstraintContact::addToSelectionSlave() } for (const auto& subName : subNames) { // for every selected sub element bool addMe = true; - if (subName.substr(0, 4) != "Face") { - QMessageBox::warning(this, tr("Selection error"), tr("Only faces can be picked")); + if ((subName.substr(0, 4) != "Face") && (subName.substr(0, 4) != "Edge")) { + QMessageBox::warning(this, + tr("Selection error"), + tr("Only faces can be picked (edges in 2D models)")); return; } for (auto itr = std::ranges::find(SubElements, subName); itr != SubElements.end(); @@ -352,8 +354,10 @@ void TaskFemConstraintContact::addToSelectionMaster() } for (const auto& subName : subNames) { // for every selected sub element bool addMe = true; - if (subName.substr(0, 4) != "Face") { - QMessageBox::warning(this, tr("Selection error"), tr("Only faces can be picked")); + if ((subName.substr(0, 4) != "Face") && (subName.substr(0, 4) != "Edge")) { + QMessageBox::warning(this, + tr("Selection error"), + tr("Only faces can be picked (edges in 2D models)")); return; } for (auto itr = std::ranges::find(SubElements.begin(), SubElements.end(), subName); diff --git a/src/Mod/Fem/femmesh/meshsetsgetter.py b/src/Mod/Fem/femmesh/meshsetsgetter.py index cffe6e3266..2d18f57f99 100644 --- a/src/Mod/Fem/femmesh/meshsetsgetter.py +++ b/src/Mod/Fem/femmesh/meshsetsgetter.py @@ -442,16 +442,15 @@ class MeshSetsGetter: for femobj in self.member.cons_contact: # femobj --> dict, FreeCAD document object is femobj["Object"] - print_obj_info(femobj["Object"]) - contact_slave_faces, contact_master_faces = meshtools.get_contact_obj_faces( - self.femmesh, self.femelement_table, self.femnodes_ele_table, femobj - ) - # [ele_id, ele_face_id], [ele_id, ele_face_id], ...] - # whereas the ele_face_id might be ccx specific - femobj["ContactSlaveFaces"] = contact_slave_faces - femobj["ContactMasterFaces"] = contact_master_faces - # FreeCAD.Console.PrintLog("{}\n".format(femobj["ContactSlaveFaces"])) - # FreeCAD.Console.PrintLog("{}\n".format(femobj["ContactMasterFaces"])) + obj = femobj["Object"] + print_obj_info(obj) + result = [] + ref_data = meshtools.pair_obj_reference(obj.References) + for ref_pair in ref_data: + result.append(meshtools.get_ccx_elements(self, ref_pair)) + + femobj["ContactSlaveFaces"] = result[:-1] + femobj["ContactMasterFaces"] = result[-1:] # information in the regard of element faces constraints # forum post: https://forum.freecad.org/viewtopic.php?f=18&t=42783&p=370286#p366723 diff --git a/src/Mod/Fem/femsolver/calculix/write_constraint_contact.py b/src/Mod/Fem/femsolver/calculix/write_constraint_contact.py index f602af6ba6..c46873c351 100644 --- a/src/Mod/Fem/femsolver/calculix/write_constraint_contact.py +++ b/src/Mod/Fem/femsolver/calculix/write_constraint_contact.py @@ -57,12 +57,23 @@ def get_after_write_constraint(): def write_meshdata_constraint(f, femobj, contact_obj, ccxwriter): # slave DEP f.write(f"*SURFACE, NAME=DEP{contact_obj.Name}\n") - for i in femobj["ContactSlaveFaces"]: - f.write(f"{i[0]},S{i[1]}\n") + for refs, surf, is_sub_el in femobj["ContactSlaveFaces"]: + if is_sub_el: + for elem, fno in surf: + f.write(f"{elem},S{fno}\n") + else: + for elem in surf: + f.write(f"{elem},S2\n") + # master IND f.write(f"*SURFACE, NAME=IND{contact_obj.Name}\n") - for i in femobj["ContactMasterFaces"]: - f.write(f"{i[0]},S{i[1]}\n") + for refs, surf, is_sub_el in femobj["ContactMasterFaces"]: + if is_sub_el: + for elem, fno in surf: + f.write(f"{elem},S{fno}\n") + else: + for elem in surf: + f.write(f"{elem},S2\n") def write_constraint(f, femobj, contact_obj, ccxwriter):