From 8a77724aa28994fbeb6a517dc24bc6770f6d7f32 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Mon, 21 May 2018 20:39:31 +0200 Subject: [PATCH] FEM: Python geometry selection class, use it for beamsection obj and rotation obj --- .../Fem/Gui/Resources/ui/ElementGeometry1D.ui | 50 +---- .../Fem/Gui/Resources/ui/ElementRotation1D.ui | 50 +---- .../_ViewProviderFemElementGeometry1D.py | 180 ++++-------------- .../_ViewProviderFemElementGeometry2D.py | 16 +- .../_ViewProviderFemElementRotation1D.py | 157 ++------------- 5 files changed, 87 insertions(+), 366 deletions(-) diff --git a/src/Mod/Fem/Gui/Resources/ui/ElementGeometry1D.ui b/src/Mod/Fem/Gui/Resources/ui/ElementGeometry1D.ui index b9fbcf0968..465c24560a 100644 --- a/src/Mod/Fem/Gui/Resources/ui/ElementGeometry1D.ui +++ b/src/Mod/Fem/Gui/Resources/ui/ElementGeometry1D.ui @@ -308,47 +308,17 @@ - - - References + + + Qt::Vertical - - - - - Leave blank to choose all remaining shapes - - - - - - - Add reference - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - l_label_text_1 - pushButton_Reference - list_References - verticalSpacer - + + + 20 + 40 + + + diff --git a/src/Mod/Fem/Gui/Resources/ui/ElementRotation1D.ui b/src/Mod/Fem/Gui/Resources/ui/ElementRotation1D.ui index 803d23c103..2fd668189f 100644 --- a/src/Mod/Fem/Gui/Resources/ui/ElementRotation1D.ui +++ b/src/Mod/Fem/Gui/Resources/ui/ElementRotation1D.ui @@ -87,47 +87,17 @@ - - - References + + + Qt::Vertical - - - - - Leave blank to choose all remaining shapes - - - - - - - Add reference - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - l_label_text_1 - pushButton_Reference - list_References - verticalSpacer - + + + 20 + 40 + + + diff --git a/src/Mod/Fem/femguiobjects/_ViewProviderFemElementGeometry1D.py b/src/Mod/Fem/femguiobjects/_ViewProviderFemElementGeometry1D.py index 1fab9a038a..eedbfd1438 100644 --- a/src/Mod/Fem/femguiobjects/_ViewProviderFemElementGeometry1D.py +++ b/src/Mod/Fem/femguiobjects/_ViewProviderFemElementGeometry1D.py @@ -35,7 +35,7 @@ False if False else FemGui.__name__ # dummy usage of FemGui for flake8, just re # for the panel from femobjects import _FemElementGeometry1D from PySide import QtCore -from PySide import QtGui +from . import FemSelectionWidgets class _ViewProviderFemElementGeometry1D: @@ -104,49 +104,44 @@ class _TaskPanelFemElementGeometry1D: '''The TaskPanel for editing References property of FemElementGeometry1D objects''' def __init__(self, obj): - FreeCADGui.Selection.clearSelection() - self.sel_server = None + + # parameter widget self.obj = obj - self.obj_notvisible = [] - - self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/ElementGeometry1D.ui") - QtCore.QObject.connect(self.form.cb_crosssectiontype, QtCore.SIGNAL("activated(int)"), self.sectiontype_changed) - QtCore.QObject.connect(self.form.if_rec_height, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.rec_height_changed) - QtCore.QObject.connect(self.form.if_rec_width, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.rec_width_changed) - QtCore.QObject.connect(self.form.if_circ_diameter, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.circ_diameter_changed) - QtCore.QObject.connect(self.form.if_pipe_diameter, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.pipe_diameter_changed) - QtCore.QObject.connect(self.form.if_pipe_thickness, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.pipe_thickness_changed) - QtCore.QObject.connect(self.form.pushButton_Reference, QtCore.SIGNAL("clicked()"), self.add_references) - self.form.list_References.itemSelectionChanged.connect(self.select_clicked_reference_shape) - 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.form.cb_crosssectiontype.addItems(_FemElementGeometry1D._FemElementGeometry1D.known_beam_types) # it is inside the class thus double _FemElementGeometry1D - + self.parameterWidget = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/ElementGeometry1D.ui") + QtCore.QObject.connect(self.parameterWidget.cb_crosssectiontype, QtCore.SIGNAL("activated(int)"), self.sectiontype_changed) + QtCore.QObject.connect(self.parameterWidget.if_rec_height, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.rec_height_changed) + QtCore.QObject.connect(self.parameterWidget.if_rec_width, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.rec_width_changed) + QtCore.QObject.connect(self.parameterWidget.if_circ_diameter, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.circ_diameter_changed) + QtCore.QObject.connect(self.parameterWidget.if_pipe_diameter, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.pipe_diameter_changed) + QtCore.QObject.connect(self.parameterWidget.if_pipe_thickness, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.pipe_thickness_changed) + self.parameterWidget.cb_crosssectiontype.addItems(_FemElementGeometry1D._FemElementGeometry1D.known_beam_types) # it is inside the class thus double _FemElementGeometry1D self.get_beamsection_props() - self.update() + self.updateParameterWidget() + + # geometry selection widget + self.selectionWidget = FemSelectionWidgets.GeometryElementsSelection(obj.References, ['Edge']) + + # form made from param and selection widget + self.form = [self.parameterWidget, self.selectionWidget] def accept(self): - self.setback_listobj_visibility() self.set_beamsection_props() - if self.sel_server: - FreeCADGui.Selection.removeObserver(self.sel_server) - FreeCADGui.ActiveDocument.resetEdit() + self.obj.References = self.selectionWidget.references FreeCAD.ActiveDocument.recompute() + self.set_back_all() return True def reject(self): - self.setback_listobj_visibility() - if self.sel_server: - FreeCADGui.Selection.removeObserver(self.sel_server) - FreeCADGui.ActiveDocument.resetEdit() + self.set_back_all() return True + def set_back_all(self): + self.selectionWidget.setback_listobj_visibility() + if self.selectionWidget.sel_server: + FreeCADGui.Selection.removeObserver(self.selectionWidget.sel_server) + FreeCADGui.ActiveDocument.resetEdit() + def get_beamsection_props(self): - self.references = [] - if self.obj.References: - self.tuplereferences = self.obj.References - self.get_references() self.SectionType = self.obj.SectionType self.RectHeight = self.obj.RectHeight self.RectWidth = self.obj.RectWidth @@ -155,7 +150,6 @@ class _TaskPanelFemElementGeometry1D: self.PipeThickness = self.obj.PipeThickness def set_beamsection_props(self): - self.obj.References = self.references self.obj.SectionType = self.SectionType self.obj.RectHeight = self.RectHeight self.obj.RectWidth = self.RectWidth @@ -163,22 +157,21 @@ class _TaskPanelFemElementGeometry1D: self.obj.PipeDiameter = self.PipeDiameter self.obj.PipeThickness = self.PipeThickness - def update(self): + def updateParameterWidget(self): 'fills the widgets' - index_crosssectiontype = self.form.cb_crosssectiontype.findText(self.SectionType) - self.form.cb_crosssectiontype.setCurrentIndex(index_crosssectiontype) - self.form.if_rec_height.setText(self.RectHeight.UserString) - self.form.if_rec_width.setText(self.RectWidth.UserString) - self.form.if_circ_diameter.setText(self.CircDiameter.UserString) - self.form.if_pipe_diameter.setText(self.PipeDiameter.UserString) - self.form.if_pipe_thickness.setText(self.PipeThickness.UserString) - self.rebuild_list_References() + index_crosssectiontype = self.parameterWidget.cb_crosssectiontype.findText(self.SectionType) + self.parameterWidget.cb_crosssectiontype.setCurrentIndex(index_crosssectiontype) + self.parameterWidget.if_rec_height.setText(self.RectHeight.UserString) + self.parameterWidget.if_rec_width.setText(self.RectWidth.UserString) + self.parameterWidget.if_circ_diameter.setText(self.CircDiameter.UserString) + self.parameterWidget.if_pipe_diameter.setText(self.PipeDiameter.UserString) + self.parameterWidget.if_pipe_thickness.setText(self.PipeThickness.UserString) def sectiontype_changed(self, index): if index < 0: return - self.form.cb_crosssectiontype.setCurrentIndex(index) - self.SectionType = str(self.form.cb_crosssectiontype.itemText(index)) # form returns unicode + self.parameterWidget.cb_crosssectiontype.setCurrentIndex(index) + self.SectionType = str(self.parameterWidget.cb_crosssectiontype.itemText(index)) # parameterWidget returns unicode def rec_height_changed(self, base_quantity_value): self.RectHeight = base_quantity_value @@ -194,102 +187,3 @@ class _TaskPanelFemElementGeometry1D: def pipe_thickness_changed(self, base_quantity_value): self.PipeThickness = base_quantity_value - - 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_remove_selected = self.form.contextMenu.addAction("Remove selected reference") - menu_item_remove_all = self.form.contextMenu.addAction("Remove all references") - if not self.references: - menu_item_remove_selected.setDisabled(True) - menu_item_remove_all.setDisabled(True) - self.form.connect(menu_item_remove_selected, QtCore.SIGNAL("triggered()"), self.remove_selected_reference) - self.form.connect(menu_item_remove_all, QtCore.SIGNAL("triggered()"), self.remove_all_references) - parentPosition = self.form.list_References.mapToGlobal(QtCore.QPoint(0, 0)) - self.form.contextMenu.move(parentPosition + QPos) - self.form.contextMenu.show() - - def remove_selected_reference(self): - if not self.references: - return - currentItemName = str(self.form.list_References.currentItem().text()) - currentRow = self.form.list_References.currentRow() - 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(currentRow) - - def remove_all_references(self): - self.references = [] - 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 - self.setback_listobj_visibility() - FreeCADGui.Selection.clearSelection() - # start SelectionObserver and parse the function to add the References to the widget - print_message = "Select Edges by single click on them to add them to the list" - if not self.sel_server: - # if we do not check, we would start a new SelectionObserver on every click on addReference button - # but close only one SelectionObserver on leaving the task panel - from . 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"): - if selection[1]: - elt = selection[0].Shape.getElement(selection[1]) - if elt.ShapeType == 'Edge': - 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, current_row=0): - 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) - if current_row > self.form.list_References.count() - 1: # first row is 0 - current_row = self.form.list_References.count() - 1 - if self.form.list_References.count() > 0: - self.form.list_References.setCurrentItem(self.form.list_References.item(current_row)) - - def select_clicked_reference_shape(self): - self.setback_listobj_visibility() - if self.sel_server: - FreeCADGui.Selection.removeObserver(self.sel_server) - self.sel_server = None - if not self.sel_server: - 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: - # print('found: shape: ' + ref[0].Name + ' element: ' + ref[1]) - if not ref[0].ViewObject.Visibility: - self.obj_notvisible.append(ref[0]) - ref[0].ViewObject.Visibility = True - FreeCADGui.Selection.clearSelection() - FreeCADGui.Selection.addSelection(ref[0], ref[1]) - - def setback_listobj_visibility(self): - '''set back Visibility of the list objects - ''' - FreeCADGui.Selection.clearSelection() - for obj in self.obj_notvisible: - obj.ViewObject.Visibility = False - self.obj_notvisible = [] diff --git a/src/Mod/Fem/femguiobjects/_ViewProviderFemElementGeometry2D.py b/src/Mod/Fem/femguiobjects/_ViewProviderFemElementGeometry2D.py index 1649ece286..a862559898 100644 --- a/src/Mod/Fem/femguiobjects/_ViewProviderFemElementGeometry2D.py +++ b/src/Mod/Fem/femguiobjects/_ViewProviderFemElementGeometry2D.py @@ -107,10 +107,12 @@ class _TaskPanelFemElementGeometry2D: # parameter widget self.obj = obj self.parameterWidget = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/ElementGeometry2D.ui") - self.init_parameter_widget() QtCore.QObject.connect(self.parameterWidget.if_thickness, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.thickness_changed) + self.init_parameter_widget() + # geometry selection widget self.selectionWidget = FemSelectionWidgets.GeometryElementsSelection(obj.References, ['Face']) + # form made from param and selection widget self.form = [self.parameterWidget, self.selectionWidget] @@ -125,15 +127,15 @@ class _TaskPanelFemElementGeometry2D: self.set_back_all() return True + def set_back_all(self): + self.selectionWidget.setback_listobj_visibility() + if self.selectionWidget.sel_server: + FreeCADGui.Selection.removeObserver(self.selectionWidget.sel_server) + FreeCADGui.ActiveDocument.resetEdit() + def init_parameter_widget(self): self.thickness = self.obj.Thickness self.parameterWidget.if_thickness.setText(self.thickness.UserString) def thickness_changed(self, base_quantity_value): self.thickness = base_quantity_value - - def set_back_all(self): - self.selectionWidget.setback_listobj_visibility() - if self.selectionWidget.sel_server: - FreeCADGui.Selection.removeObserver(self.selectionWidget.sel_server) - FreeCADGui.ActiveDocument.resetEdit() diff --git a/src/Mod/Fem/femguiobjects/_ViewProviderFemElementRotation1D.py b/src/Mod/Fem/femguiobjects/_ViewProviderFemElementRotation1D.py index 613fa22d25..8209f145d9 100644 --- a/src/Mod/Fem/femguiobjects/_ViewProviderFemElementRotation1D.py +++ b/src/Mod/Fem/femguiobjects/_ViewProviderFemElementRotation1D.py @@ -34,7 +34,7 @@ False if False else FemGui.__name__ # dummy usage of FemGui for flake8, just re # for the panel from PySide import QtCore -from PySide import QtGui +from . import FemSelectionWidgets class _ViewProviderFemElementRotation1D: @@ -108,151 +108,36 @@ class _ViewProviderFemElementRotation1D: class _TaskPanelFemElementRotation1D: '''The TaskPanel for editing References property of FemElementRotation1D objects''' def __init__(self, obj): - FreeCADGui.Selection.clearSelection() - self.sel_server = None + + # parameter widget self.obj = obj - self.obj_notvisible = [] + self.parameterWidget = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/ElementRotation1D.ui") + QtCore.QObject.connect(self.parameterWidget.if_rotation, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.rotation_changed) + self.rotation = self.obj.Rotation + self.parameterWidget.if_rotation.setText(self.rotation.UserString) - self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/ElementRotation1D.ui") - QtCore.QObject.connect(self.form.if_rotation, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.rotation_changed) - QtCore.QObject.connect(self.form.pushButton_Reference, QtCore.SIGNAL("clicked()"), self.add_references) - self.form.list_References.itemSelectionChanged.connect(self.select_clicked_reference_shape) - 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) + # geometry selection widget + self.selectionWidget = FemSelectionWidgets.GeometryElementsSelection(obj.References, ['Edge']) - self.get_beamsection_props() - self.update() + # form made from param and selection widget + self.form = [self.parameterWidget, self.selectionWidget] def accept(self): - self.setback_listobj_visibility() - self.set_beamrotation_props() - if self.sel_server: - FreeCADGui.Selection.removeObserver(self.sel_server) - FreeCADGui.ActiveDocument.resetEdit() + self.obj.Rotation = self.rotation + self.obj.References = self.selectionWidget.references FreeCAD.ActiveDocument.recompute() + self.set_back_all() return True def reject(self): - self.setback_listobj_visibility() - if self.sel_server: - FreeCADGui.Selection.removeObserver(self.sel_server) - FreeCADGui.ActiveDocument.resetEdit() + self.set_back_all() return True - def get_beamsection_props(self): - self.references = [] - if self.obj.References: - self.tuplereferences = self.obj.References - self.get_references() - self.Rotation = self.obj.Rotation - - def set_beamrotation_props(self): - self.obj.References = self.references - self.obj.Rotation = self.Rotation - - def update(self): - 'fills the widgets' - self.form.if_rotation.setText(self.Rotation.UserString) - self.rebuild_list_References() + def set_back_all(self): + self.selectionWidget.setback_listobj_visibility() + if self.selectionWidget.sel_server: + FreeCADGui.Selection.removeObserver(self.selectionWidget.sel_server) + FreeCADGui.ActiveDocument.resetEdit() def rotation_changed(self, base_quantity_value): - self.Rotation = base_quantity_value - - 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_remove_selected = self.form.contextMenu.addAction("Remove selected reference") - menu_item_remove_all = self.form.contextMenu.addAction("Remove all references") - if not self.references: - menu_item_remove_selected.setDisabled(True) - menu_item_remove_all.setDisabled(True) - self.form.connect(menu_item_remove_selected, QtCore.SIGNAL("triggered()"), self.remove_selected_reference) - self.form.connect(menu_item_remove_all, QtCore.SIGNAL("triggered()"), self.remove_all_references) - parentPosition = self.form.list_References.mapToGlobal(QtCore.QPoint(0, 0)) - self.form.contextMenu.move(parentPosition + QPos) - self.form.contextMenu.show() - - def remove_selected_reference(self): - if not self.references: - return - currentItemName = str(self.form.list_References.currentItem().text()) - currentRow = self.form.list_References.currentRow() - 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(currentRow) - - def remove_all_references(self): - self.references = [] - 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 - self.setback_listobj_visibility() - FreeCADGui.Selection.clearSelection() - # start SelectionObserver and parse the function to add the References to the widget - print_message = "Select Edges by single click on them to add them to the list" - if not self.sel_server: - # if we do not check, we would start a new SelectionObserver on every click on addReference button - # but close only one SelectionObserver on leaving the task panel - from . 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"): - if selection[1]: - elt = selection[0].Shape.getElement(selection[1]) - if elt.ShapeType == 'Edge': - 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, current_row=0): - 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) - if current_row > self.form.list_References.count() - 1: # first row is 0 - current_row = self.form.list_References.count() - 1 - if self.form.list_References.count() > 0: - self.form.list_References.setCurrentItem(self.form.list_References.item(current_row)) - - def select_clicked_reference_shape(self): - self.setback_listobj_visibility() - if self.sel_server: - FreeCADGui.Selection.removeObserver(self.sel_server) - self.sel_server = None - if not self.sel_server: - 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: - # print('found: shape: ' + ref[0].Name + ' element: ' + ref[1]) - if not ref[0].ViewObject.Visibility: - self.obj_notvisible.append(ref[0]) - ref[0].ViewObject.Visibility = True - FreeCADGui.Selection.clearSelection() - FreeCADGui.Selection.addSelection(ref[0], ref[1]) - - def setback_listobj_visibility(self): - '''set back Visibility of the list objects - ''' - FreeCADGui.Selection.clearSelection() - for obj in self.obj_notvisible: - obj.ViewObject.Visibility = False - self.obj_notvisible = [] + self.rotation = base_quantity_value