mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2024-11-11 16:19:17 +05:00
[bos #38044][EDF] (2023-T3) Support for automatic reparation. Updated UI.
This commit is contained in:
parent
583263c43e
commit
6715a241c1
@ -45,6 +45,7 @@ IF(SALOME_BUILD_GUI)
|
||||
SET(_gui_SCRIPTS
|
||||
basedlg.py
|
||||
basedlg.ui
|
||||
subshapes_basedlg.py
|
||||
${geom_dlg_ref}/DlgRef_1Sel_QTD.ui
|
||||
DlgRef_1Spin_QTD.ui # copied because original was promoted to SalomeApp_DoubleSpinBox
|
||||
)
|
||||
|
@ -32,6 +32,7 @@ from libGEOM_Swig import GEOM_Swig
|
||||
|
||||
from .basedlg_ui import Ui_BaseDlg
|
||||
from .geomrepairadv_execute import execute
|
||||
from .geomrepairadv_logger import logger
|
||||
from .geomrepairadv_common import DlgRef_1Sel_QTD, \
|
||||
GEOM_RESULT_NAME_GRP, NAME_LBL, GEOM_SELECTED_LBL, GEOM_SELECTED_SHAPE
|
||||
import GEOM
|
||||
@ -236,6 +237,23 @@ class BaseDlg(Ui_BaseDlg, QWidget):
|
||||
return self._result_widget.LineEdit1.text()
|
||||
|
||||
|
||||
def set_selection_level(self, selection_level):
|
||||
"""
|
||||
Sets selection level.
|
||||
|
||||
Args:
|
||||
selection_level - GEOM selection level.
|
||||
|
||||
Returns:
|
||||
None.
|
||||
"""
|
||||
|
||||
self._selection_level = selection_level
|
||||
|
||||
# Update selection for current object
|
||||
self.on_select_object()
|
||||
|
||||
|
||||
def set_selection(self, entry = None):
|
||||
"""
|
||||
Sets selection level to self._selection_level or resets it.
|
||||
@ -291,6 +309,47 @@ class BaseDlg(Ui_BaseDlg, QWidget):
|
||||
self.set_selection(entry)
|
||||
|
||||
|
||||
def get_local_selection(self):
|
||||
"""
|
||||
Returns selected sub-shapes ids.
|
||||
|
||||
Args:
|
||||
None.
|
||||
|
||||
Returns:
|
||||
List of ids.
|
||||
"""
|
||||
|
||||
geom_swig = GEOM_Swig()
|
||||
selected_ids = geom_swig.getLocalSelection()
|
||||
logger.debug('selected_ids: %s', selected_ids)
|
||||
|
||||
return selected_ids
|
||||
|
||||
|
||||
def is_selection_valid(self, selected_ids, min_selected):
|
||||
"""
|
||||
Checks number of sub-shapes ids.
|
||||
|
||||
Args:
|
||||
selected_ids - list of selected.
|
||||
|
||||
Returns:
|
||||
True if we have valid number of ids.
|
||||
"""
|
||||
|
||||
if len(selected_ids) < min_selected:
|
||||
QMessageBox.warning(
|
||||
None,
|
||||
'Warning',
|
||||
'The algorithm needs at least {} selected sub-shapes!\n'
|
||||
'Operation was canceled.'.format(min_selected)
|
||||
)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""
|
||||
Overrides default close envent to reset selection level.
|
||||
|
@ -53,7 +53,12 @@ class DlgRef_1Spin_QTD(Ui_DlgRef_1Spin_QTD, QWidget):
|
||||
We need it because a class generated from ui file is derived from an object and
|
||||
cannot be added as a widget to a dialog's layout.
|
||||
"""
|
||||
def __init__(self):
|
||||
def __init__(self, title, default_value, decimals, max_value):
|
||||
QWidget.__init__(self)
|
||||
# Set up the user interface from Designer.
|
||||
self.setupUi(self)
|
||||
|
||||
self.TextLabel1.setText(title)
|
||||
self.SpinBox_DX.setValue(default_value)
|
||||
self.SpinBox_DX.setDecimals(decimals)
|
||||
self.SpinBox_DX.setMaximum(max_value)
|
||||
|
@ -22,8 +22,9 @@
|
||||
import os
|
||||
import sys
|
||||
import importlib.util
|
||||
from traceback import format_exc
|
||||
|
||||
from qtsalome import QApplication, QFileDialog
|
||||
from qtsalome import QApplication, QFileDialog, QMessageBox
|
||||
|
||||
from salome.kernel.services import ObjectToID
|
||||
from salome.geom.geomtools import GeomStudyTools
|
||||
@ -68,7 +69,18 @@ def module_from_filename(filename):
|
||||
logger.error('spec.loader is None for %s module!', module_name)
|
||||
return None
|
||||
|
||||
spec.loader.exec_module(module)
|
||||
try:
|
||||
spec.loader.exec_module(module)
|
||||
|
||||
except FileNotFoundError:
|
||||
logger.error(format_exc())
|
||||
QMessageBox.warning(
|
||||
None,
|
||||
'Error',
|
||||
'Cannot find module {}!\nOperation was canceled.'.format(module_name)
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
return module
|
||||
|
||||
|
@ -21,9 +21,11 @@
|
||||
|
||||
import sys
|
||||
|
||||
from qtsalome import QGridLayout, QFrame, QApplication
|
||||
from qtsalome import QGridLayout, QFrame, QApplication, QComboBox, QLabel, QPushButton, QMessageBox
|
||||
|
||||
from salome.geom.geomrepairadv.basedlg import BaseDlg
|
||||
|
||||
from .geomrepairadv_common import DlgRef_1Spin_QTD
|
||||
import GEOM
|
||||
|
||||
class LocateSubShapesDlg(BaseDlg):
|
||||
@ -31,14 +33,141 @@ class LocateSubShapesDlg(BaseDlg):
|
||||
Dialog for Locate Subshapes plugin that selects the sub-shapes of a compound
|
||||
by length, area or volume depending on whether it is an EDGE, a FACE or a SOLID.
|
||||
"""
|
||||
def __init__(self, selection_level = GEOM.COMPOUND):
|
||||
def __init__(self, selection_level = GEOM.EDGE):
|
||||
# Implement widget's content here
|
||||
main_widget = QFrame()
|
||||
layout = QGridLayout(main_widget)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
# A combobox to choose measurment type
|
||||
type_label = QLabel('Shape Measurement')
|
||||
self._type_widget = QComboBox()
|
||||
type_items = ['Length (EDGE)', 'Area (FACE)', 'Volume (SOLID)']
|
||||
self._type_widget.insertItems(0, type_items)
|
||||
self._type_widget.setToolTip('Select a type of shape measurement')
|
||||
self._type_widget.currentIndexChanged.connect(self.on_measurment_type_changed)
|
||||
|
||||
# Min/max values widgets
|
||||
decimals = 2
|
||||
max_value = sys.float_info.max
|
||||
self._min_widget = DlgRef_1Spin_QTD('Min', 0, decimals, max_value)
|
||||
self._max_widget = DlgRef_1Spin_QTD('Max', 100, decimals, max_value)
|
||||
|
||||
# Add select button
|
||||
self._select_button = QPushButton("Show Selected Sub-shapes")
|
||||
self._select_button.clicked.connect(self.on_select_button_clicked)
|
||||
|
||||
# Add the widgets to layout
|
||||
layout.addWidget(type_label, 0, 0)
|
||||
layout.addWidget(self._type_widget, 1, 0)
|
||||
layout.addWidget(self._min_widget, 2, 0)
|
||||
layout.addWidget(self._max_widget, 3, 0)
|
||||
layout.addWidget(self._select_button, 4, 0)
|
||||
|
||||
# Init base dialog
|
||||
BaseDlg.__init__(
|
||||
self, main_widget, 'Locate Subshapes', 'locate_subshapes_algo.py', False, selection_level)
|
||||
self,
|
||||
main_widget,
|
||||
'Locate Subshapes',
|
||||
'locate_subshapes_algo.py',
|
||||
False,
|
||||
selection_level
|
||||
)
|
||||
|
||||
|
||||
def get_limits(self):
|
||||
"""
|
||||
Returns current values for min/max limits.
|
||||
|
||||
Args:
|
||||
None.
|
||||
|
||||
Returns:
|
||||
List of limits [min, max].
|
||||
"""
|
||||
|
||||
return [self._min_widget.SpinBox_DX.value(),
|
||||
self._max_widget.SpinBox_DX.value()]
|
||||
|
||||
|
||||
def get_measurment_type(self, index):
|
||||
"""
|
||||
Returns selection level based on current measurment type.
|
||||
|
||||
Args:
|
||||
index - current combobox index.
|
||||
|
||||
Returns:
|
||||
GEOM selection level value.
|
||||
"""
|
||||
|
||||
measurment_types = {
|
||||
0 : GEOM.EDGE,
|
||||
1 : GEOM.FACE,
|
||||
2 : GEOM.SOLID
|
||||
}
|
||||
|
||||
return measurment_types[index]
|
||||
|
||||
|
||||
def on_measurment_type_changed(self, index):
|
||||
"""
|
||||
Changes selection level on type changed.
|
||||
|
||||
Args:
|
||||
index - current combobox index.
|
||||
|
||||
Returns:
|
||||
None.
|
||||
"""
|
||||
|
||||
selection_level = self.get_measurment_type(index)
|
||||
self.set_selection_level(selection_level)
|
||||
|
||||
|
||||
def on_select_button_clicked(self):
|
||||
"""
|
||||
Show selection info on button click.
|
||||
|
||||
Args:
|
||||
None.
|
||||
|
||||
Returns:
|
||||
None.
|
||||
"""
|
||||
|
||||
#TODO: what are we going to do on this click?
|
||||
# Should it do a separated script?
|
||||
QMessageBox.warning(None, 'Warning', 'Not implemented yet')
|
||||
|
||||
|
||||
def get_args(self):
|
||||
"""
|
||||
Collects arguments for a repair execution algorithm into a dictionary.
|
||||
|
||||
Args:
|
||||
None.
|
||||
|
||||
Returns:
|
||||
Dictionary with arguments for execution.
|
||||
"""
|
||||
|
||||
selected_ids = self.get_local_selection()
|
||||
current_index = self._type_widget.currentIndex()
|
||||
selection_level = self.get_measurment_type(current_index)
|
||||
limits = self.get_limits()
|
||||
min_selected = 1
|
||||
|
||||
if self.is_selection_valid(selected_ids, min_selected):
|
||||
return {
|
||||
'selected_ids': selected_ids,
|
||||
'result_name': self.get_result_name(),
|
||||
'selection_level': selection_level,
|
||||
'min_limit': limits[0],
|
||||
'max_limit': limits[1]
|
||||
}
|
||||
|
||||
return None
|
||||
|
||||
|
||||
# For testing run as a module from geomrepairadv parent directory in
|
||||
|
@ -21,76 +21,19 @@
|
||||
|
||||
import sys
|
||||
|
||||
from qtsalome import QGridLayout, QFrame, QMessageBox, QApplication
|
||||
from qtsalome import QApplication
|
||||
|
||||
from libGEOM_Swig import GEOM_Swig
|
||||
from .geomrepairadv_logger import logger
|
||||
from .basedlg import BaseDlg
|
||||
from .geomrepairadv_common import DlgRef_1Spin_QTD
|
||||
from .subshapes_basedlg import SubShapesBaseDlg
|
||||
import GEOM
|
||||
|
||||
class MergeFacesDlg(BaseDlg):
|
||||
class MergeFacesDlg(SubShapesBaseDlg):
|
||||
"""
|
||||
Dialog for Merge Faces plugin that merges selected faces with a given precision.
|
||||
"""
|
||||
|
||||
def __init__(self, selection_level = GEOM.FACE):
|
||||
# Make layout for new widgets
|
||||
main_widget = QFrame()
|
||||
layout = QGridLayout(main_widget)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
# Precision widget
|
||||
self._precision_widget = DlgRef_1Spin_QTD()
|
||||
self._precision_widget.TextLabel1.setText('Precision')
|
||||
layout.addWidget(self._precision_widget, 0, 0)
|
||||
|
||||
BaseDlg.__init__(
|
||||
self, main_widget, 'Merge Faces', 'merge_faces_algo.py', True, selection_level)
|
||||
|
||||
|
||||
def get_precision(self):
|
||||
"""
|
||||
Returns current precision value.
|
||||
|
||||
Args:
|
||||
None.
|
||||
|
||||
Returns:
|
||||
Double.
|
||||
"""
|
||||
|
||||
return self._precision_widget.SpinBox_DX.value()
|
||||
|
||||
|
||||
def get_args(self):
|
||||
"""
|
||||
Collects arguments for a repair execution algorithm into a dictionary.
|
||||
|
||||
Args:
|
||||
None.
|
||||
|
||||
Returns:
|
||||
Dictionary with arguments for execution.
|
||||
"""
|
||||
|
||||
geom_swig = GEOM_Swig()
|
||||
faces_ids = geom_swig.getLocalSelection()
|
||||
logger.debug('faces_ids: %s', faces_ids)
|
||||
|
||||
if len(faces_ids) < 2:
|
||||
QMessageBox.warning(
|
||||
None,
|
||||
'Warning',
|
||||
'The algorithm needs at least two selected faces!\nMerging was canceled.'
|
||||
)
|
||||
return None
|
||||
|
||||
return {
|
||||
'faces_ids': faces_ids,
|
||||
'result_name': self.get_result_name(),
|
||||
'precision': self.get_precision()
|
||||
}
|
||||
SubShapesBaseDlg.__init__(
|
||||
self, 'Merge Faces', 'merge_faces_algo.py', True, selection_level, 2)
|
||||
|
||||
|
||||
# For testing run as a module from geomrepairadv parent directory in
|
||||
|
@ -52,14 +52,15 @@ def run(args_dict, progress_emitter):
|
||||
|
||||
|
||||
if ('source_solid' not in args_dict or
|
||||
'faces_ids' not in args_dict or
|
||||
'result_name' not in args_dict):
|
||||
'selected_ids' not in args_dict or
|
||||
'result_name' not in args_dict or
|
||||
'precision' not in args_dict):
|
||||
|
||||
logging.info('Cant execute an algo because the arguments are empty!')
|
||||
return False
|
||||
|
||||
source_solid = args_dict['source_solid']
|
||||
faces_ids = args_dict['faces_ids']
|
||||
faces_ids = args_dict['selected_ids']
|
||||
result_name = args_dict['result_name']
|
||||
|
||||
|
||||
|
99
src/RepairGUIAdv/subshapes_basedlg.py
Normal file
99
src/RepairGUIAdv/subshapes_basedlg.py
Normal file
@ -0,0 +1,99 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014-2024 EDF
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library 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
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See https://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
#
|
||||
# Author : Konstantin Leontev (OpenCascade S.A.S)
|
||||
|
||||
import sys
|
||||
|
||||
from qtsalome import QGridLayout, QFrame, QApplication
|
||||
|
||||
from .basedlg import BaseDlg
|
||||
from .geomrepairadv_common import DlgRef_1Spin_QTD
|
||||
|
||||
class SubShapesBaseDlg(BaseDlg):
|
||||
"""
|
||||
Base dialog for Merge Faces and Union Edges plugins that provides
|
||||
to algorithm selected faces with a given precision.
|
||||
"""
|
||||
|
||||
def __init__(self, window_title, algo_name, is_default_location, selection_level, min_selected):
|
||||
# Set min number of selected sub-shapes
|
||||
self._min_selected = min_selected
|
||||
|
||||
# Make layout for new widgets
|
||||
main_widget = QFrame()
|
||||
layout = QGridLayout(main_widget)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
# Precision widget
|
||||
self._precision_widget = DlgRef_1Spin_QTD('Precision', 0, 2, 100)
|
||||
layout.addWidget(self._precision_widget, 0, 0)
|
||||
|
||||
BaseDlg.__init__(
|
||||
self, main_widget, window_title, algo_name, is_default_location, selection_level)
|
||||
|
||||
|
||||
def get_precision(self):
|
||||
"""
|
||||
Returns current precision value.
|
||||
|
||||
Args:
|
||||
None.
|
||||
|
||||
Returns:
|
||||
Double.
|
||||
"""
|
||||
|
||||
return self._precision_widget.SpinBox_DX.value()
|
||||
|
||||
|
||||
def get_args(self):
|
||||
"""
|
||||
Collects arguments for a repair execution algorithm into a dictionary.
|
||||
|
||||
Args:
|
||||
None.
|
||||
|
||||
Returns:
|
||||
Dictionary with arguments for execution.
|
||||
"""
|
||||
|
||||
selected_ids = self.get_local_selection()
|
||||
if self.is_selection_valid(selected_ids, self._min_selected):
|
||||
return {
|
||||
'selected_ids': selected_ids,
|
||||
'result_name': self.get_result_name(),
|
||||
'precision': self.get_precision()
|
||||
}
|
||||
|
||||
return None
|
||||
|
||||
|
||||
# For testing run as a module from geomrepairadv parent directory in
|
||||
# Salome INSTALL, because the dialog needs a generated Ui_BaseDlg class
|
||||
# that we don't have in the SOURCE.
|
||||
# Example:
|
||||
# $ python -m geomrepairadv.subshapes_basedlg
|
||||
if __name__ == '__main__':
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
dlg = SubShapesBaseDlg('Test SubShapesBaseDlg', 'merge_faces_algo.py', True, None, 1)
|
||||
dlg.show()
|
||||
|
||||
sys.exit(app.exec_())
|
@ -21,23 +21,18 @@
|
||||
|
||||
import sys
|
||||
|
||||
from qtsalome import QGridLayout, QFrame, QApplication
|
||||
from qtsalome import QApplication
|
||||
|
||||
from salome.geom.geomrepairadv.basedlg import BaseDlg
|
||||
from .subshapes_basedlg import SubShapesBaseDlg
|
||||
import GEOM
|
||||
|
||||
class UnionEdgesDlg(BaseDlg):
|
||||
class UnionEdgesDlg(SubShapesBaseDlg):
|
||||
"""
|
||||
Dialog for Union Edges plugin that unifies edges of selected face.
|
||||
"""
|
||||
def __init__(self, selection_level = GEOM.COMPOUND):
|
||||
# Implement widget's content here
|
||||
main_widget = QFrame()
|
||||
layout = QGridLayout(main_widget)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
BaseDlg.__init__(
|
||||
self, main_widget, 'Union Edges', 'union_edges_algo.py', False, selection_level)
|
||||
def __init__(self, selection_level = GEOM.FACE):
|
||||
SubShapesBaseDlg.__init__(
|
||||
self, 'Union Edges', 'union_edges_algo.py', False, selection_level, 1)
|
||||
|
||||
|
||||
# For testing run as a module from geomrepairadv parent directory in
|
||||
|
Loading…
Reference in New Issue
Block a user