diff --git a/src/Mod/Fem/App/CMakeLists.txt b/src/Mod/Fem/App/CMakeLists.txt index d27e6760df..551d956c23 100755 --- a/src/Mod/Fem/App/CMakeLists.txt +++ b/src/Mod/Fem/App/CMakeLists.txt @@ -92,6 +92,7 @@ SET(FemScripts_SRCS _FemMaterial.py _TaskPanelFemBeamSection.py _TaskPanelFemMeshGmsh.py + _TaskPanelFemMeshGroup.py _TaskPanelFemMeshRegion.py _TaskPanelFemShellThickness.py _TaskPanelFemSolverCalculix.py @@ -140,6 +141,7 @@ SET(FemScripts_SRCS z88DispReader.py TaskPanelFemBeamSection.ui TaskPanelFemMeshGmsh.ui + TaskPanelFemMeshGroup.ui TaskPanelFemMeshRegion.ui TaskPanelFemShellThickness.ui TaskPanelFemSolverCalculix.ui diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index 3324b2e53f..308e3d580d 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -59,6 +59,8 @@ INSTALL( _FemMeshGroup.py _ViewProviderFemMeshGroup.py _CommandMeshGroup.py + _TaskPanelFemMeshGroup.py + TaskPanelFemMeshGroup.ui FemMeshRegion.py _FemMeshRegion.py diff --git a/src/Mod/Fem/TaskPanelFemMeshGroup.ui b/src/Mod/Fem/TaskPanelFemMeshGroup.ui new file mode 100644 index 0000000000..6a7cf9bb90 --- /dev/null +++ b/src/Mod/Fem/TaskPanelFemMeshGroup.ui @@ -0,0 +1,120 @@ + + + Form + + + + 0 + 0 + 350 + 500 + + + + Mesh group + + + + + + + 16777215 + 1677215 + + + + Identifier used for mesh export + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Name + + + true + + + + + + + Label + + + + + + + + + + + + References + + + + + + Add reference + + + + + + + + + + + + Solid + + + + + + + Face, Edge, Vertex + + + true + + + + + + + <html><head/><body><p>Selection</p></body></html> + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/src/Mod/Fem/_TaskPanelFemMeshGroup.py b/src/Mod/Fem/_TaskPanelFemMeshGroup.py new file mode 100644 index 0000000000..018d882a35 --- /dev/null +++ b/src/Mod/Fem/_TaskPanelFemMeshGroup.py @@ -0,0 +1,190 @@ +# *************************************************************************** +# * * +# * Copyright (c) 2016 - Bernd Hahnebach * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +__title__ = "_TaskPanelFemMeshGroup" +__author__ = "Bernd Hahnebach" +__url__ = "http://www.freecadweb.org" + +## @package TaskPanelFemMeshGroup +# \ingroup FEM + +import FreeCAD +import FreeCADGui +from PySide import QtGui +from PySide import QtCore + + +class _TaskPanelFemMeshGroup: + '''The TaskPanel for editing References property of FemMeshGroup objects''' + def __init__(self, obj): + FreeCADGui.Selection.clearSelection() + self.sel_server = None + self.obj = obj + self.selection_mode_solid = False + self.selection_mode_std_print_message = "Select Faces, Edges and Vertices by single click on them to add them to the list." + self.selection_mode_solid_print_message = "Select Solids by single click on a Face or Edge which belongs to the Solid, to add the Solid to the list." + + self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/TaskPanelFemMeshGroup.ui") + QtCore.QObject.connect(self.form.rb_name, QtCore.SIGNAL("toggled(bool)"), self.choose_exportidentifier_name) + QtCore.QObject.connect(self.form.rb_label, QtCore.SIGNAL("toggled(bool)"), self.choose_exportidentifier_label) + QtCore.QObject.connect(self.form.rb_standard, QtCore.SIGNAL("toggled(bool)"), self.choose_selection_mode_standard) + QtCore.QObject.connect(self.form.rb_solid, QtCore.SIGNAL("toggled(bool)"), self.choose_selection_mode_solid) + QtCore.QObject.connect(self.form.pushButton_Reference, QtCore.SIGNAL("clicked()"), self.add_references) + self.form.list_References.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.form.list_References.connect(self.form.list_References, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), self.references_list_right_clicked) + + self.get_meshgroup_props() + self.update() + + def accept(self): + self.set_meshgroup_props() + if self.sel_server: + FreeCADGui.Selection.removeObserver(self.sel_server) + FreeCADGui.ActiveDocument.resetEdit() + FreeCAD.ActiveDocument.recompute() + return True + + def reject(self): + if self.sel_server: + FreeCADGui.Selection.removeObserver(self.sel_server) + FreeCADGui.ActiveDocument.resetEdit() + return True + + def get_meshgroup_props(self): + self.use_label = self.obj.UseLabel + self.references = [] + if self.obj.References: + self.tuplereferences = self.obj.References + self.get_references() + + def set_meshgroup_props(self): + self.obj.References = self.references + self.obj.UseLabel = self.use_label + + def update(self): + 'fills the widgets' + self.form.rb_name.setChecked(not self.use_label) + self.form.rb_label.setChecked(self.use_label) + self.rebuild_list_References() + + def choose_exportidentifier_name(self, state): + self.use_label = not state + + def choose_exportidentifier_label(self, state): + self.use_label = state + + def choose_selection_mode_standard(self, state): + self.selection_mode_solid = not state + if self.sel_server and not self.selection_mode_solid: + print(self.selection_mode_std_print_message) + + def choose_selection_mode_solid(self, state): + self.selection_mode_solid = state + if self.sel_server and self.selection_mode_solid: + print(self.selection_mode_solid_print_message) + + 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") + if not self.references: + menu_item.setDisabled(True) + self.form.connect(menu_item, QtCore.SIGNAL("triggered()"), self.remove_reference) + parentPosition = self.form.list_References.mapToGlobal(QtCore.QPoint(0, 0)) + self.form.contextMenu.move(parentPosition + QPos) + self.form.contextMenu.show() + + def remove_reference(self): + if not self.references: + return + currentItemName = str(self.form.list_References.currentItem().text()) + for ref in self.references: + refname_to_compare_listentry = ref[0].Name + ':' + ref[1] + if refname_to_compare_listentry == currentItemName: + self.references.remove(ref) + self.rebuild_list_References() + + def add_references(self): + '''Called if Button add_reference is triggered''' + # in constraints EditTaskPanel the selection is active as soon as the taskpanel is open + # here the addReference button EditTaskPanel has to be triggered to start selection mode + FreeCADGui.Selection.clearSelection() + # start SelectionObserver and parse the function to add the References to the widget + if self.selection_mode_solid: # print message on button click + print_message = self.selection_mode_solid_print_message + else: + print_message = self.selection_mode_std_print_message + import FemSelectionObserver + self.sel_server = FemSelectionObserver.FemSelectionObserver(self.selectionParser, print_message) + + def selectionParser(self, selection): + print('selection: ', selection[0].Shape.ShapeType, ' ', selection[0].Name, ' ', selection[1]) + if hasattr(selection[0], "Shape") and selection[1]: + elt = selection[0].Shape.getElement(selection[1]) + if self.selection_mode_solid: + # in solid selection mode use edges and faces for selection of a solid + solid_to_add = None + if elt.ShapeType == 'Edge': + found_edge = False + for i, s in enumerate(selection[0].Shape.Solids): + for e in s.Edges: + if elt.isSame(e): + if not found_edge: + solid_to_add = str(i + 1) + else: + FreeCAD.Console.PrintMessage('Edge belongs to more than one solid\n') + solid_to_add = None + found_edge = True + elif elt.ShapeType == 'Face': + found_face = False + for i, s in enumerate(selection[0].Shape.Solids): + for e in s.Faces: + if elt.isSame(e): + if not found_face: + solid_to_add = str(i + 1) + else: + FreeCAD.Console.PrintMessage('Face belongs to more than one solid\n') + solid_to_add = None + found_edge = True + if solid_to_add: + selection = (selection[0], 'Solid' + solid_to_add) + print('selection element changed to Solid: ', selection[0].Shape.ShapeType, ' ', selection[0].Name, ' ', selection[1]) + else: + return + if selection not in self.references: + self.references.append(selection) + self.rebuild_list_References() + else: + FreeCAD.Console.PrintMessage(selection[0].Name + ' --> ' + selection[1] + ' is in reference list already!\n') + + def rebuild_list_References(self): + self.form.list_References.clear() + items = [] + 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)