mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2024-12-26 17:30:35 +05:00
[bos #38044][EDF] (2023-T3) Support for automatic reparation. Base implementation of Sub-Shape dialog.
This commit is contained in:
parent
8ef86c6185
commit
cd33417290
@ -37,6 +37,7 @@ IF(SALOME_BUILD_GUI)
|
|||||||
geomrepairadv_worker.py
|
geomrepairadv_worker.py
|
||||||
locate_subshapes.py
|
locate_subshapes.py
|
||||||
locate_subshapes_algo.py
|
locate_subshapes_algo.py
|
||||||
|
locate_subshapes_limits.py
|
||||||
merge_faces.py
|
merge_faces.py
|
||||||
merge_faces_algo.py
|
merge_faces_algo.py
|
||||||
union_edges.py
|
union_edges.py
|
||||||
|
@ -120,8 +120,7 @@ class BaseDlg(Ui_BaseDlg, QWidget):
|
|||||||
|
|
||||||
# Execution module
|
# Execution module
|
||||||
# Name of particular algo module for each repair class
|
# Name of particular algo module for each repair class
|
||||||
self._algo_name = ''
|
self._algo_name = self.set_algoname(algo_name, is_default_location)
|
||||||
self.set_algoname(algo_name, is_default_location)
|
|
||||||
|
|
||||||
# Let it be always on top of the application.
|
# Let it be always on top of the application.
|
||||||
# We need it because this dialog will run without parent.
|
# We need it because this dialog will run without parent.
|
||||||
@ -130,7 +129,6 @@ class BaseDlg(Ui_BaseDlg, QWidget):
|
|||||||
# Default selection level
|
# Default selection level
|
||||||
self._selection_level = selection_level
|
self._selection_level = selection_level
|
||||||
self._is_level_changed = False
|
self._is_level_changed = False
|
||||||
self._is_local_selection = False
|
|
||||||
|
|
||||||
# Connect selection manager
|
# Connect selection manager
|
||||||
salome_pyqt = SalomePyQt.SalomePyQt()
|
salome_pyqt = SalomePyQt.SalomePyQt()
|
||||||
@ -219,9 +217,9 @@ class BaseDlg(Ui_BaseDlg, QWidget):
|
|||||||
|
|
||||||
if is_default_location:
|
if is_default_location:
|
||||||
package_dir = Path(__file__).parent.absolute()
|
package_dir = Path(__file__).parent.absolute()
|
||||||
self._algo_name = package_dir.joinpath(algo_name)
|
return package_dir.joinpath(algo_name)
|
||||||
else:
|
else:
|
||||||
self._algo_name = algo_name
|
return algo_name
|
||||||
|
|
||||||
|
|
||||||
def set_result_name(self, name):
|
def set_result_name(self, name):
|
||||||
@ -252,6 +250,20 @@ class BaseDlg(Ui_BaseDlg, QWidget):
|
|||||||
return self._result_widget.LineEdit1.text()
|
return self._result_widget.LineEdit1.text()
|
||||||
|
|
||||||
|
|
||||||
|
def get_selection_level(self):
|
||||||
|
"""
|
||||||
|
Return current selection level.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Selection level.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self._selection_level
|
||||||
|
|
||||||
|
|
||||||
def set_selection_level(self, selection_level):
|
def set_selection_level(self, selection_level):
|
||||||
"""
|
"""
|
||||||
Sets selection level.
|
Sets selection level.
|
||||||
@ -296,23 +308,18 @@ class BaseDlg(Ui_BaseDlg, QWidget):
|
|||||||
# Init it again if the level was changed
|
# Init it again if the level was changed
|
||||||
if self._is_level_changed:
|
if self._is_level_changed:
|
||||||
geom_swig.closeLocalSelection()
|
geom_swig.closeLocalSelection()
|
||||||
self._is_local_selection = False
|
|
||||||
|
|
||||||
# We need to init a local selection only once
|
|
||||||
if not self._is_local_selection:
|
|
||||||
# Init it here
|
# Init it here
|
||||||
sel_level = geomBuilder.EnumToLong(self._selection_level)
|
sel_level = geomBuilder.EnumToLong(self._selection_level)
|
||||||
geom_swig.initLocalSelection(entry, sel_level)
|
geom_swig.initLocalSelection(entry, sel_level)
|
||||||
|
|
||||||
self._is_local_selection = True
|
|
||||||
else:
|
else:
|
||||||
# No entry - no local selection
|
# No entry - no local selection
|
||||||
geom_swig.closeLocalSelection()
|
geom_swig.closeLocalSelection()
|
||||||
self._is_local_selection = False
|
|
||||||
|
|
||||||
# We don't need the flag after selection was set
|
# We don't need the flag after selection was set
|
||||||
self._is_level_changed = False
|
self._is_level_changed = False
|
||||||
|
|
||||||
|
|
||||||
def on_select_object(self):
|
def on_select_object(self):
|
||||||
"""
|
"""
|
||||||
Adds selected object to a dialog.
|
Adds selected object to a dialog.
|
||||||
|
@ -85,14 +85,15 @@ def module_from_filename(filename):
|
|||||||
return module
|
return module
|
||||||
|
|
||||||
|
|
||||||
def execute(selected_object, algo_name, args_dict):
|
def execute(selected_object, algo_name, args_dict, is_dump_on = True):
|
||||||
"""
|
"""
|
||||||
Executes GEOM advanced repair algorithm.
|
Executes GEOM advanced repair algorithm.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
selected_object - geom object selected by user for algorithm
|
selected_object - geom object selected by user for algorithm
|
||||||
algo_name - path to the algo module
|
algo_name - path to the algo module
|
||||||
args_dict - dictionary with arguments those are specific for each algo.
|
args_dict - dictionary with arguments those are specific for each algo
|
||||||
|
is_dump_on - if True saves the call to the Python dump.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Result GEOM object or None if failed or canceled.
|
Result GEOM object or None if failed or canceled.
|
||||||
@ -136,6 +137,7 @@ def execute(selected_object, algo_name, args_dict):
|
|||||||
logger.error('Could not get a result object after exec of %s file!', str(algo_name))
|
logger.error('Could not get a result object after exec of %s file!', str(algo_name))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
if is_dump_on:
|
||||||
geompy.FuncToPythonDump(
|
geompy.FuncToPythonDump(
|
||||||
selected_object,
|
selected_object,
|
||||||
result_object,
|
result_object,
|
||||||
|
@ -25,8 +25,10 @@ from qtsalome import QGridLayout, QFrame, QApplication, \
|
|||||||
QComboBox, QLabel, QPushButton, QMessageBox
|
QComboBox, QLabel, QPushButton, QMessageBox
|
||||||
|
|
||||||
from salome.geom.geomrepairadv.basedlg import BaseDlg
|
from salome.geom.geomrepairadv.basedlg import BaseDlg
|
||||||
|
from salome.geom import geomBuilder
|
||||||
|
|
||||||
from .geomrepairadv_common import DlgRef_1Spin_QTD
|
from .geomrepairadv_common import DlgRef_1Spin_QTD
|
||||||
|
from .geomrepairadv_execute import execute
|
||||||
import GEOM
|
import GEOM
|
||||||
|
|
||||||
class LocateSubShapesDlg(BaseDlg):
|
class LocateSubShapesDlg(BaseDlg):
|
||||||
@ -34,7 +36,13 @@ class LocateSubShapesDlg(BaseDlg):
|
|||||||
Dialog for Locate Subshapes plugin that selects the sub-shapes of a compound
|
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.
|
by length, area or volume depending on whether it is an EDGE, a FACE or a SOLID.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
SUBSHAPES_LABEL_TEXT = 'Sub-shapes: '
|
||||||
|
|
||||||
def __init__(self, selection_level = GEOM.EDGE):
|
def __init__(self, selection_level = GEOM.EDGE):
|
||||||
|
# Path to Min/max script
|
||||||
|
self._minmax_algo = self.set_algoname('locate_subshapes_limits.py', True)
|
||||||
|
|
||||||
# Implement widget's content here
|
# Implement widget's content here
|
||||||
main_widget = QFrame()
|
main_widget = QFrame()
|
||||||
layout = QGridLayout(main_widget)
|
layout = QGridLayout(main_widget)
|
||||||
@ -48,11 +56,22 @@ class LocateSubShapesDlg(BaseDlg):
|
|||||||
self._type_widget.setToolTip('Select a type of shape measurement')
|
self._type_widget.setToolTip('Select a type of shape measurement')
|
||||||
self._type_widget.currentIndexChanged.connect(self.on_measurment_type_changed)
|
self._type_widget.currentIndexChanged.connect(self.on_measurment_type_changed)
|
||||||
|
|
||||||
|
# Add Min/Max button
|
||||||
|
self._minmax_button = QPushButton("Compute Min/Max")
|
||||||
|
self._minmax_button.clicked.connect(self.on_minmax_button_clicked)
|
||||||
|
|
||||||
# Min/max values widgets
|
# Min/max values widgets
|
||||||
decimals = 2
|
decimals = 2
|
||||||
max_value = sys.float_info.max
|
max_value = sys.float_info.max
|
||||||
self._min_widget = DlgRef_1Spin_QTD('Min', 0, decimals, max_value)
|
self._min_widget = DlgRef_1Spin_QTD('Min', 0, decimals, max_value)
|
||||||
self._max_widget = DlgRef_1Spin_QTD('Max', 100, decimals, max_value)
|
self._max_widget = DlgRef_1Spin_QTD('Max', 1000, decimals, max_value)
|
||||||
|
self._min_widget.SpinBox_DX.valueChanged.connect(self.on_limit_changed)
|
||||||
|
self._max_widget.SpinBox_DX.valueChanged.connect(self.on_limit_changed)
|
||||||
|
|
||||||
|
# Sub-shapes number
|
||||||
|
self._subshapes_selected = 0
|
||||||
|
self._subshapes_total = 0
|
||||||
|
self._subshapes_label = QLabel()
|
||||||
|
|
||||||
# Add select button
|
# Add select button
|
||||||
self._select_button = QPushButton("Show Selected Sub-shapes")
|
self._select_button = QPushButton("Show Selected Sub-shapes")
|
||||||
@ -60,10 +79,12 @@ class LocateSubShapesDlg(BaseDlg):
|
|||||||
|
|
||||||
# Add the widgets to layout
|
# Add the widgets to layout
|
||||||
layout.addWidget(type_label, 0, 0)
|
layout.addWidget(type_label, 0, 0)
|
||||||
layout.addWidget(self._type_widget, 1, 0)
|
layout.addWidget(self._minmax_button, 1, 0)
|
||||||
layout.addWidget(self._min_widget, 2, 0)
|
layout.addWidget(self._type_widget, 2, 0)
|
||||||
layout.addWidget(self._max_widget, 3, 0)
|
layout.addWidget(self._min_widget, 3, 0)
|
||||||
layout.addWidget(self._select_button, 4, 0)
|
layout.addWidget(self._max_widget, 4, 0)
|
||||||
|
layout.addWidget(self._subshapes_label, 5, 0)
|
||||||
|
layout.addWidget(self._select_button, 6, 0)
|
||||||
|
|
||||||
# Init base dialog
|
# Init base dialog
|
||||||
BaseDlg.__init__(
|
BaseDlg.__init__(
|
||||||
@ -91,6 +112,21 @@ class LocateSubShapesDlg(BaseDlg):
|
|||||||
self._max_widget.SpinBox_DX.value()]
|
self._max_widget.SpinBox_DX.value()]
|
||||||
|
|
||||||
|
|
||||||
|
def set_limits(self, min_value, max_value):
|
||||||
|
"""
|
||||||
|
Sets given values for min/max limits.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self._min_widget.SpinBox_DX.setValue(min_value)
|
||||||
|
self._max_widget.SpinBox_DX.setValue(max_value)
|
||||||
|
|
||||||
|
|
||||||
def get_measurment_type(self, index):
|
def get_measurment_type(self, index):
|
||||||
"""
|
"""
|
||||||
Returns selection level based on current measurment type.
|
Returns selection level based on current measurment type.
|
||||||
@ -111,6 +147,62 @@ class LocateSubShapesDlg(BaseDlg):
|
|||||||
return measurment_types[index]
|
return measurment_types[index]
|
||||||
|
|
||||||
|
|
||||||
|
def set_subshapes_counters(self, selected, total):
|
||||||
|
"""
|
||||||
|
Set counters for selected and total subshapes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self._subshapes_selected = selected
|
||||||
|
self._subshapes_total = total
|
||||||
|
|
||||||
|
|
||||||
|
def update_subshapes_label(self):
|
||||||
|
"""
|
||||||
|
Updates a text of Sub-Shapes label.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None.
|
||||||
|
"""
|
||||||
|
|
||||||
|
selected = str(self._subshapes_selected)
|
||||||
|
total = str(self._subshapes_total)
|
||||||
|
|
||||||
|
self._subshapes_label.setText(self.SUBSHAPES_LABEL_TEXT + selected + '/' + total)
|
||||||
|
|
||||||
|
|
||||||
|
def update_subshapes_info(self):
|
||||||
|
"""
|
||||||
|
Updates all info about Sub-Shapes in the dialog.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not self._selected_object:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Update counters
|
||||||
|
geompy = geomBuilder.New()
|
||||||
|
all_ids = geompy.SubShapeAllIDs(self._selected_object, self.get_selection_level())
|
||||||
|
selected_ids = self.get_local_selection()
|
||||||
|
self.set_subshapes_counters(len(selected_ids), len(all_ids))
|
||||||
|
|
||||||
|
# Update label
|
||||||
|
self.update_subshapes_label()
|
||||||
|
|
||||||
|
|
||||||
def on_measurment_type_changed(self, index):
|
def on_measurment_type_changed(self, index):
|
||||||
"""
|
"""
|
||||||
Changes selection level on type changed.
|
Changes selection level on type changed.
|
||||||
@ -128,6 +220,78 @@ class LocateSubShapesDlg(BaseDlg):
|
|||||||
# Clear pre selected sub-shapes list
|
# Clear pre selected sub-shapes list
|
||||||
self.on_select_subshape()
|
self.on_select_subshape()
|
||||||
|
|
||||||
|
self.update_subshapes_info()
|
||||||
|
|
||||||
|
|
||||||
|
def select_subshapes_in_limits(self):
|
||||||
|
"""
|
||||||
|
Updates a text of Sub-Shapes label.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not self._selected_object:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Get all sub-shapes
|
||||||
|
geompy = geomBuilder.New()
|
||||||
|
selection_level = self.get_selection_level()
|
||||||
|
subshapes_ids = geompy.SubShapeAllIDs(self._selected_object, selection_level)
|
||||||
|
|
||||||
|
# Iterate over ids to check if it fits to limits
|
||||||
|
# TODO: implement selections
|
||||||
|
limits = self.get_limits()
|
||||||
|
for id in subshapes_ids:
|
||||||
|
# Get a sub-shape by id
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Get related parameter to check it later
|
||||||
|
param = None
|
||||||
|
if selection_level == GEOM.EDGE:
|
||||||
|
# Get a lenght of an edge
|
||||||
|
pass
|
||||||
|
elif selection_level == GEOM.FACE:
|
||||||
|
# Get an area of a face
|
||||||
|
pass
|
||||||
|
elif selection_level == GEOM.SOLID:
|
||||||
|
# Get a volume of a solid
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# We shouldn't fall here
|
||||||
|
QMessageBox.warning(
|
||||||
|
None, 'Warning', 'Wrong selection level: %s!' % (selection_level))
|
||||||
|
return
|
||||||
|
|
||||||
|
# Check if it fits to the limits
|
||||||
|
if param >= limits[0] and param <= limits[1]:
|
||||||
|
# Select sub-shape
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# Deselect sub-shape
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Update displayed info
|
||||||
|
self.update_subshapes_info()
|
||||||
|
|
||||||
|
|
||||||
|
def on_limit_changed(self):
|
||||||
|
"""
|
||||||
|
One of the limits was changed.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# TODO: Do we need an interactive change here?
|
||||||
|
# self.select_subshapes_in_limits()
|
||||||
|
|
||||||
|
|
||||||
def on_select_button_clicked(self):
|
def on_select_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
@ -140,9 +304,40 @@ class LocateSubShapesDlg(BaseDlg):
|
|||||||
None.
|
None.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#TODO: what are we going to do on this click?
|
# Doesn't make any sence without selected object
|
||||||
# Should it do a separated script?
|
if not self._selected_object:
|
||||||
QMessageBox.warning(None, 'Warning', 'Not implemented yet')
|
QMessageBox.warning(
|
||||||
|
None, 'Warning', 'You must select an object to see sub-shapes selected!')
|
||||||
|
return
|
||||||
|
|
||||||
|
self.select_subshapes_in_limits()
|
||||||
|
|
||||||
|
|
||||||
|
def on_minmax_button_clicked(self):
|
||||||
|
"""
|
||||||
|
Compute Min/Max limits on button click.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Doesn't make any sence without selected object
|
||||||
|
if not self._selected_object:
|
||||||
|
QMessageBox.warning(None, 'Warning', 'You must select an object to compute!')
|
||||||
|
return
|
||||||
|
|
||||||
|
# Execute a separated script the same way as it is expected for on_apply() but without dump
|
||||||
|
args = {
|
||||||
|
'result_name': 'dummy',
|
||||||
|
'selection_level': self.get_selection_level()
|
||||||
|
}
|
||||||
|
|
||||||
|
limits = execute(self._selected_object, self._minmax_algo, args, False)
|
||||||
|
if len(limits) >= 2:
|
||||||
|
self.set_limits(limits[0], limits[1])
|
||||||
|
|
||||||
|
|
||||||
def get_args(self):
|
def get_args(self):
|
||||||
@ -156,24 +351,45 @@ class LocateSubShapesDlg(BaseDlg):
|
|||||||
Dictionary with arguments for execution.
|
Dictionary with arguments for execution.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Update selection with a current values
|
||||||
|
# TODO: should we call it here?
|
||||||
|
# In a worst case scenario we can run it twice
|
||||||
|
# if a user has just pressed selection button.
|
||||||
|
self.select_subshapes_in_limits()
|
||||||
|
|
||||||
|
# Collect current values for the execution
|
||||||
selected_ids = self.get_local_selection()
|
selected_ids = self.get_local_selection()
|
||||||
current_index = self._type_widget.currentIndex()
|
selection_level = self.get_selection_level()
|
||||||
selection_level = self.get_measurment_type(current_index)
|
min_selected = 0
|
||||||
limits = self.get_limits()
|
|
||||||
min_selected = 1
|
|
||||||
|
|
||||||
if self.is_selection_valid(selected_ids, min_selected):
|
if self.is_selection_valid(selected_ids, min_selected):
|
||||||
return {
|
return {
|
||||||
'selected_ids': selected_ids,
|
'selected_ids': selected_ids,
|
||||||
'result_name': self.get_result_name(),
|
'result_name': self.get_result_name(),
|
||||||
'selection_level': selection_level,
|
'selection_level': selection_level
|
||||||
'min_limit': limits[0],
|
|
||||||
'max_limit': limits[1]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def on_select_object(self):
|
||||||
|
"""
|
||||||
|
Override parent's method to display sub-shapes info.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Call parent method first
|
||||||
|
super().on_select_object()
|
||||||
|
|
||||||
|
# Update displayed info
|
||||||
|
self.update_subshapes_info()
|
||||||
|
|
||||||
|
|
||||||
# For testing run as a module from geomrepairadv parent directory in
|
# For testing run as a module from geomrepairadv parent directory in
|
||||||
# Salome INSTALL, because the dialog needs a generated Ui_BaseDlg class
|
# Salome INSTALL, because the dialog needs a generated Ui_BaseDlg class
|
||||||
# that we don't have in the SOURCE.
|
# that we don't have in the SOURCE.
|
||||||
|
@ -55,9 +55,7 @@ def run(args_dict, progress_emitter):
|
|||||||
if ('source_solid' not in args_dict or
|
if ('source_solid' not in args_dict or
|
||||||
'selected_ids' not in args_dict or
|
'selected_ids' not in args_dict or
|
||||||
'result_name' not in args_dict or
|
'result_name' not in args_dict or
|
||||||
'selection_level' not in args_dict or
|
'selection_level' not in args_dict):
|
||||||
'min_limit' not in args_dict or
|
|
||||||
'max_limit' not in args_dict):
|
|
||||||
|
|
||||||
logging.info('Cant execute an algo because the arguments are empty!')
|
logging.info('Cant execute an algo because the arguments are empty!')
|
||||||
return False
|
return False
|
||||||
@ -66,8 +64,6 @@ def run(args_dict, progress_emitter):
|
|||||||
selected_ids = args_dict['selected_ids']
|
selected_ids = args_dict['selected_ids']
|
||||||
result_name = args_dict['result_name']
|
result_name = args_dict['result_name']
|
||||||
selection_level = args_dict['selection_level']
|
selection_level = args_dict['selection_level']
|
||||||
min_limit = args_dict['min_limit']
|
|
||||||
max_limit = args_dict['max_limit']
|
|
||||||
|
|
||||||
# Replace the lines below with an actual algorithm
|
# Replace the lines below with an actual algorithm
|
||||||
logging.info('Received arguments:')
|
logging.info('Received arguments:')
|
||||||
@ -75,21 +71,29 @@ def run(args_dict, progress_emitter):
|
|||||||
logging.info('\tselected_ids: %s', selected_ids)
|
logging.info('\tselected_ids: %s', selected_ids)
|
||||||
logging.info('\tresult_name: %s', result_name)
|
logging.info('\tresult_name: %s', result_name)
|
||||||
logging.info('\tselection_level: %s', selection_level)
|
logging.info('\tselection_level: %s', selection_level)
|
||||||
logging.info('\tmin_limit: %s', min_limit)
|
|
||||||
logging.info('\tmax_limit: %s', max_limit)
|
|
||||||
progress_emitter.emit()
|
|
||||||
|
|
||||||
sleep(1)
|
|
||||||
|
|
||||||
logging.warning('The algo script is not implemented! Return the copy of the source object...')
|
|
||||||
solid = geompy.MakeCopy(source_solid, result_name)
|
|
||||||
|
|
||||||
progress_emitter.emit()
|
progress_emitter.emit()
|
||||||
|
|
||||||
logging.info('Done.')
|
sleep(0.1)
|
||||||
|
|
||||||
|
# Make a group
|
||||||
|
group = geompy.CreateGroup(source_solid, selection_level, theName = result_name)
|
||||||
|
|
||||||
|
# Iterate all over the group's ids and remove unselected
|
||||||
|
group_ids = geompy.GetObjectIDs(group)
|
||||||
|
logging.info('Group Sub-shapes ids: %s', group_ids)
|
||||||
|
|
||||||
|
for subshape_id in group_ids:
|
||||||
|
if subshape_id not in selected_ids:
|
||||||
|
geompy.RemoveObject(group, subshape_id)
|
||||||
|
logging.info('\tSub-shape %s was removed!', subshape_id)
|
||||||
|
|
||||||
progress_emitter.emit()
|
progress_emitter.emit()
|
||||||
|
|
||||||
return solid
|
logging.info('Group of selected sub-shapes was created.')
|
||||||
|
progress_emitter.emit()
|
||||||
|
|
||||||
|
return group
|
||||||
|
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
@ -107,17 +111,17 @@ def test():
|
|||||||
source_solid = geompy.ImportBREP(test_file)
|
source_solid = geompy.ImportBREP(test_file)
|
||||||
geompy.addToStudy(source_solid, "source_solid")
|
geompy.addToStudy(source_solid, "source_solid")
|
||||||
|
|
||||||
|
selection_level = GEOM.EDGE
|
||||||
|
|
||||||
# TODO: Implement for actual algorithm
|
# TODO: Implement for actual algorithm
|
||||||
# Here we just use all ids.
|
# Here we just use all ids.
|
||||||
all_subshapes = geompy.SubShapeAllIDs(source_solid, GEOM.EDGE)
|
all_subshapes = geompy.SubShapeAllIDs(source_solid, selection_level)
|
||||||
|
|
||||||
args_dict = {
|
args_dict = {
|
||||||
'source_solid': source_solid,
|
'source_solid': source_solid,
|
||||||
'selected_ids': all_subshapes,
|
'selected_ids': all_subshapes,
|
||||||
'result_name': 'LocateSubshapes_result',
|
'result_name': 'LocateSubshapes_result',
|
||||||
'selection_level': GEOM.EDGE,
|
'selection_level': selection_level
|
||||||
'min_limit': 0.0,
|
|
||||||
'max_limit': 99.99
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Dummy emitter
|
# Dummy emitter
|
||||||
|
112
src/RepairGUIAdv/locate_subshapes_limits.py
Executable file
112
src/RepairGUIAdv/locate_subshapes_limits.py
Executable file
@ -0,0 +1,112 @@
|
|||||||
|
# -*- 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)
|
||||||
|
|
||||||
|
"""Example of algorithm script for GEOM Locate Subshapes plugin.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
import salome
|
||||||
|
|
||||||
|
from salome.geom import geomBuilder
|
||||||
|
from qtsalome import QFileDialog, QApplication, pyqtSignal
|
||||||
|
import GEOM
|
||||||
|
|
||||||
|
|
||||||
|
salome.salome_init()
|
||||||
|
geompy = geomBuilder.New()
|
||||||
|
|
||||||
|
|
||||||
|
def run(args_dict, progress_emitter):
|
||||||
|
"""
|
||||||
|
Helper function to call run() with arguments parsed from dictionary.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
args_dict - arguments as pairs string : any type value
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A result object.
|
||||||
|
"""
|
||||||
|
|
||||||
|
logging.info('Run Locate Subshapes algorithm.')
|
||||||
|
progress_emitter.emit()
|
||||||
|
|
||||||
|
|
||||||
|
if ('source_solid' not in args_dict or
|
||||||
|
'selection_level' not in args_dict):
|
||||||
|
|
||||||
|
logging.info('Cant execute an algo because the arguments are empty!')
|
||||||
|
return False
|
||||||
|
|
||||||
|
source_solid = args_dict['source_solid']
|
||||||
|
selection_level = args_dict['selection_level']
|
||||||
|
|
||||||
|
# Replace the lines below with an actual algorithm
|
||||||
|
logging.info('Received arguments:')
|
||||||
|
logging.info('\tsource_solid: %s', source_solid)
|
||||||
|
logging.info('\tselection_level: %s', selection_level)
|
||||||
|
progress_emitter.emit()
|
||||||
|
|
||||||
|
sleep(1)
|
||||||
|
|
||||||
|
logging.warning('The algo script is not implemented! Return default values...')
|
||||||
|
limits = [0.0, 100.0]
|
||||||
|
|
||||||
|
logging.info('Done.')
|
||||||
|
progress_emitter.emit()
|
||||||
|
|
||||||
|
return limits
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
"""
|
||||||
|
Tests execution of repair algo script.
|
||||||
|
"""
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
|
test_file, _ = QFileDialog.getOpenFileName(None, 'Open brep', '/home', 'Brep Files (*.brep)')
|
||||||
|
if not test_file:
|
||||||
|
return
|
||||||
|
|
||||||
|
# test_file = "PartitionCube.brep"
|
||||||
|
source_solid = geompy.ImportBREP(test_file)
|
||||||
|
geompy.addToStudy(source_solid, "source_solid")
|
||||||
|
|
||||||
|
args_dict = {
|
||||||
|
'source_solid': source_solid,
|
||||||
|
'selection_level': GEOM.EDGE
|
||||||
|
}
|
||||||
|
|
||||||
|
# Dummy emitter
|
||||||
|
# TODO: doesn't work
|
||||||
|
# progress_emitter = pyqtSignal()
|
||||||
|
progress_emitter = type('DummyEmitter', (object,), {'emit': lambda self: sleep(0.1)})()
|
||||||
|
|
||||||
|
run(args_dict, progress_emitter)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
test()
|
||||||
|
sys.exit(app.exec_())
|
Loading…
Reference in New Issue
Block a user