588 lines
25 KiB
Python
588 lines
25 KiB
Python
# ***************************************************************************
|
|
# * 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 PySide import QtGui
|
|
from PySide import QtCore
|
|
|
|
import FreeCAD
|
|
import FreeCADGui
|
|
import FreeCADGui as Gui
|
|
|
|
from femtools import geomtools
|
|
|
|
|
|
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)
|
|
|
|
@QtCore.Slot()
|
|
def _add(self):
|
|
selection = self.getSelection()
|
|
self._updateReferences(selection)
|
|
|
|
@QtCore.Slot()
|
|
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"))
|
|
# label
|
|
self._helpTextLbl = QtGui.QLabel()
|
|
self._helpTextLbl.setWordWrap(True)
|
|
helpTextPart1 = self.tr(
|
|
'Click on "Add" 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>")
|
|
helpTextEmpty = self.tr(
|
|
"{}If no geometry is added to the list, all remaining ones are used."
|
|
).format("<br>")
|
|
if self.showHintEmptyList is True:
|
|
self._helpTextLbl.setText(helpTextPart1 + helpTextEmpty)
|
|
else:
|
|
self._helpTextLbl.setText(helpTextPart1)
|
|
# 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)
|
|
# main layout
|
|
mainLayout = QtGui.QVBoxLayout()
|
|
mainLayout.addWidget(self._helpTextLbl)
|
|
mainLayout.addWidget(self.pushButton_Add)
|
|
mainLayout.addWidget(self.list_References)
|
|
|
|
# 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.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":
|
|
found_eltedge_in_other_solid = False
|
|
for i, s in enumerate(sobj.Shape.Solids):
|
|
for e in s.Edges:
|
|
if elt.isSame(e):
|
|
if found_eltedge_in_other_solid is False:
|
|
solid_to_add = str(i + 1)
|
|
else:
|
|
# could be more than two solids, think of polar pattern
|
|
FreeCAD.Console.PrintMessage(
|
|
" Edge belongs to at least two solids: "
|
|
" Solid{}, Solid{}\n".format(solid_to_add, str(i + 1))
|
|
)
|
|
solid_to_add = None
|
|
found_eltedge_in_other_solid = True
|
|
elif ele_ShapeType == "Face":
|
|
found_eltface_in_other_solid = False
|
|
for i, s in enumerate(sobj.Shape.Solids):
|
|
for e in s.Faces:
|
|
if elt.isSame(e):
|
|
if not found_eltface_in_other_solid:
|
|
solid_to_add = str(i + 1)
|
|
else:
|
|
# AFAIK (bernd) a face can only belong to two solids
|
|
FreeCAD.Console.PrintMessage(
|
|
" Face belongs to two solids: Solid{}, Solid{}\n".format(
|
|
solid_to_add, str(i + 1)
|
|
)
|
|
)
|
|
solid_to_add = None
|
|
found_eltface_in_other_solid = True
|
|
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
|
|
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)
|