diff --git a/src/App/PropertyLinks.cpp b/src/App/PropertyLinks.cpp index b8be1f24b042..79aa219f7a8b 100644 --- a/src/App/PropertyLinks.cpp +++ b/src/App/PropertyLinks.cpp @@ -684,16 +684,7 @@ std::vector PropertyLinkSubList::getSubListValues() PyObject *PropertyLinkSubList::getPyObject(void) { - // FIXME: The current implementation returns a list of tuples with two items - // of the form: [(object, sub-element1), (object, sub-element2),...] - // If for an object several sub-elements are stored then it appears several - // times. However, to keep the output more compact the string for the - // sub-element should be replaced by a tuple to be of the form: - // [(object, (sub-element1, sub-element2)),...] - // When doing so the Python function 'get_femelement_sets' in the Python - // module cxxInpWriter.py gives an error because it passes a tuple instead - // of a string. -#if 0 +#if 1 std::vector subLists = getSubListValues(); std::size_t count = subLists.size(); #if 0//FIXME: Should switch to tuple diff --git a/src/Mod/Fem/FemInputWriter.py b/src/Mod/Fem/FemInputWriter.py index 9cc480e2d270..d2daf583a039 100644 --- a/src/Mod/Fem/FemInputWriter.py +++ b/src/Mod/Fem/FemInputWriter.py @@ -94,7 +94,7 @@ def get_constraints_force_nodeloads(self): femobj['RefShapeType'] = '' if frc_obj.References: first_ref_obj = frc_obj.References[0] - first_ref_shape = first_ref_obj[0].Shape.getElement(first_ref_obj[1]) + first_ref_shape = first_ref_obj[0].Shape.getElement(first_ref_obj[1][0]) femobj['RefShapeType'] = first_ref_shape.ShapeType else: # frc_obj.References could be empty ! # TODO in FemTools: check diff --git a/src/Mod/Fem/FemInputWriterCcx.py b/src/Mod/Fem/FemInputWriterCcx.py index 599ba798231f..2c3518a8e879 100644 --- a/src/Mod/Fem/FemInputWriterCcx.py +++ b/src/Mod/Fem/FemInputWriterCcx.py @@ -293,14 +293,15 @@ def write_constraints_pressure(self, f): for femobj in self.pressure_objects: prs_obj = femobj['Object'] f.write('*DLOAD\n') - for o, e in prs_obj.References: + for o, elem_tup in prs_obj.References: rev = -1 if prs_obj.Reversed else 1 - elem = o.Shape.getElement(e) - if elem.ShapeType == 'Face': - v = self.femmesh.getccxVolumesByFace(elem) - f.write("** Load on face {}\n".format(e)) - for i in v: - f.write("{},P{},{}\n".format(i[0], i[1], rev * prs_obj.Pressure)) + for elem in elem_tup: + ref_shape = o.Shape.getElement(elem) + if ref_shape.ShapeType == 'Face': + v = self.femmesh.getccxVolumesByFace(ref_shape) + f.write("** Load on face {}\n".format(elem)) + for i in v: + f.write("{},P{},{}\n".format(i[0], i[1], rev * prs_obj.Pressure)) def write_frequency(self, f): f.write('\n***********************************************************\n') diff --git a/src/Mod/Fem/FemMeshTools.py b/src/Mod/Fem/FemMeshTools.py index 18752b17d99e..17b06b2f513d 100644 --- a/src/Mod/Fem/FemMeshTools.py +++ b/src/Mod/Fem/FemMeshTools.py @@ -53,21 +53,23 @@ def get_femnodes_by_references(femmesh, references): def get_femnodes_by_refshape(femmesh, ref): - if ref[1]: - r = ref[0].Shape.getElement(ref[1]) # Vertex, Edge, Face - else: - r = ref[0].Shape # solid - # print(' ReferenceShape : ', r.ShapeType, ', ', ref[0].Name, ', ', ref[0].Label, ' --> ', ref[1]) - if r.ShapeType == 'Vertex': - nodes = femmesh.getNodesByVertex(r) - elif r.ShapeType == 'Edge': - nodes = femmesh.getNodesByEdge(r) - elif r.ShapeType == 'Face': - nodes = femmesh.getNodesByFace(r) - elif r.ShapeType == 'Solid': - nodes = femmesh.getNodesBySolid(r) - else: - print(' No Vertice, Edge, Face or Solid as reference shapes!') + nodes = [] + for refelement in ref[1]: + if refelement: + r = ref[0].Shape.getElement(refelement) # Vertex, Edge, Face + else: + r = ref[0].Shape # solid + print(' ReferenceShape : ', r.ShapeType, ', ', ref[0].Name, ', ', ref[0].Label, ' --> ', refelement) + if r.ShapeType == 'Vertex': + nodes += femmesh.getNodesByVertex(r) + elif r.ShapeType == 'Edge': + nodes += femmesh.getNodesByEdge(r) + elif r.ShapeType == 'Face': + nodes += femmesh.getNodesByFace(r) + elif r.ShapeType == 'Solid': + nodes += femmesh.getNodesBySolid(r) + else: + print(' No Vertice, Edge, Face or Solid as reference shapes!') return nodes @@ -152,11 +154,13 @@ def get_force_obj_vertex_nodeload_table(femmesh, frc_obj): # force_obj_node_load_table = [('refshape_name.elemname',node_load_table), ..., ('refshape_name.elemname',node_load_table)] force_obj_node_load_table = [] node_load = frc_obj.Force / len(frc_obj.References) - for o, elem in frc_obj.References: - elem_o = o.Shape.getElement(elem) - node = femmesh.getNodesByVertex(elem_o) - elem_info_string = 'node load on shape: ' + o.Name + ':' + elem - force_obj_node_load_table.append((elem_info_string, {node[0]: node_load})) + for o, elem_tup in frc_obj.References: + node_count = len(elem_tup) + for elem in elem_tup: + ref_node = o.Shape.getElement(elem) + node = femmesh.getNodesByVertex(ref_node) + elem_info_string = 'node load on shape: ' + o.Name + ':' + elem + force_obj_node_load_table.append((elem_info_string, {node[0]: node_load / node_count})) return force_obj_node_load_table @@ -167,40 +171,40 @@ def get_force_obj_edge_nodeload_table(femmesh, femelement_table, femnodes_mesh, sum_ref_edge_length = 0 sum_ref_edge_node_length = 0 # for debugging sum_node_load = 0 # for debugging - for o, elem in frc_obj.References: - elem_o = o.Shape.getElement(elem) - sum_ref_edge_length += elem_o.Length + for o, elem_tup in frc_obj.References: + for elem in elem_tup: + sum_ref_edge_length += o.Shape.getElement(elem).Length if sum_ref_edge_length != 0: force_per_sum_ref_edge_length = frc_obj.Force / sum_ref_edge_length - for o, elem in frc_obj.References: - elem_o = o.Shape.getElement(elem) - ref_edge = elem_o - - # edge_table = { meshedgeID : ( nodeID, ... , nodeID ) } - edge_table = get_ref_edgenodes_table(femmesh, femelement_table, ref_edge) - - # node_length_table = [ (nodeID, length), ... , (nodeID, length) ] some nodes will have more than one entry - node_length_table = get_ref_edgenodes_lengths(femnodes_mesh, edge_table) - - # node_sum_length_table = { nodeID : Length, ... , nodeID : Length } LengthSum for each node, one entry for each node - node_sum_length_table = get_ref_shape_node_sum_geom_table(node_length_table) - - # node_load_table = { nodeID : NodeLoad, ... , nodeID : NodeLoad } NodeLoad for each node, one entry for each node - node_load_table = {} - sum_node_lengths = 0 # for debugging - for node in node_sum_length_table: - sum_node_lengths += node_sum_length_table[node] # for debugging - node_load_table[node] = node_sum_length_table[node] * force_per_sum_ref_edge_length - ratio_refedge_lengths = sum_node_lengths / elem_o.Length - if ratio_refedge_lengths < 0.99 or ratio_refedge_lengths > 1.01: - FreeCAD.Console.PrintError('Error on: ' + frc_obj.Name + ' --> ' + o.Name + '.' + elem + '\n') - print(' sum_node_lengths:', sum_node_lengths) - print(' refedge_length: ', elem_o.Length) - bad_refedge = elem_o - sum_ref_edge_node_length += sum_node_lengths - - elem_info_string = 'node loads on shape: ' + o.Name + ':' + elem - force_obj_node_load_table.append((elem_info_string, node_load_table)) + for o, elem_tup in frc_obj.References: + for elem in elem_tup: + ref_edge = o.Shape.getElement(elem) + + # edge_table = { meshedgeID : ( nodeID, ... , nodeID ) } + edge_table = get_ref_edgenodes_table(femmesh, femelement_table, ref_edge) + + # node_length_table = [ (nodeID, length), ... , (nodeID, length) ] some nodes will have more than one entry + node_length_table = get_ref_edgenodes_lengths(femnodes_mesh, edge_table) + + # node_sum_length_table = { nodeID : Length, ... , nodeID : Length } LengthSum for each node, one entry for each node + node_sum_length_table = get_ref_shape_node_sum_geom_table(node_length_table) + + # node_load_table = { nodeID : NodeLoad, ... , nodeID : NodeLoad } NodeLoad for each node, one entry for each node + node_load_table = {} + sum_node_lengths = 0 # for debugging + for node in node_sum_length_table: + sum_node_lengths += node_sum_length_table[node] # for debugging + node_load_table[node] = node_sum_length_table[node] * force_per_sum_ref_edge_length + ratio_refedge_lengths = sum_node_lengths / ref_edge.Length + if ratio_refedge_lengths < 0.99 or ratio_refedge_lengths > 1.01: + FreeCAD.Console.PrintError('Error on: ' + frc_obj.Name + ' --> ' + o.Name + '.' + elem + '\n') + print(' sum_node_lengths:', sum_node_lengths) + print(' refedge_length: ', ref_edge.Length) + bad_refedge = ref_edge + sum_ref_edge_node_length += sum_node_lengths + + elem_info_string = 'node loads on shape: ' + o.Name + ':' + elem + force_obj_node_load_table.append((elem_info_string, node_load_table)) for ref_shape in force_obj_node_load_table: for node in ref_shape[1]: @@ -262,39 +266,39 @@ def get_force_obj_face_nodeload_table(femmesh, femelement_table, femnodes_mesh, sum_ref_face_area = 0 sum_ref_face_node_area = 0 # for debugging sum_node_load = 0 # for debugging - for o, elem in frc_obj.References: - elem_o = o.Shape.getElement(elem) - sum_ref_face_area += elem_o.Area + for o, elem_tup in frc_obj.References: + for elem in elem_tup: + sum_ref_face_area += o.Shape.getElement(elem).Area if sum_ref_face_area != 0: force_per_sum_ref_face_area = frc_obj.Force / sum_ref_face_area - for o, elem in frc_obj.References: - elem_o = o.Shape.getElement(elem) - ref_face = elem_o - - # face_table = { meshfaceID : ( nodeID, ... , nodeID ) } - face_table = get_ref_facenodes_table(femmesh, femelement_table, ref_face) - - # node_area_table = [ (nodeID, Area), ... , (nodeID, Area) ] some nodes will have more than one entry - node_area_table = get_ref_facenodes_areas(femnodes_mesh, face_table) - - # node_sum_area_table = { nodeID : Area, ... , nodeID : Area } AreaSum for each node, one entry for each node - node_sum_area_table = get_ref_shape_node_sum_geom_table(node_area_table) - - # node_load_table = { nodeID : NodeLoad, ... , nodeID : NodeLoad } NodeLoad for each node, one entry for each node - node_load_table = {} - sum_node_areas = 0 # for debugging - for node in node_sum_area_table: - sum_node_areas += node_sum_area_table[node] # for debugging - node_load_table[node] = node_sum_area_table[node] * force_per_sum_ref_face_area - ratio_refface_areas = sum_node_areas / elem_o.Area - if ratio_refface_areas < 0.99 or ratio_refface_areas > 1.01: - FreeCAD.Console.PrintError('Error on: ' + frc_obj.Name + ' --> ' + o.Name + '.' + elem + '\n') - print(' sum_node_lengths:', sum_node_areas) - print(' refedge_length: ', elem_o.Area) - sum_ref_face_node_area += sum_node_areas - - elem_info_string = 'node loads on shape: ' + o.Name + ':' + elem - force_obj_node_load_table.append((elem_info_string, node_load_table)) + for o, elem_tup in frc_obj.References: + for elem in elem_tup: + ref_face = o.Shape.getElement(elem) + + # face_table = { meshfaceID : ( nodeID, ... , nodeID ) } + face_table = get_ref_facenodes_table(femmesh, femelement_table, ref_face) + + # node_area_table = [ (nodeID, Area), ... , (nodeID, Area) ] some nodes will have more than one entry + node_area_table = get_ref_facenodes_areas(femnodes_mesh, face_table) + + # node_sum_area_table = { nodeID : Area, ... , nodeID : Area } AreaSum for each node, one entry for each node + node_sum_area_table = get_ref_shape_node_sum_geom_table(node_area_table) + + # node_load_table = { nodeID : NodeLoad, ... , nodeID : NodeLoad } NodeLoad for each node, one entry for each node + node_load_table = {} + sum_node_areas = 0 # for debugging + for node in node_sum_area_table: + sum_node_areas += node_sum_area_table[node] # for debugging + node_load_table[node] = node_sum_area_table[node] * force_per_sum_ref_face_area + ratio_refface_areas = sum_node_areas / ref_face.Area + if ratio_refface_areas < 0.99 or ratio_refface_areas > 1.01: + FreeCAD.Console.PrintError('Error on: ' + frc_obj.Name + ' --> ' + o.Name + '.' + elem + '\n') + print(' sum_node_lengths:', sum_node_areas) + print(' refedge_length: ', ref_face.Area) + sum_ref_face_node_area += sum_node_areas + + elem_info_string = 'node loads on shape: ' + o.Name + ':' + elem + force_obj_node_load_table.append((elem_info_string, node_load_table)) for ref_shape in force_obj_node_load_table: for node in ref_shape[1]: diff --git a/src/Mod/Fem/_TaskPanelFemBeamSection.py b/src/Mod/Fem/_TaskPanelFemBeamSection.py index 09cbe4ee7b85..d1761e532943 100644 --- a/src/Mod/Fem/_TaskPanelFemBeamSection.py +++ b/src/Mod/Fem/_TaskPanelFemBeamSection.py @@ -37,7 +37,10 @@ def __init__(self, obj): FreeCADGui.Selection.clearSelection() self.sel_server = None self.obj = obj - self.references = self.obj.References + self.references = [] + if self.obj.References: + self.tuplereferences = self.obj.References + self.get_references() self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/TaskPanelFemBeamSection.ui") QtCore.QObject.connect(self.form.pushButton_Reference, QtCore.SIGNAL("clicked()"), self.add_references) @@ -60,6 +63,11 @@ def reject(self): FreeCADGui.ActiveDocument.resetEdit() return True + def get_references(self): + for ref in self.tuplereferences: + for elem in ref[1]: + self.references.append((ref[0], elem)) + def references_list_right_clicked(self, QPos): self.form.contextMenu = QtGui.QMenu() menu_item = self.form.contextMenu.addAction("Remove Reference") @@ -105,8 +113,8 @@ def selectionParser(self, selection): def rebuild_list_References(self): self.form.list_References.clear() items = [] - for i in self.references: - item_name = i[0].Name + ':' + i[1] + for ref in self.references: + item_name = ref[0].Name + ':' + ref[1] items.append(item_name) for listItemName in sorted(items): self.form.list_References.addItem(listItemName) diff --git a/src/Mod/Fem/_TaskPanelFemShellThickness.py b/src/Mod/Fem/_TaskPanelFemShellThickness.py index 442c930f741b..600a36ce0e8f 100644 --- a/src/Mod/Fem/_TaskPanelFemShellThickness.py +++ b/src/Mod/Fem/_TaskPanelFemShellThickness.py @@ -37,7 +37,10 @@ def __init__(self, obj): FreeCADGui.Selection.clearSelection() self.sel_server = None self.obj = obj - self.references = self.obj.References + self.references = [] + if self.obj.References: + self.tuplereferences = self.obj.References + self.get_references() self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/TaskPanelFemShellThickness.ui") QtCore.QObject.connect(self.form.pushButton_Reference, QtCore.SIGNAL("clicked()"), self.add_references) @@ -60,6 +63,11 @@ def reject(self): FreeCADGui.ActiveDocument.resetEdit() return True + def get_references(self): + for ref in self.tuplereferences: + for elem in ref[1]: + self.references.append((ref[0], elem)) + def references_list_right_clicked(self, QPos): self.form.contextMenu = QtGui.QMenu() menu_item = self.form.contextMenu.addAction("Remove Reference") @@ -105,8 +113,8 @@ def selectionParser(self, selection): def rebuild_list_References(self): self.form.list_References.clear() items = [] - for i in self.references: - item_name = i[0].Name + ':' + i[1] + for ref in self.references: + item_name = ref[0].Name + ':' + ref[1] items.append(item_name) for listItemName in sorted(items): self.form.list_References.addItem(listItemName) diff --git a/src/Mod/Fem/_TaskPanelMechanicalMaterial.py b/src/Mod/Fem/_TaskPanelMechanicalMaterial.py index e8c57bc8bd67..98eada20acdb 100644 --- a/src/Mod/Fem/_TaskPanelMechanicalMaterial.py +++ b/src/Mod/Fem/_TaskPanelMechanicalMaterial.py @@ -38,7 +38,10 @@ def __init__(self, obj): self.sel_server = None self.obj = obj self.material = self.obj.Material - self.references = self.obj.References + self.references = [] + if self.obj.References: + self.tuplereferences = self.obj.References + self.get_references() self.references_shape_type = None self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/TaskPanelMechanicalMaterial.ui") @@ -91,6 +94,11 @@ def remove_active_sel_server(self): if self.sel_server: FreeCADGui.Selection.removeObserver(self.sel_server) + def get_references(self): + for ref in self.tuplereferences: + for elem in ref[1]: + self.references.append((ref[0], elem)) + def has_equal_references_shape_types(self): if not self.references: self.references_shape_type = None