import sys
from pathlib import Path
-from traceback import format_exc
from qtsalome import Qt, QWidget, QMessageBox, QApplication, QGridLayout
from salome.gui import helper
from salome.kernel.studyedit import EDITOR
-from salome.kernel.services import IDToObject, ObjectToID
+from salome.kernel.services import IDToObject
from salome.geom import geomBuilder
-from salome.geom.geomtools import GeomStudyTools
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
# that we need to pass for execution instead of original one.
# TODO: decide if we really need to pass a copy.
self._selected_object = None
- self._selected_copy = None
# Put the common widgets and a child widget for a specific algorithm
# in a place right above standard buttons (defined by child_placeholder).
)
return
- # Make copy to prevent unintentional changing of a source object from the algo script
- builder = geomBuilder.New()
- self._selected_copy = builder.MakeCopy(
- self._selected_object, self.get_result_name() + '_temp')
-
args_dict = self.get_args()
if args_dict:
- # Add the copy object first
- args_dict['source_solid'] = self._selected_copy
-
- execute(self._algo_name, args_dict)
+ execute(self._selected_object, self._algo_name, args_dict)
# TODO: do we need to handle here a case if the algo failed?
- # Delete a copy object in any case
- copy_entry = ObjectToID(self._selected_copy)
- tools = GeomStudyTools()
- tools.deleteShape(copy_entry)
- self._selected_copy = None
-
def set_algoname(self, algo_name, is_default_location):
"""
import sys
import importlib.util
+from qtsalome import QApplication, QFileDialog
+
+from salome.kernel.services import ObjectToID
+from salome.geom.geomtools import GeomStudyTools
+
from .geomrepairadv_progress import RepairProgressDialog
from .geomrepairadv_logger import logger
-from qtsalome import Qt, QApplication, QFileDialog
-
# Testing
import salome
return module
-def execute(algo_name, args_dict):
+def execute(selected_object, algo_name, args_dict):
"""
Executes GEOM advanced repair algorithm.
Args:
+ selected_object - geom object selected by user for algorithm
algo_name - path to the algo module
args_dict - dictionary with arguments those are specific for each algo.
Returns:
- False if the algo failed.
+ Result GEOM object or None if failed or canceled.
"""
logger.debug('execute() start')
algo_module = module_from_filename(algo_name)
logger.debug('algo_module: %s', algo_module)
if not algo_module:
- return False
+ return None
+
+ # Keep the args for python dump
+ args_dict_str = str(args_dict)
+ logger.debug('args_dict_str: {}'.format(args_dict_str))
+
+ # Make copy to prevent unintentional changing of a source object from the algo script
+ geompy = geomBuilder.New()
+ selected_copy = geompy.MakeCopy(
+ selected_object, args_dict['result_name'] + '_temp')
+
+ # Add the copy object as a source
+ args_dict['source_solid'] = selected_copy
logger.debug('Create RepairProgressDialog...')
progress_dlg = RepairProgressDialog(parent=None, target=algo_module.run, args=args_dict)
- result = progress_dlg.exec()
- logger.info('result: %s', result)
+ progress_dlg.exec()
+
+ # Delete a copy object in any case
+ copy_entry = ObjectToID(selected_copy)
+ tools = GeomStudyTools()
+ tools.deleteShape(copy_entry)
+
+ # Python dump if execution was completed without errors
+ if progress_dlg.is_completed():
+ result_object = progress_dlg.get_result()
+
+ # Completed execution doesn't guarantee that we received a valid object
+ if not result_object:
+ logger.error('Could not get a result object after exec of %s file!', str(algo_name))
+ return None
+
+ geompy.FuncToPythonDump(
+ selected_object,
+ result_object,
+ 'from salome.geom.geomrepairadv import geomrepairadv_execute\n',
+ 'geomrepairadv_execute.execute',
+ '\'' + str(algo_name) + '\', ' + args_dict_str
+ )
+
+ return result_object
+
+ return None
def test_execution():
# Récupération des faces à fusionner
face_a = geompy.GetFaceNearPoint(source_solid, geompy.MakeVertex(-143, -127, 250))
face_b = geompy.GetFaceNearPoint(source_solid, geompy.MakeVertex(49,-127,250))
+ faces_ids = geompy.GetSubShapesIDs(source_solid, [face_a, face_b])
geompy.addToStudy(source_solid, "source_solid")
geompy.addToStudyInFather(source_solid, face_a, "face_a")
args_dict = {
'source_solid': source_solid,
- 'face_a': face_a,
- 'face_b': face_b,
+ 'faces_ids': faces_ids,
'result_name': 'MergeFaces_result'
}
if not algo_filename:
return
- execute(algo_filename, args_dict)
+ execute(source_solid, algo_filename, args_dict)
if __name__ == '__main__':
# Helper flag to decide if we need to change button or close the dialog
self.canceled = False
+ # Helper flag to check if execution was completed without errors
+ self.completed = False
+
# Set logger to redirect logs output into the text widget
self.log_handler = QTextEditLogger(self)
logging.getLogger().addHandler(self.log_handler)
self.progress.setLabelText('Completed!')
self.progress.setCancelButtonText('Close')
+ # Set the Close button to actually close dialog
self.canceled = True
+ # Lets us know that we get the job done
+ self.completed = True
+
def value(self):
"""
super().close()
+ def is_completed(self):
+ """
+ Returns True if execution was completed without errors and wasn't canceled.
+ """
+
+ return self.completed
+
+
+ def get_result(self):
+ """
+ Returns result of the execution or None if the execution failed.
+ """
+
+ return self.thread.get_result()
+
+
def test_thread():
"""
Tests running a test function in a thread while
"""
progress_dlg = RepairProgressDialog(parent=None, target=test, args=None)
- result = progress_dlg.exec()
- logging.info('result: %s', result)
+ progress_dlg.exec()
+
+ if progress_dlg.is_completed():
+ logging.info('result: %s', progress_dlg.get_result())
+ else:
+ logging.info('Cannot get results because execution was not completed.')
def test(args, progress_emitter):
logging.debug('debug msg')
sleep(2)
+ # raise Exception
progress_emitter.emit()
logging.info('info msg')
progress_emitter.emit()
+ return "Result from test!"
+
if __name__ == '__main__':
app = QApplication(sys.argv)
#
# Author : Konstantin Leontev (OpenCascade S.A.S)
-import logging
import inspect
from traceback import format_exc
# Set a progress emitter to update the progress from the target
self.progress_emitter = ProgressEmitter(self.progress_update, total_lines, first_line)
+ # Set a variable for result
+ self.result = None
+
def run(self):
"""
# Wait mode cursor
QApplication.setOverrideCursor(Qt.WaitCursor)
- self.target(self.args, self.progress_emitter)
+ self.result = self.target(self.args, self.progress_emitter)
# Reset the progress when finished
self.progress_update.emit(100)
QApplication.restoreOverrideCursor()
+ def get_result(self):
+ """
+ Returns result of the execution or None if the execution failed.
+ """
+
+ return self.result
+
+
class ProgressEmitter():
"""
Helper class to reduce code repetition while update progress
from qtsalome import QGridLayout, QFrame, QMessageBox, QApplication
from libGEOM_Swig import GEOM_Swig
-from salome.geom import geomBuilder
from .geomrepairadv_logger import logger
from .basedlg import BaseDlg
from .geomrepairadv_common import DlgRef_1Spin_QTD
)
return None
- # Get faces from a temporary copy object
- builder = geomBuilder.New()
- faces = builder.SubShapes(self._selected_copy, faces_ids)
- logger.debug('faces: %s', faces)
-
return {
- 'face_a': faces[0],
- 'face_b': faces[1],
+ 'faces_ids': faces_ids,
'result_name': self.get_result_name(),
'precision': self.get_precision()
}
args_dict - arguments as pairs string : any type value
Returns:
- A string with result description.
+ A result object.
"""
logging.info('Run Merge Faces algorithm.')
if ('source_solid' not in args_dict or
- 'face_a' not in args_dict or
- 'face_b' not in args_dict or
+ 'faces_ids' not in args_dict or
'result_name' not in args_dict):
logging.info('Cant execute an algo because the arguments are empty!')
return False
source_solid = args_dict['source_solid']
- face_a = args_dict['face_a']
- face_b = args_dict['face_b']
+ faces_ids = args_dict['faces_ids']
result_name = args_dict['result_name']
logging.info('Creating of two faces...')
progress_emitter.emit()
- # Fusion des deux faces
- partition = geompy.MakePartition([face_a, face_b],[])
- points = [geompy.GetVertexNearPoint(partition, geompy.MakeVertex(-298, 29, 250)),
- geompy.GetVertexNearPoint(partition, geompy.MakeVertex(178, 29, 250)),
- geompy.GetVertexNearPoint(partition, geompy.MakeVertex(178, -282, 250)),
- geompy.GetVertexNearPoint(partition, geompy.MakeVertex(-298, -282, 250))]
- wire = geompy.MakePolyline(points,True)
- fused_face = geompy.MakeFaceWires([wire], True)
- geompy.addToStudy(fused_face, "fused_face")
+ # This block creates a face using passed selected faces.
+ # Commented to simplify output - just one object.
+
+ # # Fusion des deux faces
+ # faces = geompy.SubShapes(source_solid, faces_ids)
+ # logging.info('faces: %s', faces)
+ # partition = geompy.MakePartition([faces[0], faces[1]],[])
+ # points = [geompy.GetVertexNearPoint(partition, geompy.MakeVertex(-298, 29, 250)),
+ # geompy.GetVertexNearPoint(partition, geompy.MakeVertex(178, 29, 250)),
+ # geompy.GetVertexNearPoint(partition, geompy.MakeVertex(178, -282, 250)),
+ # geompy.GetVertexNearPoint(partition, geompy.MakeVertex(-298, -282, 250))]
+ # wire = geompy.MakePolyline(points,True)
+ # fused_face = geompy.MakeFaceWires([wire], True)
+ # geompy.addToStudy(fused_face, "fused_face")
logging.info('Creating of a new geometry from the source brep...')
progress_emitter.emit()
- sleep(5)
+ sleep(1)
# Fusion des deux faces au sein de la boite + nettoyage de la boite
points = [geompy.GetVertexNearPoint(source_solid, geompy.MakeVertex(-298, 29, 250)),
logging.info('Cleaning of the new geometry...')
progress_emitter.emit()
- sleep(5)
+ sleep(1)
# Uncomment to simulate exception handling in a thread worker class
# raise Exception
logging.info('Creating a solid...')
progress_emitter.emit()
- sleep(5)
+ sleep(1)
# ### Création du solide
shell = geompy.MakeShell(faces)
logging.info('Merge Faces algorithm was completed successfully.')
progress_emitter.emit()
- return True
+ return solid
def test():