Download src/Mod/Fem/femguiutils/selection_widgets.py from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 26.7 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Fem/femguiutils/selection_widgets.py
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/Fem/femguiutils/selection_widgets.py
-
curl -L -o selection_widgets.py https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Fem/femguiutils/selection_widgets.py
26.7 kB
| # *************************************************************************** | |
| # * Copyright (c) 2017 Markus Hovorka <m.hovorka@live.de> * | |
| # * Copyright (c) 2018 Bernd Hahnebach <bernd@bimstatik.org> * | |
| # * * | |
| # * This file is part of the FreeCAD CAx development system. * | |
| # * * | |
| # * 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__ = "FreeCAD FEM select widget" | |
| __author__ = "Markus Hovorka, Bernd Hahnebach" | |
| __url__ = "https://www.freecad.org" | |
| ## @package FemSelectWidget | |
| # \ingroup FEM | |
| # \brief FreeCAD FEM FemSelectWidget | |
| from typing import List, TYPE_CHECKING | |
| from PySide import QtGui | |
| from PySide import QtCore | |
| import FreeCAD | |
| import FreeCADGui | |
| import FreeCADGui as Gui | |
| from femtools import geomtools | |
| from femguiutils.disambiguate_solid_selection import disambiguate_solid_selection | |
| if TYPE_CHECKING: | |
| from Part import Face, Edge, PartFeature | |
| def solids_with_edge(parent_part: "PartFeature", edge: "Edge") -> List[int]: | |
| """ | |
| Return the indices in the parent's list of solids that are partially bounded by edge. | |
| """ | |
| solids_with_edge: List[int] = [] | |
| for idx, solid in enumerate(parent_part.Shape.Solids): | |
| if any([edge.isSame(e) for e in solid.Edges]): | |
| solids_with_edge.append(idx) | |
| return solids_with_edge | |
| def solids_with_face(parent_part: "PartFeature", face: "Face") -> List[int]: | |
| """ | |
| Return the indices in the parent's list of solids that are partially bounded by face. | |
| """ | |
| solids_with_face: List[int] = [] | |
| for idx, solid in enumerate(parent_part.Shape.Solids): | |
| if any([face.isSame(f) for f in solid.Faces]): | |
| solids_with_face.append(idx) | |
| return solids_with_face | |
| class _Selector(QtGui.QWidget): | |
| def __init__(self): | |
| super().__init__() | |
| self._references = [] | |
| self._register = dict() | |
| addBtn = QtGui.QPushButton(self.tr("Add")) | |
| delBtn = QtGui.QPushButton(self.tr("Remove")) | |
| addBtn.clicked.connect(self._add) | |
| delBtn.clicked.connect(self._del) | |
| btnLayout = QtGui.QHBoxLayout() | |
| btnLayout.addWidget(addBtn) | |
| btnLayout.addWidget(delBtn) | |
| self._model = QtGui.QStandardItemModel() | |
| self._view = SmallListView() | |
| self._view.setModel(self._model) | |
| self._helpTextLbl = QtGui.QLabel() | |
| self._helpTextLbl.setWordWrap(True) | |
| mainLayout = QtGui.QVBoxLayout() | |
| mainLayout.addWidget(self._helpTextLbl) | |
| mainLayout.addLayout(btnLayout) | |
| mainLayout.addWidget(self._view) | |
| self.setLayout(mainLayout) | |
| def references(self): | |
| return [entry for entry in self._references if entry[1]] | |
| def setReferences(self, references): | |
| self._references = [] | |
| self._updateReferences(references) | |
| def setHelpText(self, text): | |
| self._helpTextLbl.setText(text) | |
| def _add(self): | |
| selection = self.getSelection() | |
| self._updateReferences(selection) | |
| def _del(self): | |
| selected = self._view.selectedIndexes() | |
| for index in selected: | |
| identifier = self._model.data(index) | |
| obj, sub = self._register[identifier] | |
| refIndex = self._getIndex(obj) | |
| entry = self._references[refIndex] | |
| newSub = tuple(x for x in entry[1] if x != sub) | |
| self._references[refIndex] = (obj, newSub) | |
| self._model.removeRow(index.row()) | |
| def _updateReferences(self, selection): | |
| for obj, subList in selection: | |
| index = self._getIndex(obj) | |
| for sub in subList: | |
| entry = self._references[index] | |
| if sub not in entry[1]: | |
| self._addToWidget(obj, sub) | |
| newEntry = (obj, entry[1] + (sub,)) | |
| self._references[index] = newEntry | |
| def _addToWidget(self, obj, sub): | |
| identifier = f"{obj.Name}::{sub}" | |
| item = QtGui.QStandardItem(identifier) | |
| self._model.appendRow(item) | |
| self._register[identifier] = (obj, sub) | |
| def _getIndex(self, obj): | |
| for i, entry in enumerate(self._references): | |
| if entry[0] == obj: | |
| return i | |
| self._references.append((obj, tuple())) | |
| return len(self._references) - 1 | |
| def getSelection(self): | |
| raise NotImplementedError() | |
| class BoundarySelector(_Selector): | |
| def __init__(self): | |
| super().__init__() | |
| self.setWindowTitle(self.tr("Select Faces/Edges/Vertexes")) | |
| self.setHelpText(self.tr('To add references: select them in the 3D view and click "Add".')) | |
| def getSelection(self): | |
| selection = [] | |
| for selObj in Gui.Selection.getSelectionEx(): | |
| if selObj.HasSubObjects: | |
| item = (selObj.Object, tuple(selObj.SubElementNames)) | |
| selection.append(item) | |
| return selection | |
| class SolidSelector(_Selector): | |
| def __init__(self): | |
| super().__init__() | |
| self.setWindowTitle(self.tr("Select Solids")) | |
| self.setHelpText( | |
| self.tr( | |
| "Select elements part of the solid that shall be added" | |
| ' to the list. To add the solid click "Add".' | |
| ) | |
| ) | |
| def getSelection(self): | |
| selection = [] | |
| for selObj in Gui.Selection.getSelectionEx(): | |
| solids = set() | |
| for sub in self._getObjects(selObj.Object, selObj.SubElementNames): | |
| s = self._getSolidOfSub(selObj.Object, sub) | |
| if s is not None: | |
| solids.add(s) | |
| if solids: | |
| item = (selObj.Object, tuple(solids)) | |
| selection.append(item) | |
| if len(selection) == 0: | |
| FreeCAD.Console.PrintMessage( | |
| "Object with no Shape selected or nothing selected at all.\n" | |
| ) | |
| return selection | |
| def _getObjects(self, obj, names): | |
| objects = [] | |
| if not hasattr(obj, "Shape"): | |
| FreeCAD.Console.PrintMessage("Selected object has no Shape.\n") | |
| return objects | |
| shape = obj.Shape | |
| for n in names: | |
| if n.startswith("Face"): | |
| objects.append(shape.Faces[int(n[4:]) - 1]) | |
| elif n.startswith("Edge"): | |
| objects.append(shape.Edges[int(n[4:]) - 1]) | |
| elif n.startswith("Vertex"): | |
| objects.append(shape.Vertexes[int(n[6:]) - 1]) | |
| elif n.startswith("Solid"): | |
| objects.append(shape.Solids[int(n[5:]) - 1]) | |
| return objects | |
| def _getSolidOfSub(self, obj, sub): | |
| foundSolids = set() | |
| if sub.ShapeType == "Solid": | |
| for solidId, solid in enumerate(obj.Shape.Solids): | |
| if sub.isSame(solid): | |
| foundSolids.add("Solid" + str(solidId + 1)) | |
| elif sub.ShapeType == "Face": | |
| for solidId, solid in enumerate(obj.Shape.Solids): | |
| if self._findSub(sub, solid.Faces): | |
| foundSolids.add("Solid" + str(solidId + 1)) | |
| elif sub.ShapeType == "Edge": | |
| for solidId, solid in enumerate(obj.Shape.Solids): | |
| if self._findSub(sub, solid.Edges): | |
| foundSolids.add("Solid" + str(solidId + 1)) | |
| elif sub.ShapeType == "Vertex": | |
| for solidId, solid in enumerate(obj.Shape.Solids): | |
| if self._findSub(sub, solid.Vertexes): | |
| foundSolids.add("Solid" + str(solidId + 1)) | |
| if len(foundSolids) == 1: | |
| it = iter(foundSolids) | |
| return next(it) | |
| return None | |
| def _findSub(self, sub, subList): | |
| for i, s in enumerate(subList): | |
| if s.isSame(sub): | |
| return True | |
| return False | |
| class SmallListView(QtGui.QListView): | |
| def sizeHint(self): | |
| return QtCore.QSize(50, 50) | |
| class GeometryElementsSelection(QtGui.QWidget): | |
| def __init__(self, ref, eltypes, multigeom, showHintEmptyList): | |
| super().__init__() | |
| # init ui stuff | |
| FreeCADGui.Selection.clearSelection() | |
| self.sel_server = None | |
| self.obj_notvisible = [] | |
| self.initElemTypes(eltypes) | |
| self.allow_multiple_geom_types = multigeom | |
| self.showHintEmptyList = showHintEmptyList | |
| self.initUI() | |
| # set references and fill the list widget | |
| self.references = [] | |
| if ref: | |
| self.tuplereferences = ref | |
| self.get_references() | |
| self.rebuild_list_References() | |
| def initElemTypes(self, eltypes): | |
| self.sel_elem_types = eltypes | |
| # FreeCAD.Console.PrintMessage( | |
| # "Selection of: {} is allowed.\n".format(self.sel_elem_types) | |
| # ) | |
| self.sel_elem_text = "" | |
| for e in self.sel_elem_types: | |
| self.sel_elem_text += e + ", " | |
| self.sel_elem_text = self.sel_elem_text.rstrip(", ") | |
| # FreeCAD.Console.PrintMessage("Selection of: " + self.sel_elem_text + " is allowed.\n") | |
| self.selection_mode_std_print_message = ( | |
| "Single click on a " + self.sel_elem_text + " will add it to the list" | |
| ) | |
| self.selection_mode_solid_print_message = ( | |
| "Single click on a Face or Edge which belongs " | |
| "to one Solid will add the Solid to the list" | |
| ) | |
| def initUI(self): | |
| # ArchPanel is coded without ui-file too | |
| # title | |
| self.setWindowTitle(self.tr("Geometry Reference Selector")) | |
| # button | |
| self.pushButton_Add = QtGui.QPushButton(self.tr("Add")) | |
| self.pushButton_Remove = QtGui.QPushButton(self.tr("Remove")) | |
| # label | |
| self.lb_help = QtGui.QLabel() | |
| self.lb_help.setWordWrap(True) | |
| selectHelpText = self.tr("Select geometry of type: {}{}{}").format( | |
| "<b>", self.sel_elem_text, "</b>" | |
| ) | |
| self.lb_help.setText(selectHelpText) | |
| # list | |
| self.list_References = QtGui.QListWidget() | |
| # radiobutton down the list | |
| self.lb_selmod = QtGui.QLabel() | |
| self.lb_selmod.setText(self.tr("Selection mode")) | |
| self.rb_standard = QtGui.QRadioButton(self.tr(self.sel_elem_text.lstrip("Solid, "))) | |
| self.rb_solid = QtGui.QRadioButton(self.tr("Solid")) | |
| # radio button layout | |
| rbtnLayout = QtGui.QHBoxLayout() | |
| rbtnLayout.addWidget(self.lb_selmod) | |
| rbtnLayout.addWidget(self.rb_standard) | |
| rbtnLayout.addWidget(self.rb_solid) | |
| # add/remove button | |
| subLayout = QtGui.QHBoxLayout() | |
| subLayout.addWidget(self.pushButton_Add) | |
| subLayout.addWidget(self.pushButton_Remove) | |
| # main layout | |
| mainLayout = QtGui.QVBoxLayout() | |
| mainLayout.addWidget(self.lb_help) | |
| mainLayout.addLayout(subLayout) | |
| mainLayout.addWidget(self.list_References) | |
| tip1 = self.tr( | |
| "Click and select geometric elements to add them to the list.{}" | |
| "The following geometry elements can be selected: {}{}{}" | |
| ).format("<br>", "<b>", self.sel_elem_text, "</b>") | |
| tip2 = self.tr( | |
| "{}If no geometry is added to the list, all remaining ones are used." | |
| ).format("<br>") | |
| tip1 += tip2 if self.showHintEmptyList else "" | |
| self.pushButton_Add.setToolTip(tip1) | |
| # if only "Solid" is avail, std-sel-mode is obsolete | |
| if "Solid" in self.sel_elem_types and len(self.sel_elem_types) == 1: | |
| self.selection_mode_solid = True | |
| else: | |
| self.selection_mode_solid = False | |
| # show radio buttons, if a solid and at least one nonsolid is allowed | |
| if "Solid" in self.sel_elem_types and len(self.sel_elem_types) > 1: | |
| self.rb_standard.setChecked(True) | |
| self.rb_solid.setChecked(False) | |
| mainLayout.addLayout(rbtnLayout) | |
| self.setLayout(mainLayout) | |
| # signals and slots | |
| self.list_References.itemSelectionChanged.connect(self.select_clicked_reference_shape) | |
| self.list_References.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) | |
| self.list_References.connect( | |
| self.list_References, | |
| QtCore.SIGNAL("customContextMenuRequested(QPoint)"), | |
| self.references_list_right_clicked, | |
| ) | |
| QtCore.QObject.connect(self.pushButton_Add, QtCore.SIGNAL("clicked()"), self.add_references) | |
| QtCore.QObject.connect( | |
| self.pushButton_Remove, QtCore.SIGNAL("clicked()"), self.remove_selected_reference | |
| ) | |
| QtCore.QObject.connect( | |
| self.rb_standard, QtCore.SIGNAL("toggled(bool)"), self.choose_selection_mode_standard | |
| ) | |
| QtCore.QObject.connect( | |
| self.rb_solid, QtCore.SIGNAL("toggled(bool)"), self.choose_selection_mode_solid | |
| ) | |
| def get_references(self): | |
| for ref in self.tuplereferences: | |
| for elem in ref[1]: | |
| self.references.append((ref[0], elem)) | |
| def get_item_text(self, ref): | |
| return ref[0].Name + ":" + ref[1] | |
| def get_allitems_text(self): | |
| items = [] | |
| for ref in self.references: | |
| items.append(self.get_item_text(ref)) | |
| return sorted(items) | |
| def rebuild_list_References(self, current_row=0): | |
| self.list_References.clear() | |
| for listItemName in self.get_allitems_text(): | |
| self.list_References.addItem(listItemName) | |
| if current_row > self.list_References.count() - 1: # first row is 0 | |
| current_row = self.list_References.count() - 1 | |
| if self.list_References.count() > 0: | |
| self.list_References.setCurrentItem(self.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.list_References.currentItem().text()) | |
| for ref in self.references: | |
| if self.get_item_text(ref) == 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() | |
| ref_sh_type = ref[0].Shape.ShapeType | |
| if ref[1].startswith("Solid") and ( | |
| ref_sh_type == "Compound" or ref_sh_type == "CompSolid" | |
| ): | |
| # selection of Solids of Compounds or CompSolids is not possible | |
| # because a Solid is no Subelement | |
| # since only Subelements can be selected | |
| # we're going to select all Faces of said Solids | |
| # the method getElement(element)doesn't return Solid elements | |
| solid = geomtools.get_element(ref[0], ref[1]) | |
| if not solid: | |
| return | |
| faces = [] | |
| for fs in solid.Faces: | |
| # find these faces in ref[0] | |
| for i, fref in enumerate(ref[0].Shape.Faces): | |
| if fs.isSame(fref): | |
| fref_elstring = "Face" + str(i + 1) | |
| if fref_elstring not in faces: | |
| faces.append(fref_elstring) | |
| for f in faces: | |
| FreeCADGui.Selection.addSelection(ref[0], f) | |
| else: | |
| # Selection of all other element types is supported | |
| 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 = [] | |
| def references_list_right_clicked(self, QPos): | |
| self.contextMenu = QtGui.QMenu() | |
| menu_item_remove_selected = self.contextMenu.addAction("Remove Selected Geometry") | |
| menu_item_remove_all = self.contextMenu.addAction("Clear List") | |
| if not self.references: | |
| menu_item_remove_selected.setDisabled(True) | |
| menu_item_remove_all.setDisabled(True) | |
| self.connect( | |
| menu_item_remove_selected, QtCore.SIGNAL("triggered()"), self.remove_selected_reference | |
| ) | |
| self.connect(menu_item_remove_all, QtCore.SIGNAL("triggered()"), self.remove_all_references) | |
| parentPosition = self.list_References.mapToGlobal(QtCore.QPoint(0, 0)) | |
| self.contextMenu.move(parentPosition + QPos) | |
| self.contextMenu.show() | |
| def remove_selected_reference(self): | |
| if not self.references: | |
| return | |
| currentItemName = str(self.list_References.currentItem().text()) | |
| currentRow = self.list_References.currentRow() | |
| for ref in self.references: | |
| if self.get_item_text(ref) == currentItemName: | |
| self.references.remove(ref) | |
| self.rebuild_list_References(currentRow) | |
| def remove_all_references(self): | |
| self.references = [] | |
| self.rebuild_list_References() | |
| def choose_selection_mode_standard(self, state): | |
| self.selection_mode_solid = not state | |
| if self.sel_server and not self.selection_mode_solid: | |
| FreeCAD.Console.PrintMessage(self.selection_mode_std_print_message + "\n") | |
| def choose_selection_mode_solid(self, state): | |
| self.selection_mode_solid = state | |
| if self.sel_server and self.selection_mode_solid: | |
| FreeCAD.Console.PrintMessage(self.selection_mode_solid_print_message + "\n") | |
| 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 | |
| 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 | |
| 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 | |
| self.sel_server = FemSelectionObserver(self.selectionParser, print_message) | |
| def selectionParser(self, selection): | |
| if hasattr(selection[0], "Shape") and selection[1]: | |
| FreeCAD.Console.PrintMessage( | |
| "Selection: {} {} {}\n".format( | |
| selection[0].Shape.ShapeType, selection[0].Name, selection[1] | |
| ) | |
| ) | |
| sobj = selection[0] | |
| elt = sobj.Shape.getElement(selection[1]) | |
| ele_ShapeType = elt.ShapeType | |
| if self.selection_mode_solid and "Solid" in self.sel_elem_types: | |
| # in solid selection mode use edges and faces for selection of a solid | |
| # adapt selection variable to hold the Solid | |
| solid_to_add = None | |
| if ele_ShapeType == "Edge": | |
| solid_indices = solids_with_edge(sobj, elt) | |
| elif ele_ShapeType == "Face": | |
| solid_indices = solids_with_face(sobj, elt) | |
| else: | |
| raise ValueError(f"Unexpected shape type: {ele_ShapeType}") | |
| if not solid_indices: | |
| raise ValueError( | |
| f"Selected {ele_ShapeType} does not appear to belong to any of the part's solids" | |
| ) | |
| elif len(solid_indices) == 1: | |
| solid_to_add = str(solid_indices[0] + 1) | |
| else: | |
| selected_solid = disambiguate_solid_selection(sobj, solid_indices) | |
| if selected_solid is not None: | |
| solid_to_add = selected_solid[len("Solid") :] | |
| if solid_to_add: | |
| selection = (sobj, "Solid" + solid_to_add) | |
| ele_ShapeType = "Solid" | |
| FreeCAD.Console.PrintMessage( | |
| " Selection variable adapted to hold the Solid: {} {} {}\n".format( | |
| sobj.Shape.ShapeType, sobj.Name, selection[1] | |
| ) | |
| ) | |
| else: | |
| return | |
| if ele_ShapeType in self.sel_elem_types: | |
| if ( | |
| self.selection_mode_solid and ele_ShapeType == "Solid" | |
| ) or self.selection_mode_solid is False: | |
| if selection not in self.references: | |
| # only equal shape types are allowed to add | |
| if self.allow_multiple_geom_types is False: | |
| if self.has_equal_references_shape_types(ele_ShapeType): | |
| self.references.append(selection) | |
| self.rebuild_list_References( | |
| self.get_allitems_text().index(self.get_item_text(selection)) | |
| ) | |
| else: | |
| # selected shape will not added to the list | |
| FreeCADGui.Selection.clearSelection() | |
| else: # multiple shape types are allowed to add | |
| self.references.append(selection) | |
| self.rebuild_list_References( | |
| self.get_allitems_text().index(self.get_item_text(selection)) | |
| ) | |
| else: | |
| # selected shape will not added to the list | |
| FreeCADGui.Selection.clearSelection() | |
| message = " Selection {} is in reference list already!\n".format( | |
| self.get_item_text(selection) | |
| ) | |
| FreeCAD.Console.PrintMessage(message) | |
| QtGui.QMessageBox.critical( | |
| None, "Geometry already in list", message.lstrip(" ") | |
| ) | |
| else: | |
| # selected shape will not added to the list | |
| FreeCADGui.Selection.clearSelection() | |
| message = ele_ShapeType + " is not allowed to add to the list!\n" | |
| FreeCAD.Console.PrintMessage(message) | |
| QtGui.QMessageBox.critical(None, "Wrong shape type", message) | |
| def has_equal_references_shape_types(self, ref_shty=""): | |
| for ref in self.references: | |
| # the method getElement(element) does not return Solid elements | |
| r = geomtools.get_element(ref[0], ref[1]) | |
| if not r: | |
| FreeCAD.Console.PrintError(f"Problem in retrieving element: {ref[1]} \n") | |
| continue | |
| FreeCAD.Console.PrintLog( | |
| " ReferenceShape : {}, {}, {} --> {}\n".format( | |
| r.ShapeType, ref[0].Name, ref[0].Label, ref[1] | |
| ) | |
| ) | |
| if not ref_shty: | |
| ref_shty = r.ShapeType | |
| if r.ShapeType != ref_shty: | |
| message = "Multiple shape types are not allowed in the reference list.\n" | |
| FreeCAD.Console.PrintMessage(message) | |
| QtGui.QMessageBox.critical(None, "Multiple ShapeTypes not allowed", message) | |
| return False | |
| return True | |
| def finish_selection(self): | |
| self.setback_listobj_visibility() | |
| if self.sel_server: | |
| FreeCADGui.Selection.removeObserver(self.sel_server) | |
| class FemSelectionObserver: | |
| """selection observer especially for the needs of geometry reference selection of FEM""" | |
| def __init__(self, parseSelectionFunction, print_message=""): | |
| self.parseSelectionFunction = parseSelectionFunction | |
| FreeCADGui.Selection.addObserver(self) | |
| # FreeCAD.Console.PrintMessage(print_message + "!\n") | |
| def addSelection(self, docName, objName, sub, pos): | |
| selected_object = FreeCAD.getDocument(docName).getObject(objName) # get the obj objName | |
| if FreeCADGui.editDocument().getInEdit().Object.Document != selected_object.Document: | |
| QtGui.QMessageBox.critical( | |
| None, "Selection error", "External object selection is not supported" | |
| ) | |
| FreeCADGui.Selection.clearSelection() | |
| return | |
| self.added_obj = (selected_object, sub) | |
| # on double click on a vertex of a solid sub is None and obj is the solid | |
| self.parseSelectionFunction(self.added_obj) | |