From 465e84c52edb243fa36d581abc659b1c97156c64 Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 12 Feb 2013 11:35:16 +0000 Subject: [PATCH] Merge from V6_main 11/02/2013 --- build_configure | 1 - configure.ac | 3 + doc/salome/Makefile.am | 5 +- doc/salome/examples/3dsketcher.py | 43 + doc/salome/examples/Makefile.am | 141 + .../examples/advanced_geom_objs_ex01.py | 73 + .../examples/advanced_geom_objs_ex02.py | 15 + .../examples/advanced_geom_objs_ex03.py | 15 + doc/salome/examples/angle.py | 60 + doc/salome/examples/basic_geom_objs_ex01.py | 61 + doc/salome/examples/basic_geom_objs_ex02.py | 31 + doc/salome/examples/basic_geom_objs_ex03.py | 30 + doc/salome/examples/basic_geom_objs_ex04.py | 34 + doc/salome/examples/basic_geom_objs_ex05.py | 29 + doc/salome/examples/basic_geom_objs_ex06.py | 68 + doc/salome/examples/basic_geom_objs_ex07.py | 27 + doc/salome/examples/basic_geom_objs_ex08.py | 75 + doc/salome/examples/basic_geom_objs_ex09.py | 38 + doc/salome/examples/basic_operations_ex01.py | 41 + doc/salome/examples/basic_operations_ex02.py | 28 + doc/salome/examples/basic_operations_ex03.py | 55 + doc/salome/examples/basic_properties.py | 20 + doc/salome/examples/blocks_operations_ex01.py | 35 + doc/salome/examples/blocks_operations_ex02.py | 26 + doc/salome/examples/blocks_operations_ex03.py | 20 + .../examples/boolean_operations_ex01.py | 38 + .../examples/boolean_operations_ex02.py | 28 + .../examples/boolean_operations_ex03.py | 28 + .../examples/boolean_operations_ex04.py | 28 + doc/salome/examples/bounding_box.py | 17 + .../examples/building_by_blocks_ex01.py | 55 + .../examples/building_by_blocks_ex02.py | 54 + doc/salome/examples/center_of_mass.py | 19 + .../examples/check_compound_of_blocks.py | 21 + .../examples/check_self_intersections.py | 11 + doc/salome/examples/check_shape.py | 11 + doc/salome/examples/complex_objs_ex01.py | 61 + doc/salome/examples/complex_objs_ex02.py | 34 + doc/salome/examples/complex_objs_ex03.py | 39 + doc/salome/examples/complex_objs_ex04.py | 38 + doc/salome/examples/complex_objs_ex05.py | 32 + doc/salome/examples/complex_objs_ex06.py | 192 + doc/salome/examples/complex_objs_ex07.py | 116 + doc/salome/examples/complex_objs_ex08.py | 76 + doc/salome/examples/complex_objs_ex09.py | 43 + doc/salome/examples/complex_objs_ex10.py | 24 + doc/salome/examples/free_boundaries.py | 79 + doc/salome/examples/free_faces.py | 46 + doc/salome/examples/get_non_blocks.py | 26 + doc/salome/examples/import_export.py | 40 + doc/salome/examples/inertia.py | 14 + doc/salome/examples/min_distance.py | 49 + doc/salome/examples/normal_face.py | 17 + doc/salome/examples/notebook_geom.py | 21 + doc/salome/examples/point_coordinates.py | 21 + doc/salome/examples/primitives_ex01.py | 27 + doc/salome/examples/primitives_ex02.py | 30 + doc/salome/examples/primitives_ex03.py | 29 + doc/salome/examples/primitives_ex04.py | 24 + doc/salome/examples/primitives_ex05.py | 24 + doc/salome/examples/primitives_ex06.py | 35 + doc/salome/examples/primitives_ex07.py | 31 + .../examples/repairing_operations_ex01.py | 46 + .../examples/repairing_operations_ex02.py | 28 + .../examples/repairing_operations_ex03.py | 30 + .../examples/repairing_operations_ex04.py | 34 + .../examples/repairing_operations_ex05.py | 50 + .../examples/repairing_operations_ex06.py | 39 + .../examples/repairing_operations_ex07.py | 32 + .../examples/repairing_operations_ex08.py | 30 + .../examples/repairing_operations_ex09.py | 33 + .../examples/repairing_operations_ex10.py | 27 + .../examples/repairing_operations_ex11.py | 49 + doc/salome/examples/sketcher.py | 42 + doc/salome/examples/testme.py | 28 + doc/salome/examples/tolerance.py | 14 + .../examples/topological_geom_objs_ex01.py | 57 + .../examples/topological_geom_objs_ex02.py | 25 + .../examples/topological_geom_objs_ex03.py | 51 + .../examples/topological_geom_objs_ex04.py | 34 + .../examples/topological_geom_objs_ex05.py | 36 + .../examples/topological_geom_objs_ex06.py | 28 + .../transformation_operations_ex01.py | 43 + .../transformation_operations_ex02.py | 44 + .../transformation_operations_ex03.py | 43 + .../transformation_operations_ex04.py | 46 + .../transformation_operations_ex05.py | 24 + .../transformation_operations_ex06.py | 20 + .../transformation_operations_ex07.py | 31 + .../transformation_operations_ex08.py | 48 + .../transformation_operations_ex09.py | 64 + .../transformation_operations_ex10.py | 17 + .../transformation_operations_ex11.py | 19 + .../transformation_operations_ex12.py | 53 + .../transformation_operations_ex13.py | 63 + doc/salome/examples/viewing_geom_objs_ex01.py | 17 + doc/salome/examples/viewing_geom_objs_ex02.py | 14 + doc/salome/examples/viewing_geom_objs_ex03.py | 16 + doc/salome/examples/viewing_geom_objs_ex04.py | 14 + doc/salome/examples/whatis.py | 9 + .../examples/working_with_groups_ex01.py | 37 + .../examples/working_with_groups_ex02.py | 26 + .../examples/working_with_groups_ex03.py | 33 + .../examples/working_with_groups_ex04.py | 29 + .../examples/working_with_groups_ex05.py | 29 + .../examples/working_with_groups_ex06.py | 29 + doc/salome/gui/GEOM/doxyfile.in | 2 +- doc/salome/gui/GEOM/images/curve4.png | Bin 26765 -> 31671 bytes doc/salome/gui/GEOM/images/distance.png | Bin 16262 -> 21548 bytes doc/salome/gui/GEOM/images/editgroup.png | Bin 33549 -> 43571 bytes .../gui/GEOM/images/hide_predef_material.PNG | Bin 0 -> 22756 bytes doc/salome/gui/GEOM/images/material.png | Bin 33790 -> 36593 bytes .../gui/GEOM/images/materials_library.png | Bin 0 -> 31359 bytes doc/salome/gui/GEOM/images/measures5.png | Bin 14644 -> 20073 bytes doc/salome/gui/GEOM/images/mtrans1.png | Bin 15614 -> 27480 bytes doc/salome/gui/GEOM/images/mtrans2.png | Bin 19232 -> 33003 bytes doc/salome/gui/GEOM/images/neo-mrot1.png | Bin 14322 -> 26689 bytes doc/salome/gui/GEOM/images/neo-mrot2.png | Bin 17422 -> 30397 bytes doc/salome/gui/GEOM/images/pref15.png | Bin 46204 -> 75408 bytes doc/salome/gui/GEOM/images/repair9.png | Bin 9949 -> 15492 bytes .../gui/GEOM/images/show_predef_material.PNG | Bin 0 -> 26551 bytes doc/salome/gui/GEOM/input/boudaries.doc | 6 +- doc/salome/gui/GEOM/input/bounding_box.doc | 14 +- doc/salome/gui/GEOM/input/creating_curve.doc | 7 +- .../gui/GEOM/input/geometry_preferences.doc | 6 +- doc/salome/gui/GEOM/input/geompy.doc | 1 + doc/salome/gui/GEOM/input/material.doc | 61 +- doc/salome/gui/GEOM/input/min_distance.doc | 27 +- .../GEOM/input/multi_rotation_operation.doc | 58 +- .../input/multi_translation_operation.doc | 44 +- doc/salome/gui/GEOM/input/tui_3dsketcher.doc | 46 +- .../gui/GEOM/input/tui_advanced_geom_objs.doc | 113 +- doc/salome/gui/GEOM/input/tui_angle.doc | 64 +- .../gui/GEOM/input/tui_basic_geom_objs.doc | 412 +- .../gui/GEOM/input/tui_basic_operations.doc | 133 +- .../gui/GEOM/input/tui_basic_properties.doc | 23 +- .../gui/GEOM/input/tui_blocks_operations.doc | 92 +- .../gui/GEOM/input/tui_boolean_operations.doc | 134 +- .../gui/GEOM/input/tui_bounding_box.doc | 14 +- .../gui/GEOM/input/tui_building_by_blocks.doc | 117 +- .../gui/GEOM/input/tui_center_of_mass.doc | 22 +- .../input/tui_check_compound_of_blocks.doc | 24 +- .../input/tui_check_self_intersections.doc | 14 +- doc/salome/gui/GEOM/input/tui_check_shape.doc | 14 +- .../gui/GEOM/input/tui_complex_objs.doc | 686 +--- .../gui/GEOM/input/tui_free_boundaries.doc | 82 +- doc/salome/gui/GEOM/input/tui_free_faces.doc | 49 +- .../gui/GEOM/input/tui_get_non_blocks.doc | 29 +- .../gui/GEOM/input/tui_import_export.doc | 42 +- doc/salome/gui/GEOM/input/tui_inertia.doc | 17 +- .../gui/GEOM/input/tui_min_distance.doc | 12 +- doc/salome/gui/GEOM/input/tui_normal_face.doc | 20 +- .../gui/GEOM/input/tui_notebook_geom.doc | 24 +- .../gui/GEOM/input/tui_point_coordinates.doc | 26 +- doc/salome/gui/GEOM/input/tui_primitives.doc | 221 +- .../GEOM/input/tui_repairing_operations.doc | 431 +-- doc/salome/gui/GEOM/input/tui_sketcher.doc | 45 +- doc/salome/gui/GEOM/input/tui_tolerance.doc | 17 +- .../GEOM/input/tui_topological_geom_objs.doc | 250 +- .../input/tui_transformation_operations.doc | 537 +-- .../gui/GEOM/input/tui_viewing_geom_objs.doc | 72 +- doc/salome/gui/GEOM/input/tui_whatis.doc | 12 +- .../GEOM/input/tui_working_with_groups.doc | 203 +- .../gui/GEOM/input/working_with_groups.doc | 11 +- doc/salome/gui/Makefile.am | 3 +- idl/GEOM_Gen.idl | 140 +- resources/SalomeApp.xml.in | 4 + src/ARCHIMEDE/Archimede_VolumeSection.cxx | 1 - src/ARCHIMEDE/Archimede_VolumeSection.hxx | 1 - src/ARCHIMEDE/Makefile.am | 1 - src/BREPExport/BREPExport.cxx | 5 +- src/BREPExport/Makefile.am | 1 - src/BREPImport/Makefile.am | 1 - src/BasicGUI/BasicGUI_CircleDlg.cxx | 3 +- src/BasicGUI/BasicGUI_CurveDlg.cxx | 485 ++- src/BasicGUI/BasicGUI_CurveDlg.h | 32 +- src/{GEOMAlgo => BlockFix}/BlockFix.cxx | 0 src/{GEOMAlgo => BlockFix}/BlockFix.hxx | 27 +- .../BlockFix_BlockFixAPI.cxx | 15 +- .../BlockFix_BlockFixAPI.hxx} | 43 +- .../BlockFix_CheckTool.cxx | 21 +- .../BlockFix_CheckTool.hxx} | 41 +- .../BlockFix_PeriodicSurfaceModifier.cxx | 51 +- .../BlockFix_PeriodicSurfaceModifier.hxx | 95 + .../BlockFix_SphereSpaceModifier.cxx | 57 +- src/BlockFix/BlockFix_SphereSpaceModifier.hxx | 82 + .../BlockFix_UnionEdges.cxx | 5 +- .../BlockFix_UnionEdges.hxx} | 32 +- .../BlockFix_UnionFaces.cxx | 23 +- .../BlockFix_UnionFaces.hxx | 41 +- src/BlockFix/Makefile.am | 55 + src/BlocksGUI/BlocksGUI_ExplodeDlg.cxx | 2 +- src/BlocksGUI/BlocksGUI_ExplodeDlg.h | 2 +- src/DisplayGUI/DisplayGUI.cxx | 8 +- src/DlgRef/DlgRef.cxx | 57 - src/DlgRef/DlgRef.h | 65 - src/DlgRef/DlgRef_1Sel4Spin2Check_QTD.ui | 211 - src/DlgRef/DlgRef_1Sel4Spin_QTD.ui | 214 -- src/DlgRef/DlgRef_1Sel5Spin_QTD.ui | 232 -- src/DlgRef/DlgRef_2Sel4Spin1Check_QTD.ui | 237 -- src/DlgRef/Makefile.am | 6 - src/EntityGUI/EntityGUI_SubShapeDlg.cxx | 2 +- src/EntityGUI/EntityGUI_SubShapeDlg.h | 2 +- src/GEOM/Makefile.am | 1 - src/GEOMAlgo/BlockFix.cdl | 67 - src/GEOMAlgo/BlockFix.ixx | 27 - src/GEOMAlgo/BlockFix.jxx | 28 - src/GEOMAlgo/BlockFix_BlockFixAPI.cdl | 68 - src/GEOMAlgo/BlockFix_BlockFixAPI.hxx | 94 - src/GEOMAlgo/BlockFix_BlockFixAPI.ixx | 77 - src/GEOMAlgo/BlockFix_BlockFixAPI.jxx | 31 - src/GEOMAlgo/BlockFix_CheckTool.cdl | 67 - src/GEOMAlgo/BlockFix_CheckTool.hxx | 120 - src/GEOMAlgo/BlockFix_CheckTool.ixx | 27 - .../BlockFix_PeriodicSurfaceModifier.cdl | 135 - .../BlockFix_PeriodicSurfaceModifier.hxx | 140 - .../BlockFix_PeriodicSurfaceModifier.ixx | 79 - .../BlockFix_PeriodicSurfaceModifier.jxx | 49 - src/GEOMAlgo/BlockFix_SphereSpaceModifier.cdl | 139 - src/GEOMAlgo/BlockFix_SphereSpaceModifier.hxx | 141 - src/GEOMAlgo/BlockFix_SphereSpaceModifier.ixx | 79 - src/GEOMAlgo/BlockFix_SphereSpaceModifier.jxx | 49 - src/GEOMAlgo/BlockFix_UnionEdges.cdl | 49 - src/GEOMAlgo/BlockFix_UnionEdges.hxx | 100 - src/GEOMAlgo/BlockFix_UnionEdges.ixx | 27 - src/GEOMAlgo/BlockFix_UnionFaces.cdl | 65 - src/GEOMAlgo/BlockFix_UnionFaces.ixx | 27 - src/GEOMAlgo/BlockFix_UnionFaces.jxx | 31 - src/GEOMAlgo/FILES | 27 - src/GEOMAlgo/Handle_BlockFix_BlockFixAPI.hxx | 92 - ...andle_BlockFix_PeriodicSurfaceModifier.hxx | 92 - .../Handle_BlockFix_SphereSpaceModifier.hxx | 92 - src/GEOMAlgo/Makefile.am | 43 +- src/GEOMBase/GEOMBase.cxx | 2 +- src/GEOMBase/GEOMBase_Helper.cxx | 164 +- src/GEOMBase/GEOMBase_Helper.h | 48 +- src/GEOMBase/GEOMBase_Skeleton.cxx | 5 +- src/GEOMBase/GEOMBase_Skeleton.h | 5 +- src/GEOMBase/GEOM_GenericObjPtr.h | 6 +- src/GEOMClient/Makefile.am | 1 - src/GEOMGUI/GEOMGUI.cxx | 9 + src/GEOMGUI/GEOMGUI.h | 1 + src/GEOMGUI/GEOMGUI_Selection.cxx | 340 +- src/GEOMGUI/GEOM_Displayer.cxx | 1400 ++++--- src/GEOMGUI/GEOM_Displayer.h | 18 +- src/GEOMGUI/GEOM_images.ts | 4 + src/GEOMGUI/GEOM_msg_en.ts | 100 +- src/GEOMGUI/GEOM_msg_fr.ts | 76 +- src/GEOMGUI/GeometryGUI.cxx | 333 +- src/GEOMGUI/GeometryGUI.h | 4 +- src/GEOMGUI/GeometryGUI_Operations.h | 3 + src/GEOMImpl/GEOMImpl_CircleDriver.cxx | 51 +- src/GEOMImpl/GEOMImpl_FaceDriver.cxx | 9 +- src/GEOMImpl/GEOMImpl_Fillet1dDriver.cxx | 6 +- src/GEOMImpl/GEOMImpl_IBlocksOperations.cxx | 7 +- src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx | 118 +- src/GEOMImpl/GEOMImpl_ICurvesOperations.hxx | 15 +- src/GEOMImpl/GEOMImpl_IInsertOperations.cxx | 4 +- src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx | 262 +- src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx | 10 +- src/GEOMImpl/GEOMImpl_IPipeDiffSect.hxx | 5 +- src/GEOMImpl/GEOMImpl_IPipePath.hxx | 2 + src/GEOMImpl/GEOMImpl_IPipeShellSect.hxx | 5 +- src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 421 +- src/GEOMImpl/GEOMImpl_IShapesOperations.hxx | 52 +- src/GEOMImpl/GEOMImpl_ISpline.hxx | 73 +- .../GEOMImpl_ITransformOperations.cxx | 212 +- .../GEOMImpl_ITransformOperations.hxx | 12 +- src/GEOMImpl/GEOMImpl_MarkerDriver.cxx | 7 +- src/GEOMImpl/GEOMImpl_MeasureDriver.cxx | 52 +- src/GEOMImpl/GEOMImpl_PipeDriver.cxx | 18 +- src/GEOMImpl/GEOMImpl_PipeTShapeDriver.cxx | 18 +- src/GEOMImpl/GEOMImpl_PlaneDriver.cxx | 7 +- src/GEOMImpl/GEOMImpl_PointDriver.cxx | 78 +- src/GEOMImpl/GEOMImpl_PositionDriver.cxx | 13 +- src/GEOMImpl/GEOMImpl_PrismDriver.cxx | 11 +- src/GEOMImpl/GEOMImpl_RevolutionDriver.cxx | 7 +- src/GEOMImpl/GEOMImpl_RotateDriver.cxx | 90 +- src/GEOMImpl/GEOMImpl_SketcherDriver.cxx | 5 +- src/GEOMImpl/GEOMImpl_SplineDriver.cxx | 125 +- src/GEOMImpl/GEOMImpl_TranslateDriver.cxx | 52 +- src/GEOMImpl/GEOMImpl_Types.hxx | 7 +- src/GEOMImpl/Makefile.am | 4 + src/GEOMToolsGUI/GEOMToolsGUI.cxx | 27 +- src/GEOMToolsGUI/GEOMToolsGUI.h | 4 + src/GEOMToolsGUI/GEOMToolsGUI_1.cxx | 114 +- .../GEOMToolsGUI_DeflectionDlg.cxx | 2 +- src/GEOMToolsGUI/GEOMToolsGUI_MarkerDlg.cxx | 6 +- .../GEOMToolsGUI_MaterialPropertiesDlg.cxx | 224 +- .../GEOMToolsGUI_MaterialPropertiesDlg.h | 15 +- .../GEOMToolsGUI_TransparencyDlg.cxx | 4 +- src/GEOMUtils/GEOMUtils.cxx | 499 +++ src/GEOMUtils/GEOMUtils.hxx | 108 + src/GEOMUtils/Makefile.am | 57 + src/GEOM_I/GEOM_Gen_i.cc | 27 +- src/GEOM_I/GEOM_ICurvesOperations_i.cc | 40 + src/GEOM_I/GEOM_ICurvesOperations_i.hh | 4 + src/GEOM_I/GEOM_IMeasureOperations_i.cc | 61 +- src/GEOM_I/GEOM_IMeasureOperations_i.hh | 7 +- src/GEOM_I/GEOM_IShapesOperations_i.cc | 43 + src/GEOM_I/GEOM_IShapesOperations_i.hh | 3 + src/GEOM_I/GEOM_ITransformOperations_i.cc | 110 +- src/GEOM_I/GEOM_ITransformOperations_i.hh | 133 +- src/GEOM_I/GEOM_Object_i.cc | 2 +- src/GEOM_I/GEOM_wrap.hxx | 59 + src/GEOM_I/Makefile.am | 4 +- src/GEOM_I_Superv/Makefile.am | 1 - src/GEOM_SWIG/GEOM_ObjectInfo.py | 1 - src/GEOM_SWIG/GEOM_Sketcher.py | 1 - src/GEOM_SWIG/GEOM_TestAll.py | 17 +- src/GEOM_SWIG/GEOM_TestMeasures.py | 13 +- src/GEOM_SWIG/GEOM_TestOthers.py | 14 +- src/GEOM_SWIG/GEOM_blocks.py | 1 - src/GEOM_SWIG/GEOM_example.py | 1 - src/GEOM_SWIG/GEOM_example2.py | 1 - src/GEOM_SWIG/GEOM_example3.py | 1 - src/GEOM_SWIG/GEOM_example5.py | 1 - src/GEOM_SWIG/GEOM_example6.py | 1 - src/GEOM_SWIG/GEOM_moteur.py | 1 - src/GEOM_SWIG/GEOM_usinggeom.py | 1 - src/GEOM_SWIG/batchmode_geompy.py | 5 +- src/GEOM_SWIG/geompy.py | 1 - src/GEOM_SWIG/geompyDC.py | 3388 +++++++++++++++-- src/GEOM_SWIG/gsketcher.py | 12 +- src/GEOM_SWIG_WITHIHM/Makefile.am | 2 + src/GEOM_SWIG_WITHIHM/libGEOM_Swig.cxx | 949 ++--- src/GEOM_SWIG_WITHIHM/libGEOM_Swig.h | 46 +- src/GEOM_SWIG_WITHIHM/libGEOM_Swig.i | 29 +- src/GroupGUI/GroupGUI_GroupDlg.cxx | 116 +- src/GroupGUI/GroupGUI_GroupDlg.h | 2 + src/IGESExport/Makefile.am | 1 - src/IGESImport/Makefile.am | 1 - src/Makefile.am | 27 +- src/Material/Makefile.am | 6 + src/Material/Material_Model.cxx | 206 +- src/Material/Material_Model.h | 25 +- src/Material/Material_ResourceMgr.cxx | 79 +- src/Material/Material_ResourceMgr.h | 28 +- src/Material/resources/SalomeMaterial.xml | 389 +- src/MeasureGUI/Makefile.am | 2 - .../MeasureGUI_2Sel4LineEdit_QTD.ui | 189 - src/MeasureGUI/MeasureGUI_BndBoxDlg.cxx | 185 +- src/MeasureGUI/MeasureGUI_BndBoxDlg.h | 36 +- src/MeasureGUI/MeasureGUI_DistanceDlg.cxx | 442 ++- src/MeasureGUI/MeasureGUI_DistanceDlg.h | 100 +- src/MeasureGUI/MeasureGUI_Widgets.cxx | 17 +- src/MeasureGUI/MeasureGUI_Widgets.h | 19 +- src/OBJECT/GEOM_AISShape.cxx | 38 +- src/OBJECT/GEOM_AISShape.hxx | 2 - src/OBJECT/GEOM_AISVector.cxx | 1 - src/OBJECT/GEOM_Actor.cxx | 231 +- src/OBJECT/GEOM_Actor.h | 38 +- src/OBJECT/GEOM_Constants.cxx | 102 + src/OBJECT/GEOM_Constants.h | 64 +- src/OBJECT/GEOM_DeviceActor.cxx | 14 + src/OBJECT/GEOM_DeviceActor.h | 5 +- src/OBJECT/GEOM_InteractiveObject.cxx | 1 - src/OBJECT/GEOM_OCCReader.h | 1 - src/OBJECT/GEOM_TopWireframeShape.cxx | 4 + src/OBJECT/GEOM_TopWireframeShape.ixx | 2 - src/OBJECT/GEOM_VTKTrihedron.cxx | 8 +- src/OBJECT/GEOM_VTKTrihedron.hxx | 1 - src/OBJECT/Makefile.am | 3 +- src/RepairGUI/RepairGUI_FreeBoundDlg.cxx | 332 +- src/RepairGUI/RepairGUI_FreeBoundDlg.h | 41 +- src/SKETCHER/Makefile.am | 1 - src/SKETCHER/Sketcher_Profile.hxx | 1 - src/STEPExport/Makefile.am | 1 - src/STEPExport/STEPExport.cxx | 5 +- src/STLExport/Makefile.am | 2 - src/ShHealOper/Makefile.am | 1 - .../TransformationGUI_MultiRotationDlg.cxx | 402 +- .../TransformationGUI_MultiRotationDlg.h | 68 +- .../TransformationGUI_MultiTranslationDlg.cxx | 85 +- src/VTKExport/Makefile.am | 2 - 375 files changed, 14413 insertions(+), 11763 deletions(-) create mode 100644 doc/salome/examples/3dsketcher.py create mode 100644 doc/salome/examples/Makefile.am create mode 100644 doc/salome/examples/advanced_geom_objs_ex01.py create mode 100644 doc/salome/examples/advanced_geom_objs_ex02.py create mode 100644 doc/salome/examples/advanced_geom_objs_ex03.py create mode 100644 doc/salome/examples/angle.py create mode 100644 doc/salome/examples/basic_geom_objs_ex01.py create mode 100644 doc/salome/examples/basic_geom_objs_ex02.py create mode 100644 doc/salome/examples/basic_geom_objs_ex03.py create mode 100644 doc/salome/examples/basic_geom_objs_ex04.py create mode 100644 doc/salome/examples/basic_geom_objs_ex05.py create mode 100644 doc/salome/examples/basic_geom_objs_ex06.py create mode 100644 doc/salome/examples/basic_geom_objs_ex07.py create mode 100644 doc/salome/examples/basic_geom_objs_ex08.py create mode 100644 doc/salome/examples/basic_geom_objs_ex09.py create mode 100644 doc/salome/examples/basic_operations_ex01.py create mode 100644 doc/salome/examples/basic_operations_ex02.py create mode 100644 doc/salome/examples/basic_operations_ex03.py create mode 100644 doc/salome/examples/basic_properties.py create mode 100644 doc/salome/examples/blocks_operations_ex01.py create mode 100644 doc/salome/examples/blocks_operations_ex02.py create mode 100644 doc/salome/examples/blocks_operations_ex03.py create mode 100644 doc/salome/examples/boolean_operations_ex01.py create mode 100644 doc/salome/examples/boolean_operations_ex02.py create mode 100644 doc/salome/examples/boolean_operations_ex03.py create mode 100644 doc/salome/examples/boolean_operations_ex04.py create mode 100644 doc/salome/examples/bounding_box.py create mode 100644 doc/salome/examples/building_by_blocks_ex01.py create mode 100644 doc/salome/examples/building_by_blocks_ex02.py create mode 100644 doc/salome/examples/center_of_mass.py create mode 100644 doc/salome/examples/check_compound_of_blocks.py create mode 100644 doc/salome/examples/check_self_intersections.py create mode 100644 doc/salome/examples/check_shape.py create mode 100644 doc/salome/examples/complex_objs_ex01.py create mode 100644 doc/salome/examples/complex_objs_ex02.py create mode 100644 doc/salome/examples/complex_objs_ex03.py create mode 100644 doc/salome/examples/complex_objs_ex04.py create mode 100644 doc/salome/examples/complex_objs_ex05.py create mode 100644 doc/salome/examples/complex_objs_ex06.py create mode 100644 doc/salome/examples/complex_objs_ex07.py create mode 100644 doc/salome/examples/complex_objs_ex08.py create mode 100644 doc/salome/examples/complex_objs_ex09.py create mode 100644 doc/salome/examples/complex_objs_ex10.py create mode 100644 doc/salome/examples/free_boundaries.py create mode 100644 doc/salome/examples/free_faces.py create mode 100644 doc/salome/examples/get_non_blocks.py create mode 100644 doc/salome/examples/import_export.py create mode 100644 doc/salome/examples/inertia.py create mode 100644 doc/salome/examples/min_distance.py create mode 100644 doc/salome/examples/normal_face.py create mode 100644 doc/salome/examples/notebook_geom.py create mode 100644 doc/salome/examples/point_coordinates.py create mode 100644 doc/salome/examples/primitives_ex01.py create mode 100644 doc/salome/examples/primitives_ex02.py create mode 100644 doc/salome/examples/primitives_ex03.py create mode 100644 doc/salome/examples/primitives_ex04.py create mode 100644 doc/salome/examples/primitives_ex05.py create mode 100644 doc/salome/examples/primitives_ex06.py create mode 100644 doc/salome/examples/primitives_ex07.py create mode 100644 doc/salome/examples/repairing_operations_ex01.py create mode 100644 doc/salome/examples/repairing_operations_ex02.py create mode 100644 doc/salome/examples/repairing_operations_ex03.py create mode 100644 doc/salome/examples/repairing_operations_ex04.py create mode 100644 doc/salome/examples/repairing_operations_ex05.py create mode 100644 doc/salome/examples/repairing_operations_ex06.py create mode 100644 doc/salome/examples/repairing_operations_ex07.py create mode 100644 doc/salome/examples/repairing_operations_ex08.py create mode 100644 doc/salome/examples/repairing_operations_ex09.py create mode 100644 doc/salome/examples/repairing_operations_ex10.py create mode 100644 doc/salome/examples/repairing_operations_ex11.py create mode 100644 doc/salome/examples/sketcher.py create mode 100755 doc/salome/examples/testme.py create mode 100644 doc/salome/examples/tolerance.py create mode 100644 doc/salome/examples/topological_geom_objs_ex01.py create mode 100644 doc/salome/examples/topological_geom_objs_ex02.py create mode 100644 doc/salome/examples/topological_geom_objs_ex03.py create mode 100644 doc/salome/examples/topological_geom_objs_ex04.py create mode 100644 doc/salome/examples/topological_geom_objs_ex05.py create mode 100644 doc/salome/examples/topological_geom_objs_ex06.py create mode 100644 doc/salome/examples/transformation_operations_ex01.py create mode 100644 doc/salome/examples/transformation_operations_ex02.py create mode 100644 doc/salome/examples/transformation_operations_ex03.py create mode 100644 doc/salome/examples/transformation_operations_ex04.py create mode 100644 doc/salome/examples/transformation_operations_ex05.py create mode 100644 doc/salome/examples/transformation_operations_ex06.py create mode 100644 doc/salome/examples/transformation_operations_ex07.py create mode 100644 doc/salome/examples/transformation_operations_ex08.py create mode 100644 doc/salome/examples/transformation_operations_ex09.py create mode 100644 doc/salome/examples/transformation_operations_ex10.py create mode 100644 doc/salome/examples/transformation_operations_ex11.py create mode 100644 doc/salome/examples/transformation_operations_ex12.py create mode 100644 doc/salome/examples/transformation_operations_ex13.py create mode 100644 doc/salome/examples/viewing_geom_objs_ex01.py create mode 100644 doc/salome/examples/viewing_geom_objs_ex02.py create mode 100644 doc/salome/examples/viewing_geom_objs_ex03.py create mode 100644 doc/salome/examples/viewing_geom_objs_ex04.py create mode 100644 doc/salome/examples/whatis.py create mode 100644 doc/salome/examples/working_with_groups_ex01.py create mode 100644 doc/salome/examples/working_with_groups_ex02.py create mode 100644 doc/salome/examples/working_with_groups_ex03.py create mode 100644 doc/salome/examples/working_with_groups_ex04.py create mode 100644 doc/salome/examples/working_with_groups_ex05.py create mode 100644 doc/salome/examples/working_with_groups_ex06.py create mode 100755 doc/salome/gui/GEOM/images/hide_predef_material.PNG create mode 100755 doc/salome/gui/GEOM/images/materials_library.png create mode 100755 doc/salome/gui/GEOM/images/show_predef_material.PNG rename src/{GEOMAlgo => BlockFix}/BlockFix.cxx (100%) rename src/{GEOMAlgo => BlockFix}/BlockFix.hxx (78%) rename src/{GEOMAlgo => BlockFix}/BlockFix_BlockFixAPI.cxx (85%) rename src/{GEOMAlgo/BlockFix_BlockFixAPI.lxx => BlockFix/BlockFix_BlockFixAPI.hxx} (72%) rename src/{GEOMAlgo => BlockFix}/BlockFix_CheckTool.cxx (98%) rename src/{GEOMAlgo/BlockFix_CheckTool.jxx => BlockFix/BlockFix_CheckTool.hxx} (52%) rename src/{GEOMAlgo => BlockFix}/BlockFix_PeriodicSurfaceModifier.cxx (92%) create mode 100644 src/BlockFix/BlockFix_PeriodicSurfaceModifier.hxx rename src/{GEOMAlgo => BlockFix}/BlockFix_SphereSpaceModifier.cxx (94%) create mode 100644 src/BlockFix/BlockFix_SphereSpaceModifier.hxx rename src/{GEOMAlgo => BlockFix}/BlockFix_UnionEdges.cxx (99%) rename src/{GEOMAlgo/BlockFix_UnionEdges.jxx => BlockFix/BlockFix_UnionEdges.hxx} (72%) rename src/{GEOMAlgo => BlockFix}/BlockFix_UnionFaces.cxx (99%) rename src/{GEOMAlgo => BlockFix}/BlockFix_UnionFaces.hxx (64%) create mode 100644 src/BlockFix/Makefile.am delete mode 100644 src/DlgRef/DlgRef_1Sel4Spin2Check_QTD.ui delete mode 100644 src/DlgRef/DlgRef_1Sel4Spin_QTD.ui delete mode 100644 src/DlgRef/DlgRef_1Sel5Spin_QTD.ui delete mode 100644 src/DlgRef/DlgRef_2Sel4Spin1Check_QTD.ui delete mode 100644 src/GEOMAlgo/BlockFix.cdl delete mode 100644 src/GEOMAlgo/BlockFix.ixx delete mode 100644 src/GEOMAlgo/BlockFix.jxx delete mode 100644 src/GEOMAlgo/BlockFix_BlockFixAPI.cdl delete mode 100644 src/GEOMAlgo/BlockFix_BlockFixAPI.hxx delete mode 100644 src/GEOMAlgo/BlockFix_BlockFixAPI.ixx delete mode 100644 src/GEOMAlgo/BlockFix_BlockFixAPI.jxx delete mode 100644 src/GEOMAlgo/BlockFix_CheckTool.cdl delete mode 100644 src/GEOMAlgo/BlockFix_CheckTool.hxx delete mode 100644 src/GEOMAlgo/BlockFix_CheckTool.ixx delete mode 100644 src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.cdl delete mode 100644 src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.hxx delete mode 100644 src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.ixx delete mode 100644 src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.jxx delete mode 100644 src/GEOMAlgo/BlockFix_SphereSpaceModifier.cdl delete mode 100644 src/GEOMAlgo/BlockFix_SphereSpaceModifier.hxx delete mode 100644 src/GEOMAlgo/BlockFix_SphereSpaceModifier.ixx delete mode 100644 src/GEOMAlgo/BlockFix_SphereSpaceModifier.jxx delete mode 100644 src/GEOMAlgo/BlockFix_UnionEdges.cdl delete mode 100644 src/GEOMAlgo/BlockFix_UnionEdges.hxx delete mode 100644 src/GEOMAlgo/BlockFix_UnionEdges.ixx delete mode 100644 src/GEOMAlgo/BlockFix_UnionFaces.cdl delete mode 100644 src/GEOMAlgo/BlockFix_UnionFaces.ixx delete mode 100644 src/GEOMAlgo/BlockFix_UnionFaces.jxx delete mode 100644 src/GEOMAlgo/Handle_BlockFix_BlockFixAPI.hxx delete mode 100644 src/GEOMAlgo/Handle_BlockFix_PeriodicSurfaceModifier.hxx delete mode 100644 src/GEOMAlgo/Handle_BlockFix_SphereSpaceModifier.hxx create mode 100644 src/GEOMUtils/GEOMUtils.cxx create mode 100644 src/GEOMUtils/GEOMUtils.hxx create mode 100644 src/GEOMUtils/Makefile.am create mode 100644 src/GEOM_I/GEOM_wrap.hxx delete mode 100644 src/MeasureGUI/MeasureGUI_2Sel4LineEdit_QTD.ui create mode 100644 src/OBJECT/GEOM_Constants.cxx diff --git a/build_configure b/build_configure index 8d2bef16f..dca23c575 100755 --- a/build_configure +++ b/build_configure @@ -26,7 +26,6 @@ # Author : Marc Tajchman - CEA # Date : 10/10/2002 # Modified by : Alexander BORODIN (OCN) - autotools usage -# $Header$ # 13/03/2007: Alexander BORODIN - OCN # Reorganization for usage of autotools # diff --git a/configure.ac b/configure.ac index 2ba331467..921fd1cc7 100644 --- a/configure.ac +++ b/configure.ac @@ -476,6 +476,7 @@ AC_OUTPUT([ \ doc/docutils/Makefile \ doc/docutils/conf.py \ doc/salome/Makefile \ + doc/salome/examples/Makefile \ doc/salome/gui/Makefile \ doc/salome/gui/GEOM/Makefile \ doc/salome/gui/GEOM/doxyfile \ @@ -499,12 +500,14 @@ AC_OUTPUT([ \ src/DlgRef/Makefile \ src/EntityGUI/Makefile \ src/GEOM/Makefile \ + src/BlockFix/Makefile \ src/GEOMAlgo/Makefile \ src/GEOMBase/Makefile \ src/GEOMClient/Makefile \ src/GEOMFiltersSelection/Makefile \ src/Material/Makefile \ src/GEOMGUI/Makefile \ + src/GEOMUtils/Makefile \ src/GEOMImpl/Makefile \ src/GEOMToolsGUI/Makefile \ src/GEOM_I/Makefile \ diff --git a/doc/salome/Makefile.am b/doc/salome/Makefile.am index 8bf9f392d..18bd13960 100644 --- a/doc/salome/Makefile.am +++ b/doc/salome/Makefile.am @@ -20,10 +20,9 @@ # -* Makefile *- # Author : Patrick GOLDBRONN (CEA) # Date : 30/11/2001 -# Modified by : Alexander BORODIN (OCN) - autotools usage -# $Header: +# Modified by : Alexander BORODIN (OCN) - autotools usage # -SUBDIRS = tui gui +SUBDIRS = tui gui examples SUBDIRSTUI = tui SUBDIRSGUI = gui diff --git a/doc/salome/examples/3dsketcher.py b/doc/salome/examples/3dsketcher.py new file mode 100644 index 000000000..84dc28112 --- /dev/null +++ b/doc/salome/examples/3dsketcher.py @@ -0,0 +1,43 @@ +# 3D Sketcher + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# Create a 3D sketcher (wire) on the given points coordinates +sketcher1 = geompy.Make3DSketcher([ 0,0,0, 50,50,50, 0,50,0, 50,0,50, 10,20,100, 0,0,0 ]) + +# add object in the study +id_sketcher1 = geompy.addToStudy(sketcher1, "Sketcher1") + +# display the sketcher +gg.createAndDisplayGO(id_sketcher1) + +# Create a 3D sketcher (wire) with Sketcher3D interface + +# get the interface instance +sk = geompy.Sketcher3D() + +# add three points with absolute coordinates +# the first point will be the start point of sketcher +# two segments will be added by this command +sk.addPointsAbsolute(1,2,3, 7,0,0, 10,-3.5,-11) + +# add one segment, defined by two angles in "OXY" coordinate system and length +sk.addPointAnglesLength("OXY", 45, 0, 100) + +# add three points with relative coordinates +# three segments will be added by this command +sk.addPointsRelative(20,0,0, 20,0,100, -40,0,-50) + +# set to close the sketcher +sk.close() + +# obtain the sketcher result +sketcher2 = sk.wire() + +# add object in the study +id_sketcher2 = geompy.addToStudy(sketcher2, "Sketcher2") + +# display the sketcher +gg.createAndDisplayGO(id_sketcher2) diff --git a/doc/salome/examples/Makefile.am b/doc/salome/examples/Makefile.am new file mode 100644 index 000000000..1174f0114 --- /dev/null +++ b/doc/salome/examples/Makefile.am @@ -0,0 +1,141 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# 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. +# +# 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# File : Makefile +# Author : Alexander KOVALEV (Open Cascade NN) +# Modified by : +# Module : doc +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +pyexamplesdir = $(docdir)/examples/GEOM + +BAD_TESTS = + +GOOD_TESTS = \ + 3dsketcher.py \ + advanced_geom_objs_ex01.py \ + advanced_geom_objs_ex02.py \ + advanced_geom_objs_ex03.py \ + angle.py \ + basic_geom_objs_ex01.py \ + basic_geom_objs_ex02.py \ + basic_geom_objs_ex03.py \ + basic_geom_objs_ex04.py \ + basic_geom_objs_ex05.py \ + basic_geom_objs_ex06.py \ + basic_geom_objs_ex07.py \ + basic_geom_objs_ex08.py \ + basic_geom_objs_ex09.py \ + basic_operations_ex01.py \ + basic_operations_ex02.py \ + basic_operations_ex03.py \ + basic_properties.py \ + blocks_operations_ex01.py \ + blocks_operations_ex02.py \ + blocks_operations_ex03.py \ + boolean_operations_ex01.py \ + boolean_operations_ex02.py \ + boolean_operations_ex03.py \ + boolean_operations_ex04.py \ + bounding_box.py \ + building_by_blocks_ex01.py \ + building_by_blocks_ex02.py \ + center_of_mass.py \ + check_compound_of_blocks.py \ + check_self_intersections.py \ + check_shape.py \ + complex_objs_ex01.py \ + complex_objs_ex02.py \ + complex_objs_ex03.py \ + complex_objs_ex04.py \ + complex_objs_ex05.py \ + complex_objs_ex06.py \ + complex_objs_ex07.py \ + complex_objs_ex08.py \ + complex_objs_ex09.py \ + complex_objs_ex10.py \ + free_boundaries.py \ + free_faces.py \ + get_non_blocks.py \ + import_export.py \ + inertia.py \ + min_distance.py \ + normal_face.py \ + notebook_geom.py \ + point_coordinates.py \ + primitives_ex01.py \ + primitives_ex02.py \ + primitives_ex03.py \ + primitives_ex04.py \ + primitives_ex05.py \ + primitives_ex06.py \ + primitives_ex07.py \ + repairing_operations_ex01.py \ + repairing_operations_ex02.py \ + repairing_operations_ex03.py \ + repairing_operations_ex04.py \ + repairing_operations_ex05.py \ + repairing_operations_ex06.py \ + repairing_operations_ex07.py \ + repairing_operations_ex08.py \ + repairing_operations_ex09.py \ + repairing_operations_ex10.py \ + repairing_operations_ex11.py \ + sketcher.py \ + tolerance.py \ + topological_geom_objs_ex01.py \ + topological_geom_objs_ex02.py \ + topological_geom_objs_ex03.py \ + topological_geom_objs_ex04.py \ + topological_geom_objs_ex05.py \ + topological_geom_objs_ex06.py \ + transformation_operations_ex01.py \ + transformation_operations_ex02.py \ + transformation_operations_ex03.py \ + transformation_operations_ex04.py \ + transformation_operations_ex05.py \ + transformation_operations_ex06.py \ + transformation_operations_ex07.py \ + transformation_operations_ex08.py \ + transformation_operations_ex09.py \ + transformation_operations_ex10.py \ + transformation_operations_ex11.py \ + transformation_operations_ex12.py \ + transformation_operations_ex13.py \ + viewing_geom_objs_ex01.py \ + viewing_geom_objs_ex02.py \ + viewing_geom_objs_ex03.py \ + viewing_geom_objs_ex04.py \ + whatis.py \ + working_with_groups_ex01.py \ + working_with_groups_ex02.py \ + working_with_groups_ex03.py \ + working_with_groups_ex04.py \ + working_with_groups_ex05.py \ + working_with_groups_ex06.py + +pyexamples_SCRIPTS = $(BAD_TESTS) $(GOOD_TESTS) + +EXTRA_DIST += $(pyexamples_SCRIPTS) testme.py + +check-local: + @for f in $(GOOD_TESTS) ; do \ + python $(top_srcdir)/doc/salome/examples/testme.py $(top_srcdir)/doc/salome/examples/$$f || exit 1; \ + done diff --git a/doc/salome/examples/advanced_geom_objs_ex01.py b/doc/salome/examples/advanced_geom_objs_ex01.py new file mode 100644 index 000000000..eb3db5fe5 --- /dev/null +++ b/doc/salome/examples/advanced_geom_objs_ex01.py @@ -0,0 +1,73 @@ +# Creation of PipeTShape + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create PipeTShape object +pipetshape = geompy.MakePipeTShape(80.0, 20.0, 200.0, 50.0, 20.0, 200.0) + +# add object in the study +id_pipetshape = geompy.addToStudy(pipetshape[0],"PipeTShape") +# add groups in the study +for g in pipetshape[1:]: + geompy.addToStudyInFather(pipetshape[0], g, g.GetName()) + +# Create junction vertices +P1 = geompy.MakeVertex(0.0, 0.0, 0.0) +P2 = geompy.MakeVertex(400.0, 0.0, 0.0) +P3 = geompy.MakeVertex(200.0, 0.0, 200.0) + +# create PipeTShape object with position +pipetshape_position = geompy.MakePipeTShape(80.0, 20.0, 200.0, 50.0, 20.0, 200.0, True, P1, P2, P3) + +# add object in the study +id_pipetshape_position = geompy.addToStudy(pipetshape_position[0],"PipeTShape_position") +# add groups in the study +for g in pipetshape_position[1:]: + geompy.addToStudyInFather(pipetshape_position[0], g, g.GetName()) + +# create PipeTShape with chamfer object +pipetshapechamfer = geompy.MakePipeTShapeChamfer(80.0, 20.0, 200.0, 50.0, 20.0, 200.0, 20.0, 20.0) + +# add object in the study +id_pipetshapechamfer = geompy.addToStudy(pipetshapechamfer[0],"PipeTShapeChamfer") +# add groups in the study +for g in pipetshapechamfer[1:]: + geompy.addToStudyInFather(pipetshapechamfer[0], g, g.GetName()) + +# create PipeTShape with chamfer object with position +pipetshapechamfer_position = geompy.MakePipeTShapeChamfer(80.0, 20.0, 200.0, 50.0, 20.0, 200.0, 20.0, 20.0, True, P1, P2, P3) + +# add object in the study +id_pipetshapechamfer_position = geompy.addToStudy(pipetshapechamfer_position[0],"PipeTShapeChamfer_position") +# add groups in the study +for g in pipetshapechamfer_position[1:]: + geompy.addToStudyInFather(pipetshapechamfer_position[0], g, g.GetName()) + +# create PipeTShape with fillet object +pipetshapefillet = geompy.MakePipeTShapeFillet(80.0, 20.0, 200.0, 50.0, 20.0, 200.0, 5.0) + +# add object in the study +id_pipetshapefillet = geompy.addToStudy(pipetshapefillet[0],"PipeTShapeFillet") +# add groups in the study +for g in pipetshapefillet[1:]: + geompy.addToStudyInFather(pipetshapefillet[0], g, g.GetName()) + +# create PipeTShape with fillet object with position +pipetshapefillet_position = geompy.MakePipeTShapeFillet(80.0, 20.0, 200.0, 50.0, 20.0, 200.0, 5.0, True, P1, P2, P3) + +# add object in the study +id_pipetshapefillet_position = geompy.addToStudy(pipetshapefillet_position[0],"PipeTShapeFillet_position") +# add groups in the study +for g in pipetshapefillet_position[1:]: + geompy.addToStudyInFather(pipetshapefillet_position[0], g, g.GetName()) + + +# display pipetshapes +gg.createAndDisplayGO(id_pipetshape) +gg.createAndDisplayGO(id_pipetshape_position) +gg.createAndDisplayGO(id_pipetshapechamfer) +gg.createAndDisplayGO(id_pipetshapechamfer_position) +gg.createAndDisplayGO(id_pipetshapefillet) +gg.createAndDisplayGO(id_pipetshapefillet_position) diff --git a/doc/salome/examples/advanced_geom_objs_ex02.py b/doc/salome/examples/advanced_geom_objs_ex02.py new file mode 100644 index 000000000..2ee301688 --- /dev/null +++ b/doc/salome/examples/advanced_geom_objs_ex02.py @@ -0,0 +1,15 @@ +# Creation of DividedDisk + +import geompy +import salome +import GEOM +gg = salome.ImportComponentGUI("GEOM") + +# create DividedDisk object +divideddisk = geompy.MakeDividedDisk(100, 1, GEOM.SQUARE) + +# add object in the study +id_divideddisk = geompy.addToStudy(divideddisk,"DividedDisk") + +# display divideddisk +gg.createAndDisplayGO(id_divideddisk) diff --git a/doc/salome/examples/advanced_geom_objs_ex03.py b/doc/salome/examples/advanced_geom_objs_ex03.py new file mode 100644 index 000000000..195cda0dd --- /dev/null +++ b/doc/salome/examples/advanced_geom_objs_ex03.py @@ -0,0 +1,15 @@ +# Creation of DividedCylinder + +import geompy +import salome +import GEOM +gg = salome.ImportComponentGUI("GEOM") + +# create DividedCylinder object +dividedcylinder = geompy.MakeDividedCylinder(100, 300, GEOM.SQUARE) + +# add object in the study +id_dividedcylinder = geompy.addToStudy(dividedcylinder,"DividedCylinder") + +# display dividedcylinder +gg.createAndDisplayGO(id_dividedcylinder) diff --git a/doc/salome/examples/angle.py b/doc/salome/examples/angle.py new file mode 100644 index 000000000..547db7184 --- /dev/null +++ b/doc/salome/examples/angle.py @@ -0,0 +1,60 @@ +# Angle + +import salome +salome.salome_init() + +import math +import geompy +geompy.init_geom(salome.myStudy) + +OX = geompy.MakeVectorDXDYDZ(10, 0,0) +OXY = geompy.MakeVectorDXDYDZ(10,10,0) + +# in one plane +Angle = geompy.GetAngle(OX, OXY) + +print "\nAngle between OX and OXY = ", Angle +if math.fabs(Angle - 45.0) > 1e-05: + print " Error: returned angle is", Angle, "while must be 45.0" + pass + +Angle = geompy.GetAngleRadians(OX, OXY) + +print "\nAngle between OX and OXY in radians = ", Angle +if math.fabs(Angle - math.pi/4) > 1e-05: + print " Error: returned angle is", Angle, "while must be pi/4" + pass + +Angle = geompy.GetAngleVectors(OX, OXY, True) + +print "\nAngle between vectors OX and OXY = ", Angle +if math.fabs(Angle - 45.0) > 1e-05: + print " Error: returned angle is", Angle, "while must be 45.0" + pass + +Angle = geompy.GetAngleRadiansVectors(OX, OXY, False) + +print "\nBig angle between vectors OX and OXY in radians = ", Angle +if math.fabs(Angle - math.pi*7./4.) > 1e-05: + print " Error: returned angle is", Angle, "while must be 7*pi/4" + pass + +# not in one plane +OXY_shift = geompy.MakeTranslation(OXY,10,-10,20) +Angle = geompy.GetAngle(OX, OXY_shift) + +print "\nAngle between OX and OXY_shift = ", Angle +if math.fabs(Angle - 45.0) > 1e-05: + print " Error: returned angle is", Angle, "while must be 45.0" + pass + +# not linear +pnt1 = geompy.MakeVertex(0, 0, 0) +pnt2 = geompy.MakeVertex(10, 0, 0) +pnt3 = geompy.MakeVertex(20, 10, 0) +arc = geompy.MakeArc(pnt1, pnt2, pnt3) +Angle = geompy.GetAngle(OX, arc) + +if (math.fabs(Angle + 1.0) > 1e-6 or geompy.MeasuOp.IsDone()): + print "Error. Angle must not be computed on curvilinear edges" + pass diff --git a/doc/salome/examples/basic_geom_objs_ex01.py b/doc/salome/examples/basic_geom_objs_ex01.py new file mode 100644 index 000000000..05abb799d --- /dev/null +++ b/doc/salome/examples/basic_geom_objs_ex01.py @@ -0,0 +1,61 @@ +# Creation of a Point + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p0 = geompy.MakeVertex(0., 0., 0.) +p100 = geompy.MakeVertexWithRef(p0, 100., 100., 100.) +px = geompy.MakeVertex(100., 0., 0.) +py = geompy.MakeVertex(0., 100., 0.) +pz = geompy.MakeVertex(0., 0., 100.) +p1 = geompy.MakeVertex(50., 50., 30.) + +# create a curve and vertices on it +Arc = geompy.MakeArc(py, pz, px) +# create a vertex by parameter +p_on_arc = geompy.MakeVertexOnCurve(Arc, 0.25) +# create a vertex by length +p_on_arc2 = geompy.MakeVertexOnCurveByLength(Arc, 50., None) +#create a vertex by point projection +p_on_arc3 = geompy.MakeVertexOnCurveByCoord(Arc, 100, -10, 10) + +# create 2 lines and make a point on its intersection +line_1 = geompy.MakeLineTwoPnt(p0, p100) +line_2 = geompy.MakeLineTwoPnt(p1, pz) +p_inter = geompy.MakeVertexOnLinesIntersection(line_1, line_2) + +# create a face and vertices on it +Add_line = geompy.MakeLineTwoPnt(px, py) +arc_face = geompy.MakeFaceWires([Arc, Add_line], 1) +p_on_face1 = geompy.MakeVertexOnSurface(arc_face, 0.5, 0.5) +p_on_face2 = geompy.MakeVertexOnSurfaceByCoord(arc_face, 35, 35, 35) +p_on_face3 = geompy.MakeVertexInsideFace(arc_face) + + +# add objects in the study +id_p0 = geompy.addToStudy(p0, "Vertex 0") +id_p100 = geompy.addToStudy(p100, "Vertex 100") +id_px = geompy.addToStudy(px, "Vertex X") +id_py = geompy.addToStudy(py, "Vertex Y") +id_pz = geompy.addToStudy(pz, "Vertex Z") +id_Arc = geompy.addToStudy(Arc, "Arc") +id_line_1 = geompy.addToStudy(line_1, "Line 1") +id_line_2 = geompy.addToStudy(line_2, "Line 2") +id_p_on_arc = geompy.addToStudy(p_on_arc, "Vertex on Arc by parameter") +id_p_on_arc2 = geompy.addToStudy(p_on_arc2, "Vertex on Arc by length") +id_p_on_arc3 = geompy.addToStudy(p_on_arc3, "Vertex on Arc by point projection") +id_p_inter = geompy.addToStudy(p_inter, "Vertex on Lines Intersection") +id_p_on_face1 = geompy.addToStudy(p_on_face1, "Vertex on face by parameter") +id_p_on_face2 = geompy.addToStudy(p_on_face2, "Vertex on face by point projection") +id_p_on_face3 = geompy.addToStudy(p_on_face3, "Vertex inside face") + +# display vertices +gg.createAndDisplayGO(id_p0) +gg.createAndDisplayGO(id_p100) +gg.createAndDisplayGO(id_Arc) +gg.createAndDisplayGO(id_p_inter) +gg.createAndDisplayGO(id_p_on_arc) +gg.createAndDisplayGO(id_p_on_arc2) +gg.createAndDisplayGO(id_p_on_arc3) diff --git a/doc/salome/examples/basic_geom_objs_ex02.py b/doc/salome/examples/basic_geom_objs_ex02.py new file mode 100644 index 000000000..02f87e910 --- /dev/null +++ b/doc/salome/examples/basic_geom_objs_ex02.py @@ -0,0 +1,31 @@ +# Creation of a Line + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p0 = geompy.MakeVertex(0., 0., 0.) +p100 = geompy.MakeVertexWithRef(p0, 100., 100., 100.) +px = geompy.MakeVertex(100., 0. , 0. ) +py = geompy.MakeVertex(0. , 100., 0. ) +pz = geompy.MakeVertex(0. , 0. , 100.) + +# create a vector from two points +vxy = geompy.MakeVector(px, py) + +# create a line from a point and a vector +line1 = geompy.MakeLine(pz, vxy) + +#create a line from two points +line2 = geompy.MakeLineTwoPnt(p0, p100) + +# add objects in the study +id_vxy = geompy.addToStudy(vxy, "Vector") +id_line1 = geompy.addToStudy(line1,"Line1") +id_line2 = geompy.addToStudy(line2,"Line2") + +# display lines +gg.createAndDisplayGO(id_vxy) +gg.createAndDisplayGO(id_line1) +gg.createAndDisplayGO(id_line2) diff --git a/doc/salome/examples/basic_geom_objs_ex03.py b/doc/salome/examples/basic_geom_objs_ex03.py new file mode 100644 index 000000000..510ae18fc --- /dev/null +++ b/doc/salome/examples/basic_geom_objs_ex03.py @@ -0,0 +1,30 @@ +# Creation of a Circle + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p0 = geompy.MakeVertex(0., 0., 0.) +px = geompy.MakeVertex(100., 0. , 0. ) +py = geompy.MakeVertex(0. , 100., 0. ) +pz = geompy.MakeVertex(0. , 0. , 100.) + +# create a vector on two points +vxy = geompy.MakeVector(px, py) + +# create a circle from a point, a vector and a radius +circle1 = geompy.MakeCircle(pz, vxy, 30) + +#create a circle from three points +circle2 = geompy.MakeCircleThreePnt(p0, px, py) + +# add objects in the study +id_vxy = geompy.addToStudy(vxy, "Vector") +id_circle1 = geompy.addToStudy(circle1,"Circle1") +id_circle2 = geompy.addToStudy(circle2,"Circle2") + +# display circles +gg.createAndDisplayGO(id_vxy) +gg.createAndDisplayGO(id_circle1) +gg.createAndDisplayGO(id_circle2) diff --git a/doc/salome/examples/basic_geom_objs_ex04.py b/doc/salome/examples/basic_geom_objs_ex04.py new file mode 100644 index 000000000..bf7d3e870 --- /dev/null +++ b/doc/salome/examples/basic_geom_objs_ex04.py @@ -0,0 +1,34 @@ +# Creation of an Ellipse + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p0 = geompy.MakeVertex(0., 0., 0.) +p1 = geompy.MakeVertex(50., 50., 50.) +p2 = geompy.MakeVertex(0., 50., 0.) + +# create a normal vector from two points +normal = geompy.MakeVector(p0, p1) + +# create a major axis vector from two points +major = geompy.MakeVector(p0, p2) + +# create an ellipse from a point, a vector and radiuses +ellipse1 = geompy.MakeEllipse(p1, normal, 50, 25) + +# create an ellipse from a point, a normal vector, radiuses and a major axis vector +ellipse2 = geompy.MakeEllipse(p1, normal, 50, 25, major) + +# add objects in the study +id_normal = geompy.addToStudy(normal, "Normal") +id_major = geompy.addToStudy(major, "Major Axis") +id_ellipse1 = geompy.addToStudy(ellipse1, "Ellipse 1") +id_ellipse2 = geompy.addToStudy(ellipse2, "Ellipse 2") + +# display the ellipse and its normal vector +gg.createAndDisplayGO(id_normal) +gg.createAndDisplayGO(id_major) +gg.createAndDisplayGO(id_ellipse1) +gg.createAndDisplayGO(id_ellipse2) diff --git a/doc/salome/examples/basic_geom_objs_ex05.py b/doc/salome/examples/basic_geom_objs_ex05.py new file mode 100644 index 000000000..5a82c3b1b --- /dev/null +++ b/doc/salome/examples/basic_geom_objs_ex05.py @@ -0,0 +1,29 @@ +# Creation of an Arc + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p0 = geompy.MakeVertex(0., 0., 0.) +p1 = geompy.MakeVertex(100., 0., 0.) +p2 = geompy.MakeVertex(50., 0., 50.) + +# create an arc from a three points +arc1 = geompy.MakeArc(p0, p1, p2) + +# create an arc from a center point, a start point and end point +arc2 = geompy.MakeArcCenter(p0, p1, p2, 1) + +# create an arc from a center point, a major point and minor point +arc3 = geompy.MakeArcOfEllipse(p0, p1, p2) + +# add objects in the study +id_arc1 = geompy.addToStudy(arc1, "Arc 1") +id_arc2 = geompy.addToStudy(arc2, "Arc 2") +id_arc3 = geompy.addToStudy(arc3, "Arc 3") + +# display the arcs +gg.createAndDisplayGO(id_arc1) +gg.createAndDisplayGO(id_arc2) +gg.createAndDisplayGO(id_arc3) diff --git a/doc/salome/examples/basic_geom_objs_ex06.py b/doc/salome/examples/basic_geom_objs_ex06.py new file mode 100644 index 000000000..ba4940c14 --- /dev/null +++ b/doc/salome/examples/basic_geom_objs_ex06.py @@ -0,0 +1,68 @@ +# Creation of a Curve + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices and vectors +p0 = geompy.MakeVertex(0. , 0. , 0. ) +p1 = geompy.MakeVertex(50. , 100., 200.) +p2 = geompy.MakeVertex(150., 50., 100.) +p3 = geompy.MakeVertex(100., 150., 170.) +p4 = geompy.MakeVertex(200., 200., 150.) + +v1 = geompy.MakeVectorDXDYDZ(0, 1, 0) +v2 = geompy.MakeVectorDXDYDZ(1, 0, 0) + +# create a polyline from a list of points +polyline = geompy.MakePolyline([p0, p1, p2, p3, p4]) + +# create a bezier curve from a list of points +bezier = geompy.MakeBezier([p0, p1, p2, p3, p4]) + +#create a b-spline curve from a list of points +interpol = geompy.MakeInterpol([p0, p1, p2, p3, p4], False) + +#create a b-spline curve with defined directions at the ends +interpol_tangents = geompy.MakeInterpolWithTangents([p0, p1, p2, p3, p4], v1, v2) + +#create a polyline using parametric definition of the basic points +param_polyline = geompy.MakeCurveParametric("t", "sin(t)", "cos(t)", 0., 100., 100, geompy.GEOM.Polyline, theNewMethod=True) + +# create a bezier curve using parametric definition of the basic points +param_bezier = geompy.MakeCurveParametric("t", "sin(t)", "cos(t)", 0., 100., 20, geompy.GEOM.Bezier, theNewMethod=True) + +#create a b-spline curve using parametric definition of the basic points +param_interpol = geompy.MakeCurveParametric("t", "sin(t)", "cos(t)", 0., 100., 100, geompy.GEOM.Interpolation, theNewMethod=True) + + +# add objects in the study +id_p0 = geompy.addToStudy(p0, "Point1") +id_p1 = geompy.addToStudy(p1, "Point2") +id_p2 = geompy.addToStudy(p2, "Point3") +id_p3 = geompy.addToStudy(p3, "Point4") +id_p4 = geompy.addToStudy(p4, "Point5") +id_v1 = geompy.addToStudy(v1, "Vector1") +id_v2 = geompy.addToStudy(v2, "Vector2") +id_polyline = geompy.addToStudy(polyline, "Polyline") +id_bezier = geompy.addToStudy(bezier, "Bezier") +id_interpol = geompy.addToStudy(interpol, "Interpol") +id_interpol_tangents = geompy.addToStudy(interpol_tangents, "Interpol Tangents") +id_param_polyline = geompy.addToStudy(param_polyline, "Polyline Parametric") +id_param_bezier = geompy.addToStudy(param_bezier, "Bezier Parametric") +id_param_interpol = geompy.addToStudy(param_interpol, "Interpol Parametric") + + +# display the points and the curves +gg.createAndDisplayGO(id_p0) +gg.createAndDisplayGO(id_p1) +gg.createAndDisplayGO(id_p2) +gg.createAndDisplayGO(id_p3) +gg.createAndDisplayGO(id_p4) +gg.createAndDisplayGO(id_polyline) +gg.createAndDisplayGO(id_bezier) +gg.createAndDisplayGO(id_interpol) +gg.createAndDisplayGO(id_interpol_tangents) +gg.createAndDisplayGO(id_param_polyline) +gg.createAndDisplayGO(id_param_bezier) +gg.createAndDisplayGO(id_param_interpol) diff --git a/doc/salome/examples/basic_geom_objs_ex07.py b/doc/salome/examples/basic_geom_objs_ex07.py new file mode 100644 index 000000000..2de687af0 --- /dev/null +++ b/doc/salome/examples/basic_geom_objs_ex07.py @@ -0,0 +1,27 @@ +# Creation of a Vector + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p1 = geompy.MakeVertex(10., 50., 20.) +p2 = geompy.MakeVertex(70., 70., 70.) + +# create a vector from two points +vector1 = geompy.MakeVector(p1, p2) + +# create a vector from the given components +vector2 = geompy.MakeVectorDXDYDZ(30, 30, 100) + +# add objects in the study +id_p1 = geompy.addToStudy(p1, "Point1") +id_p2 = geompy.addToStudy(p2, "Point2") +id_vector1 = geompy.addToStudy(vector1,"Vector1") +id_vector2 = geompy.addToStudy(vector2,"Vector2") + +# display the points and the vectors +gg.createAndDisplayGO(id_p1) +gg.createAndDisplayGO(id_p2) +gg.createAndDisplayGO(id_vector1) +gg.createAndDisplayGO(id_vector2) diff --git a/doc/salome/examples/basic_geom_objs_ex08.py b/doc/salome/examples/basic_geom_objs_ex08.py new file mode 100644 index 000000000..81a8745c5 --- /dev/null +++ b/doc/salome/examples/basic_geom_objs_ex08.py @@ -0,0 +1,75 @@ +# Creation of a Plane + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p1 = geompy.MakeVertex( 0., 0., 100.) +p2 = geompy.MakeVertex(100., 0., 0.) +p3 = geompy.MakeVertex(200., 200., 200.) +p4 = geompy.MakeVertex(100., 100., 0.) +p5 = geompy.MakeVertex(0. , 100., 0.) + +# create a vectors from the given components +vector1 = geompy.MakeVectorDXDYDZ(100., 100., 100.) +vector2 = geompy.MakeVectorDXDYDZ(-100., 0., 100.) + +# create a vector from two points +vector_arc = geompy.MakeVector(p2, p5) + +# create an arc from three points +arc = geompy.MakeArc(p2, p4, p5) + +# create a wire +wire = geompy.MakeWire([vector_arc, arc]) + +# create a face +isPlanarWanted = 1 +face = geompy.MakeFace(wire, isPlanarWanted) +trimsize = 1000. + +# create a Local Coordinate System + +LCS = geompy.MakeMarker(100., 100., 101., 1, 0, 0, 0, 1, 0) + +# create a plane from a point, a vector and a trimsize +plane1 = geompy.MakePlane(p1, vector1, trimsize) + +# create a plane from three points and a trimsize +plane2 = geompy.MakePlaneThreePnt(p1, p2, p3, trimsize) + +# create a plane from the given face +plane3 = geompy.MakePlaneFace(face, trimsize) + +# create a plane from two vectors and a trimsize +plane4 = geompy.MakePlane2Vec(vector1, vector2, trimsize) + +# create a plane with the Local Coordinate System and a trimsize +plane5 = geompy.MakePlaneLCS(LCS, trimsize, 1) + +# add objects in the study +id_face = geompy.addToStudy(face, "Face") +id_plane1 = geompy.addToStudy(plane1,"Plane1") +id_plane2 = geompy.addToStudy(plane2,"Plane2") +id_plane3 = geompy.addToStudy(plane3,"Plane3") +id_plane4 = geompy.addToStudy(plane4,"Plane4") +id_plane5 = geompy.addToStudy(plane5,"Plane5") + +# display the points and the vectors +gg.createAndDisplayGO(id_face) +gg.createAndDisplayGO(id_plane1) +gg.createAndDisplayGO(id_plane2) +gg.createAndDisplayGO(id_plane3) +gg.createAndDisplayGO(id_plane4) +gg.createAndDisplayGO(id_plane5) +gg.setDisplayMode(id_plane1,1) +gg.setTransparency(id_plane1,0.5) +gg.setDisplayMode(id_plane2,1) +gg.setTransparency(id_plane2,0.5) +gg.setDisplayMode(id_plane3,1) +gg.setTransparency(id_plane3,0.5) +gg.setDisplayMode(id_plane4,1) +gg.setTransparency(id_plane4,0.5) +gg.setDisplayMode(id_plane5,1) +gg.setTransparency(id_plane5,0.5) diff --git a/doc/salome/examples/basic_geom_objs_ex09.py b/doc/salome/examples/basic_geom_objs_ex09.py new file mode 100644 index 000000000..3934410ee --- /dev/null +++ b/doc/salome/examples/basic_geom_objs_ex09.py @@ -0,0 +1,38 @@ +# Creation of a Local Coordinate System + +import GEOM +import geompy +import math +import SALOMEDS + +#Create vertexes, vectors and shapes to construct local CS +Vertex_1 = geompy.MakeVertex(50, 50, 50) +Vertex_2 = geompy.MakeVertex(70, 70, 70) +Vertex_3 = geompy.MakeVertex(0, 0, 0) +Vector_X = geompy.MakeVectorDXDYDZ(50, 0, 0) +Vector_Y = geompy.MakeVectorDXDYDZ(0, 50, 0) +Face_1 = geompy.MakeFaceHW(100, 100, 1) +Box_1 = geompy.MakeBoxTwoPnt(Vertex_1, Vertex_2) + +#Construct local CS by manual definition +LocalCS_1 = geompy.MakeMarker(0, 0, 0, 1, 0, 0, 0, 1, 0) + +#Construct local CS by center point and two vectors (X and Y directions) +LocalCS_2 = geompy.MakeMarkerPntTwoVec(Vertex_3, Vector_X, Vector_Y) + +#Construct local CS from shape orientation +LocalCS_FACE = geompy.MakeMarkerFromShape(Face_1) +LocalCS_BOX = geompy.MakeMarkerFromShape(Box_1) + +#Add created object to study +geompy.addToStudy( Face_1, "Face_1" ) +geompy.addToStudy( Vertex_1, "Vertex_1" ) +geompy.addToStudy( Vertex_2, "Vertex_2" ) +geompy.addToStudy( Box_1, "Box_1" ) +geompy.addToStudy( Vertex_3, "Vertex_3" ) +geompy.addToStudy( Vector_X, "Vector_X" ) +geompy.addToStudy( Vector_Y, "Vector_Y" ) +geompy.addToStudy( LocalCS_1, "LocalCS_1" ) +geompy.addToStudy( LocalCS_2, "LocalCS_3" ) +geompy.addToStudy( LocalCS_FACE, "LocalCS_FACE" ) +geompy.addToStudy( LocalCS_BOX, "LocalCS_BOX" ) diff --git a/doc/salome/examples/basic_operations_ex01.py b/doc/salome/examples/basic_operations_ex01.py new file mode 100644 index 000000000..bed9e1c86 --- /dev/null +++ b/doc/salome/examples/basic_operations_ex01.py @@ -0,0 +1,41 @@ +# Partition + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p0 = geompy.MakeVertex( 0., 0., 0.) +p200 = geompy.MakeVertex(200., 200., 200.) +pz = geompy.MakeVertex( 0., 0., 100.) + +# create a vector +vxyz = geompy.MakeVectorDXDYDZ(100., 100., 100.) + +# create a box from two points +box = geompy.MakeBoxTwoPnt(p0, p200) + +# create a plane +trimsize = 500. +plane = geompy.MakePlane(pz, vxyz, trimsize) + +# create partition objects +partition1 = geompy.MakePartition([box], [plane]) +partition2 = geompy.Partition([box], [plane]) +partition3 = geompy.MakeHalfPartition(box, plane) + +# add objects in the study +id_box = geompy.addToStudy(box,"Box") +id_plane = geompy.addToStudy(plane,"Plane") +id_partition1 = geompy.addToStudy(partition1,"MakePartition") +id_partition2 = geompy.addToStudy(partition2,"Partition") +id_partition3 = geompy.addToStudy(partition3,"MakeHalfPartition") + +# display the partition objects and the plane +gg.createAndDisplayGO(id_box) +gg.setDisplayMode(id_box,1) +gg.createAndDisplayGO(id_plane) +gg.setDisplayMode(id_plane,1) +gg.createAndDisplayGO(id_partition1) +gg.createAndDisplayGO(id_partition2) +gg.createAndDisplayGO(id_partition3) diff --git a/doc/salome/examples/basic_operations_ex02.py b/doc/salome/examples/basic_operations_ex02.py new file mode 100644 index 000000000..ac9b77b9d --- /dev/null +++ b/doc/salome/examples/basic_operations_ex02.py @@ -0,0 +1,28 @@ +# Archimede + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p0 = geompy.MakeVertex( 0., 0., 0.) +p200 = geompy.MakeVertex(200., 200., 200.) + +# create a box from two points +box = geompy.MakeBoxTwoPnt(p0, p200) + +# perform an Archimede operation on the selected shape with selected parameters +weight = 1000000. +waterdensity = 1. +meshingdeflection = 0.01 +archimede = geompy.Archimede(box, weight, waterdensity, meshingdeflection) + +# add objects in the study +id_box = geompy.addToStudy(box,"Box") +id_archimede = geompy.addToStudy(archimede,"Archimede") + +# display the box and the result of Archimede operation +gg.createAndDisplayGO(id_box) +gg.setDisplayMode(id_box,1) +gg.createAndDisplayGO(id_archimede) +gg.setDisplayMode(id_archimede,1) diff --git a/doc/salome/examples/basic_operations_ex03.py b/doc/salome/examples/basic_operations_ex03.py new file mode 100644 index 000000000..39b1dd22b --- /dev/null +++ b/doc/salome/examples/basic_operations_ex03.py @@ -0,0 +1,55 @@ +# Restore presentation parameters and sub-shapes + +import geompy +import GEOM +import SALOMEDS + +# create a box and a cylinder +box = geompy.MakeBoxDXDYDZ(200, 200, 200) +cyl = geompy.MakeCylinderRH(100, 300) + +# create translated box +vec = geompy.MakeVectorDXDYDZ(100, 50, 0) +tra = geompy.MakeTranslationVector(box, vec) + +# create partition objects +partition1 = geompy.MakePartition([box, cyl]) +partition2 = geompy.MakePartition([box], [cyl]) +partition3 = geompy.MakePartition([box], [tra]) + +# set colours +box.SetColor(SALOMEDS.Color(1,0,0)) +cyl.SetColor(SALOMEDS.Color(0,1,0)) + +# add objects in the study +geompy.addToStudy(box, "Box") +geompy.addToStudy(cyl, "Cylinder") +geompy.addToStudy(vec, "Vector") +geompy.addToStudy(tra, "Translation") +geompy.addToStudy(partition1, "Partition_1") +geompy.addToStudy(partition2, "Partition_2") +geompy.addToStudy(partition3, "Partition_3") + +# Restore presentation parameters and sub-shapes +# different methods can be used to find the sub-shapes in the result: +# GetInPlace, GetSame, GetInPlaceByHistory, GetShapesOnShape. +# By default, GetInPlace method is used (GEOM.FSM_GetInPlace) +geompy.RestoreSubShapes(partition1) + +geompy.RestoreSubShapes(partition2, [], GEOM.FSM_GetInPlace) + +# The list of arguments can be used to avoid restoring all arguments, +# but restore only the passed. +geompy.RestoreSubShapes(partition3, [tra], GEOM.FSM_GetInPlaceByHistory) + +# To find sub-shapes in a transformed shape only one method could be +# used: pass GEOM.FSM_Transformed for that. +# True passed for the last argument, means that the transformed shape +# will inherit colour and sub-shapes from its first argument (see above +# MakeTranslation). +geompy.RestoreSubShapes(tra, [], GEOM.FSM_Transformed, True) + +# Also we could do this directly with method addToStudy: +partition4 = geompy.MakePartition([box, tra]) +geompy.addToStudy(partition4, "Partition_4", True, [], + GEOM.FSM_GetInPlaceByHistory, False) diff --git a/doc/salome/examples/basic_properties.py b/doc/salome/examples/basic_properties.py new file mode 100644 index 000000000..239655901 --- /dev/null +++ b/doc/salome/examples/basic_properties.py @@ -0,0 +1,20 @@ +# Basic Properties + +import geompy +import math + +# create a box +box = geompy.MakeBoxDXDYDZ(100,30,100) +props = geompy.BasicProperties(box) +print "\nBox 100x30x100 Basic Properties:" +print " Wires length: ", props[0] +print " Surface area: ", props[1] +print " Volume : ", props[2] +length = math.sqrt((props[0] - 1840)*(props[0] - 1840)) +area = math.sqrt((props[1] - 32000)*(props[1] - 32000)) +volume = math.sqrt((props[2] - 300000)*(props[2] - 300000)) +if length > 1e-7 or area > 1e-7 or volume > 1e-7: + print "While must be:" + print " Wires length: ", 1840 + print " Surface area: ", 32000 + print " Volume : ", 300000. diff --git a/doc/salome/examples/blocks_operations_ex01.py b/doc/salome/examples/blocks_operations_ex01.py new file mode 100644 index 000000000..5535f121d --- /dev/null +++ b/doc/salome/examples/blocks_operations_ex01.py @@ -0,0 +1,35 @@ +# Multi Transformation + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p_25_25_50 = geompy.MakeVertex(25., 25., 50.) +p_50_25_25 = geompy.MakeVertex(50., 25., 25.) +p_25_50_25 = geompy.MakeVertex(25., 50., 25.) + +box = geompy.MakeBoxDXDYDZ(50, 50, 50) + +top_face = geompy.GetFaceNearPoint(box, p_25_25_50) +yz_face = geompy.GetFaceNearPoint(box, p_50_25_25) +xz_face = geompy.GetFaceNearPoint(box, p_25_50_25) + +top_face_ind = geompy.GetSubShapeID(box, top_face) +yz_face_ind = geompy.GetSubShapeID(box, yz_face) +xz_face_ind = geompy.GetSubShapeID(box, xz_face) + +# Multi-transformate block and glue the result +box_tr1 = geompy.MakeMultiTransformation1D(box, yz_face_ind, top_face_ind, 3) +box_tr2 = geompy.MakeMultiTransformation2D(box, xz_face_ind, yz_face_ind, 3, top_face_ind, 0, 2) + +# add objects in the study +id_box = geompy.addToStudy(box, "Box") +id_box_tr1 = geompy.addToStudy(box_tr1, "Multi-transformed Block 1D") +id_box_tr2 = geompy.addToStudy(box_tr2, "Multi-transformed Block 2D") + +# display the results +gg.createAndDisplayGO(id_box) +gg.setDisplayMode(id_box,1) +gg.createAndDisplayGO(id_box_tr1) +gg.createAndDisplayGO(id_box_tr2) diff --git a/doc/salome/examples/blocks_operations_ex02.py b/doc/salome/examples/blocks_operations_ex02.py new file mode 100644 index 000000000..68fbb01a6 --- /dev/null +++ b/doc/salome/examples/blocks_operations_ex02.py @@ -0,0 +1,26 @@ +# Explode on Blocks + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a box and a sphere +box = geompy.MakeBoxDXDYDZ(200, 200, 200) +sphere = geompy.MakeSphereR(100) + +# make a compound +compound = geompy.MakeCompound([box, sphere]) + +# get all the blocks of the given compound, by criteria: min_nb_faces <= nb. of faces <= max_nb_faces +min_nb_faces = 6 +max_nb_faces = 6 +make_block_explode = geompy.MakeBlockExplode(compound, min_nb_faces, max_nb_faces) + +# add objects in the study +id_compound = geompy.addToStudy(compound, "Compound") +id_make_block_explode = geompy.addToStudyInFather(compound, make_block_explode[0], "MakeBlockExplode") + +# display the results +gg.createAndDisplayGO(id_compound) +gg.createAndDisplayGO(id_make_block_explode) +gg.setDisplayMode(id_make_block_explode,1) diff --git a/doc/salome/examples/blocks_operations_ex03.py b/doc/salome/examples/blocks_operations_ex03.py new file mode 100644 index 000000000..546bc2274 --- /dev/null +++ b/doc/salome/examples/blocks_operations_ex03.py @@ -0,0 +1,20 @@ +# Propagate + +import geompy +import salome + +# create a box +box = geompy.MakeBoxDXDYDZ(200, 200, 200) + +# build all possible propagation groups +listChains = geompy.Propagate(check_box) + +# add objects in the study +geompy.addToStudy(check_box, "Box") +ii = 1 +for chain in listChains: + geompy.addToStudyInFather(check_box, chain, "propagation chain " + `ii`) + ii = ii + 1 + pass + +salome.sg.updateObjBrowser(1) diff --git a/doc/salome/examples/boolean_operations_ex01.py b/doc/salome/examples/boolean_operations_ex01.py new file mode 100644 index 000000000..5f52542c6 --- /dev/null +++ b/doc/salome/examples/boolean_operations_ex01.py @@ -0,0 +1,38 @@ +# Fuse + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex(25, 55, 0) +p2 = geompy.MakeVertex( 0, 0, 0) +v = geompy.MakeVector(p1, p2) + +# create a cylinder +height = 35 +radius1 = 20 +cylinder = geompy.MakeCylinder(p1, v, radius1, height) + +# create a sphere +sphere = geompy.MakeSphereR(40) + +# fuse +fuse1 = geompy.MakeFuse(cylinder, sphere) +fuse2 = geompy.MakeBoolean(cylinder, sphere, 3) + +# add objects in the study +id_cylinder = geompy.addToStudy(cylinder, "Cylinder") +id_sphere = geompy.addToStudy(sphere, "Sphere") +id_fuse1 = geompy.addToStudy(fuse1, "Fuse_1") +id_fuse2 = geompy.addToStudy(fuse2, "Fuse_2") + +# display results +gg.createAndDisplayGO(id_cylinder) +gg.setDisplayMode(id_cylinder,1) +gg.createAndDisplayGO(id_sphere) +gg.setDisplayMode(id_sphere,1) +gg.createAndDisplayGO(id_fuse1) +gg.setDisplayMode(id_fuse1,1) +gg.createAndDisplayGO(id_fuse2) +gg.setDisplayMode(id_fuse2,1) diff --git a/doc/salome/examples/boolean_operations_ex02.py b/doc/salome/examples/boolean_operations_ex02.py new file mode 100644 index 000000000..b7e73b727 --- /dev/null +++ b/doc/salome/examples/boolean_operations_ex02.py @@ -0,0 +1,28 @@ +# Common + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex(25, 55, 0) +p2 = geompy.MakeVertex( 0, 0, 0) +v = geompy.MakeVector(p1, p2) + +# create a cylinder +height = 35 +radius1 = 20 +cylinder = geompy.MakeCylinder(p1, v, radius1, height) + +# create a sphere +sphere = geompy.MakeSphereR(40) + +# make common +common = geompy.MakeCommon(cylinder, sphere) + +# add objects in the study +id_common = geompy.addToStudy(common, "Common") + +# display the results +gg.createAndDisplayGO(id_common) +gg.setDisplayMode(id_common,1) diff --git a/doc/salome/examples/boolean_operations_ex03.py b/doc/salome/examples/boolean_operations_ex03.py new file mode 100644 index 000000000..44c597405 --- /dev/null +++ b/doc/salome/examples/boolean_operations_ex03.py @@ -0,0 +1,28 @@ +# Cut + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex(25, 55, 0) +p2 = geompy.MakeVertex( 0, 0, 0) +v = geompy.MakeVector(p1, p2) + +# create a cylinder +height = 35 +radius1 = 20 +cylinder = geompy.MakeCylinder(p1, v, radius1, height) + +# create a sphere +sphere = geompy.MakeSphereR(40) + +#cut +cut = geompy.MakeCut(cylinder, sphere) + +# add objects in the study +id_cut = geompy.addToStudy(cut, "Cut") + +# display the results +gg.createAndDisplayGO(id_cut) +gg.setDisplayMode(id_cut,1) diff --git a/doc/salome/examples/boolean_operations_ex04.py b/doc/salome/examples/boolean_operations_ex04.py new file mode 100644 index 000000000..9472f7aa1 --- /dev/null +++ b/doc/salome/examples/boolean_operations_ex04.py @@ -0,0 +1,28 @@ +# Section + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex(25, 55, 0) +p2 = geompy.MakeVertex( 0, 0, 0) +v = geompy.MakeVector(p1, p2) + +# create a cylinder +height = 35 +radius1 = 20 +cylinder = geompy.MakeCylinder(p1, v, radius1, height) + +# create a sphere +sphere = geompy.MakeSphereR(40) + +# make a section +section = geompy.MakeSection(cylinder, sphere) + +# add objects in the study +id_section = geompy.addToStudy(section, "Section") + +# display the results +gg.createAndDisplayGO(id_section) +gg.setDisplayMode(id_section,1) diff --git a/doc/salome/examples/bounding_box.py b/doc/salome/examples/bounding_box.py new file mode 100644 index 000000000..d6480aeac --- /dev/null +++ b/doc/salome/examples/bounding_box.py @@ -0,0 +1,17 @@ +# Bounding Box + +import geompy + +# create a box +box = geompy.MakeBoxDXDYDZ(100,30,100) + +bb = geompy.BoundingBox(box) +print "\nBounding Box of box 100x30x100:" +print " Xmin = ", bb[0], ", Xmax = ", bb[1] +print " Ymin = ", bb[2], ", Ymax = ", bb[3] +print " Zmin = ", bb[4], ", Zmax = ", bb[5] + +aBB = geompy.MakeBoundingBox(box) + +geompy.addToStudy(box, "box 100x30x100") +geompy.addToStudy(aBB, "Bounding box of box 100x30x100") diff --git a/doc/salome/examples/building_by_blocks_ex01.py b/doc/salome/examples/building_by_blocks_ex01.py new file mode 100644 index 000000000..16b02d75b --- /dev/null +++ b/doc/salome/examples/building_by_blocks_ex01.py @@ -0,0 +1,55 @@ +# Quadrangle Face + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p1 = geompy.MakeVertex( 0., 0., 0.) +p2 = geompy.MakeVertex(150., 30., 0.) +p3 = geompy.MakeVertex( 0., 120., 50.) +p4 = geompy.MakeVertex( 0., 40., 70.) + +# create edges +edge1 = geompy.MakeEdge(p1, p2) +edge2 = geompy.MakeEdge(p2, p3) +edge3 = geompy.MakeEdge(p3, p4) +edge4 = geompy.MakeEdge(p4, p1) + +# create a quadrangle face from four edges +qface1 = geompy.MakeQuad(edge1, edge2, edge3, edge4) + +# create a quadrangle face from two edges +qface2 = geompy.MakeQuad2Edges(edge1, edge3) + +# create a quadrangle from four points in its corners +qface3 = geompy.MakeQuad4Vertices(p1, p2, p3, p4) + +# add objects in the study +id_p1 = geompy.addToStudy(p1,"Point1") +id_p2 = geompy.addToStudy(p2,"Point2") +id_p3 = geompy.addToStudy(p3,"Point3") +id_p4 = geompy.addToStudy(p4,"Point4") +id_edge1 = geompy.addToStudy(edge1,"Edge1") +id_edge2 = geompy.addToStudy(edge2,"Edge2") +id_edge3 = geompy.addToStudy(edge3,"Edge3") +id_edge4 = geompy.addToStudy(edge4,"Edge4") +id_qface1 = geompy.addToStudy(qface1,"Qface1") +id_qface2 = geompy.addToStudy(qface2,"Qface2") +id_qface3 = geompy.addToStudy(qface3,"Qface3") + +# display the vertices, the edges and the quadrangle faces +gg.createAndDisplayGO(id_p1) +gg.createAndDisplayGO(id_p2) +gg.createAndDisplayGO(id_p3) +gg.createAndDisplayGO(id_p4) +gg.createAndDisplayGO(id_edge1) +gg.createAndDisplayGO(id_edge2) +gg.createAndDisplayGO(id_edge3) +gg.createAndDisplayGO(id_edge4) +gg.createAndDisplayGO(id_qface1) +gg.setDisplayMode(id_qface1,1) +gg.createAndDisplayGO(id_qface2) +gg.setDisplayMode(id_qface2,1) +gg.createAndDisplayGO(id_qface3) +gg.setDisplayMode(id_qface3,1) diff --git a/doc/salome/examples/building_by_blocks_ex02.py b/doc/salome/examples/building_by_blocks_ex02.py new file mode 100644 index 000000000..ed81f4233 --- /dev/null +++ b/doc/salome/examples/building_by_blocks_ex02.py @@ -0,0 +1,54 @@ +# Hexagonal Solid + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p0 = geompy.MakeVertex( 0., 0., 0.) +p1 = geompy.MakeVertex( 0., 0., 40.) +p2 = geompy.MakeVertex( 70., -15., 0.) +p3 = geompy.MakeVertex( 70., -15., 70.) + +p4 = geompy.MakeVertex( 0., 70., 0.) +p5 = geompy.MakeVertex( 0., 70., 40.) +p6 = geompy.MakeVertex( 70., 70., 0.) +p7 = geompy.MakeVertex( 70., 70., 70.) + +p8 = geompy.MakeVertex( 0., -50., 0.) +p9 = geompy.MakeVertex( 0., -50., 40.) +p10 = geompy.MakeVertex( 70., -35., 0.) +p11 = geompy.MakeVertex( 70., -35., 70.) + +# create faces +qface1 = geompy.MakeQuad4Vertices(p0, p1, p2, p3) +qface2 = geompy.MakeQuad4Vertices(p4, p5, p6, p7) +qface3 = geompy.MakeQuad4Vertices(p0, p1, p4, p5) +qface4 = geompy.MakeQuad4Vertices(p2, p3, p6, p7) +qface5 = geompy.MakeQuad4Vertices(p0, p2, p4, p6) +qface6 = geompy.MakeQuad4Vertices(p1, p3, p5, p7) +qface7 = geompy.MakeQuad4Vertices(p8, p9, p10, p11) + +# create a hexahedral solid between two given faces +solid1 = geompy.MakeHexa2Faces(qface1, qface7) + +# create a hexahedral solid, bounded by six given faces +solid2 = geompy.MakeHexa(qface1, qface2, qface3, qface4, qface5, qface6) + +# add objects in the study +geompy.addToStudy(qface1,"qface1") +geompy.addToStudy(qface2,"qface2") +geompy.addToStudy(qface3,"qface3") +geompy.addToStudy(qface4,"qface4") +geompy.addToStudy(qface5,"qface5") +geompy.addToStudy(qface6,"qface6") +geompy.addToStudy(qface7,"qface7") + +id_solid1 = geompy.addToStudy(solid1,"Solid1") +id_solid2 = geompy.addToStudy(solid2,"Solid2") + +# display solids +gg.createAndDisplayGO(id_solid1) +gg.setDisplayMode(id_solid1, 1) +gg.createAndDisplayGO(id_solid2) +gg.setDisplayMode(id_solid2, 1) diff --git a/doc/salome/examples/center_of_mass.py b/doc/salome/examples/center_of_mass.py new file mode 100644 index 000000000..acf5962ff --- /dev/null +++ b/doc/salome/examples/center_of_mass.py @@ -0,0 +1,19 @@ +# Center of masses + +import geompy +import math + +# create a box +box = geompy.MakeBoxDXDYDZ(100,30,100) +cm = geompy.MakeCDG(box) +if cm is None: + raise RuntimeError, "MakeCDG(box) failed" +else: + print "\nCentre of gravity of box has been successfully obtained:" + coords = geompy.PointCoordinates(cm) + print "(", coords[0], ", ", coords[1], ", ", coords[2], ")" + dx = math.sqrt((coords[0] - 50)*(coords[0] - 50)) + dy = math.sqrt((coords[1] - 15)*(coords[1] - 15)) + dz = math.sqrt((coords[2] - 50)*(coords[2] - 50)) + if dx > 1e-7 or dy > 1e-7 or dz > 1e-7: + print "But must be (50, 15, 50)" diff --git a/doc/salome/examples/check_compound_of_blocks.py b/doc/salome/examples/check_compound_of_blocks.py new file mode 100644 index 000000000..2f1ba9850 --- /dev/null +++ b/doc/salome/examples/check_compound_of_blocks.py @@ -0,0 +1,21 @@ +# Check Compound of Blocks + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create boxes +box1 = geompy.MakeBox(0,0,0,100,50,100) +box2 = geompy.MakeBox(100,0,0,250,50,100) + +# make a compound +compound = geompy.MakeCompound([box1, box2]) + +# glue the faces of the compound +tolerance = 1e-5 +glue = geompy.MakeGlueFaces(compound, tolerance) +IsValid = geompy.CheckCompoundOfBlocks(glue) +if IsValid == 0: + raise RuntimeError, "Invalid compound created" +else: + print "\nCompound is valid" diff --git a/doc/salome/examples/check_self_intersections.py b/doc/salome/examples/check_self_intersections.py new file mode 100644 index 000000000..44c55d257 --- /dev/null +++ b/doc/salome/examples/check_self_intersections.py @@ -0,0 +1,11 @@ +# Detect Self-intersections + +import geompy + +# create a box +box = geompy.MakeBoxDXDYDZ(100,30,100) +IsValid = geompy.CheckSelfIntersections(box) +if IsValid == 0: + raise RuntimeError, "Box with self-intersections created" +else: + print "\nBox is valid" diff --git a/doc/salome/examples/check_shape.py b/doc/salome/examples/check_shape.py new file mode 100644 index 000000000..b708494b3 --- /dev/null +++ b/doc/salome/examples/check_shape.py @@ -0,0 +1,11 @@ +# Check Shape + +import geompy + +# create a box +box = geompy.MakeBoxDXDYDZ(100,30,100) +IsValid = geompy.CheckShape(box) +if IsValid == 0: + raise RuntimeError, "Invalid box created" +else: + print "\nBox is valid" diff --git a/doc/salome/examples/complex_objs_ex01.py b/doc/salome/examples/complex_objs_ex01.py new file mode 100644 index 000000000..a5cf102c8 --- /dev/null +++ b/doc/salome/examples/complex_objs_ex01.py @@ -0,0 +1,61 @@ +# Creation of a Prism + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex( 0., 0., 0.) +p2 = geompy.MakeVertex( 100., 0., 0.) +p3 = geompy.MakeVertex( 100., 100., 0.) +p4 = geompy.MakeVertex( 0., 100., 0.) +p5 = geompy.MakeVertex( 0., 0., 60.) +p6 = geompy.MakeVertex(-100., 0., 0.) +p7 = geompy.MakeVertex(-100.,-100., 0.) +p8 = geompy.MakeVertex( 0.,-100., 0.) + +# create a vector from the given components +vector = geompy.MakeVectorDXDYDZ(50., 50., 50.) + +#create vectors from two points +vector1_arc1 = geompy.MakeVector(p1, p2) +vector2_arc1 = geompy.MakeVector(p1, p4) +vector1_arc2 = geompy.MakeVector(p1, p6) +vector2_arc2 = geompy.MakeVector(p1, p8) + +# create arcs from three points +arc1 = geompy.MakeArc(p2, p3, p4) +arc2 = geompy.MakeArc(p6, p7, p8) + +# create wires +wire1 = geompy.MakeWire([vector1_arc1, arc1, vector2_arc1]) +wire2 = geompy.MakeWire([vector1_arc2, arc2, vector2_arc2]) + +# create faces +isPlanarWanted = 1 +face1 = geompy.MakeFace(wire1, isPlanarWanted) +face2 = geompy.MakeFace(wire2, isPlanarWanted) + +# create prisms +prism1 = geompy.MakePrism(face2, p1, p5) +prism2 = geompy.MakePrismVecH(face1, vector, 50) +prism3 = geompy.MakePrismVecH2Ways(face1, vector, 50) + +# add objects in the study +id_face1 = geompy.addToStudy(face1,"Face1") +id_face2 = geompy.addToStudy(face2,"Face2") +id_prism1 = geompy.addToStudy(prism1,"Prism1") +id_prism2 = geompy.addToStudy(prism2,"Prism2") +id_prism3 = geompy.addToStudy(prism3,"Prism3") + +# display cylinders +gg.createAndDisplayGO(id_face1) +gg.setDisplayMode(id_face1,1) +gg.createAndDisplayGO(id_face2) +gg.setDisplayMode(id_face2,1) +gg.createAndDisplayGO(id_prism1) +gg.setDisplayMode(id_prism1,1) +gg.createAndDisplayGO(id_prism2) +gg.setDisplayMode(id_prism2,1) +gg.createAndDisplayGO(id_prism3) +gg.setDisplayMode(id_prism3,1) diff --git a/doc/salome/examples/complex_objs_ex02.py b/doc/salome/examples/complex_objs_ex02.py new file mode 100644 index 000000000..e096551fd --- /dev/null +++ b/doc/salome/examples/complex_objs_ex02.py @@ -0,0 +1,34 @@ +# Creation of a Revolution + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex( 10., 10., 10.) +p2 = geompy.MakeVertex( 15., 15., 50.) +p3 = geompy.MakeVertex( 40., 40., 0.) + +#create vectors from two points +vector1 = geompy.MakeVector(p1, p2) +vector2 = geompy.MakeVector(p1, p3) + +# create a vector from the given components +vector3 = geompy.MakeVectorDXDYDZ(-20., -20., 100.) + +# create a wire +wire = geompy.MakeWire([vector1, vector2]) + +# create a revolution +revolution = geompy.MakeRevolution(wire, vector3, 2.3) + +# add objects in the study +id_vector3 = geompy.addToStudy(vector3,"Axis") +id_wire = geompy.addToStudy(wire,"Wire") +id_revolution = geompy.addToStudy(revolution,"Revolution") + +# display the vector, the wire and the revolution +gg.createAndDisplayGO(id_vector3) +gg.createAndDisplayGO(id_wire) +gg.createAndDisplayGO(id_revolution) +gg.setDisplayMode(id_revolution,1) diff --git a/doc/salome/examples/complex_objs_ex03.py b/doc/salome/examples/complex_objs_ex03.py new file mode 100644 index 000000000..ec7767b2a --- /dev/null +++ b/doc/salome/examples/complex_objs_ex03.py @@ -0,0 +1,39 @@ +# Creation of a Filling + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +mindeg = 2 +maxdeg = 5 +tol3d = 0.0001 +tol2d = 0.0001 +nbiter = 5 + +# create a vertex and a vector +p1 = geompy.MakeVertex( -30., -30., 50.) +p2 = geompy.MakeVertex( -60., -60., 30.) +p3 = geompy.MakeVertex( -30., -30., 10.) + +# create an arc from three points +arc = geompy.MakeArc(p1, p2, p3) +ShapeListCompound = [] +i = 0 +while i <= 3 : + S = geompy.MakeTranslation(arc, i * 50., 0., 0.) + ShapeListCompound.append(S) + i = i + 1 + +compound = geompy.MakeCompound(ShapeListCompound) + +# create a filling +filling = geompy.MakeFilling(compound, mindeg, maxdeg, tol3d, tol2d, nbiter) + +# add objects in the study +id_compound = geompy.addToStudy(compound,"Compound") +id_filling = geompy.addToStudy(filling,"Filling") + +# display the compound and the filling +gg.createAndDisplayGO(id_compound) +gg.createAndDisplayGO(id_filling) +gg.setDisplayMode(id_filling,1) diff --git a/doc/salome/examples/complex_objs_ex04.py b/doc/salome/examples/complex_objs_ex04.py new file mode 100644 index 000000000..72af08f29 --- /dev/null +++ b/doc/salome/examples/complex_objs_ex04.py @@ -0,0 +1,38 @@ +# Creation of a Pipe + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p0 = geompy.MakeVertex(0. , 0. , 0. ) +px = geompy.MakeVertex(100., 0. , 0. ) +py = geompy.MakeVertex(0. , 100., 0. ) +pz = geompy.MakeVertex(0. , 0. , 100.) +pxyz = geompy.MakeVertex(100., 100., 100.) + +# create a vector from two points +vxy = geompy.MakeVector(px, py) + +# create an arc from three points +arc = geompy.MakeArc(py, pz, px) + +# create a wire +wire = geompy.MakeWire([vxy, arc]) + +# create an edge +edge = geompy.MakeEdge(p0, pxyz) + +# create a pipe +pipe = geompy.MakePipe(wire, edge) + +# add objects in the study +id_wire = geompy.addToStudy(wire,"Wire") +id_edge = geompy.addToStudy(edge,"Edge") +id_pipe = geompy.addToStudy(pipe,"Pipe") + +# display the wire, the edge (path) and the pipe +gg.createAndDisplayGO(id_wire) +gg.createAndDisplayGO(id_edge) +gg.createAndDisplayGO(id_pipe) +gg.setDisplayMode(id_pipe,1) diff --git a/doc/salome/examples/complex_objs_ex05.py b/doc/salome/examples/complex_objs_ex05.py new file mode 100644 index 000000000..724810c58 --- /dev/null +++ b/doc/salome/examples/complex_objs_ex05.py @@ -0,0 +1,32 @@ +# Creation of a PipeWithDifferentSections + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +Wire_1 = geompy.MakeSketcher("Sketcher:F 0 0:TT 100 0:R 0:C 100 90:T 0 200", [0, 0, 0, 0, 0, 1, 1, 0, -0]) +edges = geompy.SubShapeAll(Wire_1, geompy.ShapeType["EDGE"]) +vertices = geompy.SubShapeAll(Wire_1, geompy.ShapeType["VERTEX"]) + +# create sections +circles=[] +circles.append(geompy.MakeCircle(vertices[0], edges[0], 20)) +circles.append(geompy.MakeCircle(vertices[1], edges[0], 40)) +circles.append(geompy.MakeCircle(vertices[2], edges[2], 30)) +circles.append(geompy.MakeCircle(vertices[3], edges[2], 20)) + +# create pipe +Pipe = geompy.MakePipeWithDifferentSections(circles, vertices, Wire_1, 0, 0) + +# add objects in the study +geompy.addToStudy(circles[0], "circles1") +geompy.addToStudy(circles[1], "circles2") +geompy.addToStudy(circles[2], "circles3") +geompy.addToStudy(circles[3], "circles4") +id_wire = geompy.addToStudy(Wire_1, "Path") +id_pipe = geompy.addToStudy(Pipe, "Pipe") + +# display the wire(path) and the pipe +gg.createAndDisplayGO(id_wire) +gg.createAndDisplayGO(id_pipe) +gg.setDisplayMode(id_pipe,1) diff --git a/doc/salome/examples/complex_objs_ex06.py b/doc/salome/examples/complex_objs_ex06.py new file mode 100644 index 000000000..a836b35fc --- /dev/null +++ b/doc/salome/examples/complex_objs_ex06.py @@ -0,0 +1,192 @@ +# Creation of a PipeWithShellSections + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create path +WirePath = geompy.MakeSketcher("Sketcher:F 0 0:TT 100 0:R 0:C 100 90:T 0 200", [0, 0, 0, 0, 0, 1, 1, 0, -0]) + +#======================================================= +# Create shell sections +#======================================================= +ps = [Vertex_1,Vertex_2,Vertex_3,Vertex_4] +theLocations = [Vertex_1, Vertex_2, Vertex_3, Vertex_4] +VC = geompy.MakeCompound(theLocations) +geompy.addToStudy(VC,"VC") +vs = [Edge_1,Edge_1,Edge_3,Edge_3] +hs = [20,40,30,20] +shells = [] +subbases = [] + +# 1 section +c0 = geompy.PointCoordinates(ps[0]) +c1 = geompy.PointCoordinates(ps[1]) +nx = c1[0] - c0[0] +ny = c1[1] - c0[1] +nz = c1[2] - c0[2] + +faces = [] +f1 = geompy.MakeSketcher("Sketcher:F 0 0:TT 20 0:TT 20 20:TT 0 20:WF", + [c0[0], c0[1], c0[2], nx, ny, nz, 0, 0, 1]) +f2 = geompy.MakeSketcher("Sketcher:F 0 0:TT 0 20:TT -20 20:TT -20 0:WF", + [c0[0], c0[1], c0[2], nx, ny, nz, 0, 0, 1]) +f3 = geompy.MakeSketcher("Sketcher:F 0 0:TT -20 0:TT -20 -20:TT 0 -20:WF", + [c0[0], c0[1], c0[2], nx, ny, nz, 0, 0, 1]) +f4 = geompy.MakeSketcher("Sketcher:F 0 0:TT 0 -20:TT 20 -20:TT 20 0:WF", + [c0[0], c0[1], c0[2], nx, ny, nz, 0, 0, 1]) +faces.append(f1) +faces.append(f2) +faces.append(f3) +faces.append(f4) +shell = geompy.MakeSewing(faces,1.e-6) +shells.append(shell) +faces = geompy.SubShapeAllSortedCentres(shell, geompy.ShapeType["FACE"]) +subbases.append(faces[0]) + +# 2 section +faces = [] + +w = geompy.MakeSketcher("Sketcher:F 20 20:TT 0 20:TT 0 0:TT 20 0", + [c1[0], c1[1], c1[2], nx, ny, nz, 0, 0, 1]) +[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) +arc = MakeArc(w,3,-1) +w = geompy.MakeWire([e1,e2,e3,arc]) +f1 = geompy.MakeFace(w,1) + +w = geompy.MakeSketcher("Sketcher:F -20 0:TT 0 0:TT 0 20:TT -20 20", + [c1[0], c1[1], c1[2], nx, ny, nz, 0, 0, 1]) +[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) +arc = MakeArc(w,3,-1) +w = geompy.MakeWire([e1,e2,e3,arc]) +f2 = geompy.MakeFace(w,1) + +w = geompy.MakeSketcher("Sketcher:F 20 0:TT 0 0:TT 0 -20:TT 20 -20", + [c1[0], c1[1], c1[2], nx, ny, nz, 0, 0, 1]) +[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) +arc = MakeArc(w,3,-1) +w = geompy.MakeWire([e1,e2,e3,arc]) +f3 = geompy.MakeFace(w,1) + +w = geompy.MakeSketcher("Sketcher:F -20 -20:TT 0 -20:TT 0 0:TT -20 0", + [c1[0], c1[1], c1[2], nx, ny, nz, 0, 0, 1]) +[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) +arc = MakeArc(w,3,-1) +w = geompy.MakeWire([e1,e2,e3,arc]) +f4 = geompy.MakeFace(w,1) + +faces.append(f1) +faces.append(f2) +faces.append(f3) +faces.append(f4) +shell = geompy.MakeSewing(faces,1.e-6) +shells.append(shell) +faces = geompy.SubShapeAllSortedCentres(shell, geompy.ShapeType["FACE"]) +subbases.append(faces[0]) + +# 3 section +faces = [] +c2 = geompy.PointCoordinates(ps[2]) +c3 = geompy.PointCoordinates(ps[3]) +nx = c3[0] - c2[0] +ny = c3[1] - c2[1] +nz = c3[2] - c2[2] + +w = geompy.MakeSketcher("Sketcher:F 20 20:TT 0 20:TT 0 0:TT 20 0", + [c2[0], c2[1], c2[2], nx, ny, nz, 0, 0, 1]) +[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) +arc = MakeArc(w,3,1) +w = geompy.MakeWire([e1,e2,e3,arc]) +f1 = geompy.MakeFace(w,1) + +w = geompy.MakeSketcher("Sketcher:F -20 0:TT 0 0:TT 0 20:TT -20 20", + [c2[0], c2[1], c2[2], nx, ny, nz, 0, 0, 1]) +[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) +arc = MakeArc(w,3,1) +w = geompy.MakeWire([e1,e2,e3,arc]) +f2 = geompy.MakeFace(w,1) + +w = geompy.MakeSketcher("Sketcher:F 20 0:TT 0 0:TT 0 -20:TT 20 -20", + [c2[0], c2[1], c2[2], nx, ny, nz, 0, 0, 1]) +[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) +arc = MakeArc(w,3,1) +w = geompy.MakeWire([e1,e2,e3,arc]) +f3 = geompy.MakeFace(w,1) + +w = geompy.MakeSketcher("Sketcher:F -20 -20:TT 0 -20:TT 0 0:TT -20 0", + [c2[0], c2[1], c2[2], nx, ny, nz, 0, 0, 1]) +[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) +arc = MakeArc(w,3,1) +w = geompy.MakeWire([e1,e2,e3,arc]) +f4 = geompy.MakeFace(w,1) + +faces.append(f1) +faces.append(f2) +faces.append(f3) +faces.append(f4) +shell = geompy.MakeSewing(faces,1.e-6) +shells.append(shell) +faces = geompy.SubShapeAllSortedCentres(shell, geompy.ShapeType["FACE"]) +subbases.append(faces[2]) + +# 4 section +faces = [] + +kk = 4 +dx = c3[0] - nx/kk +dy = c3[1] - ny/kk +dz = c3[2] - nz/kk +rad = math.sqrt(nx*nx+ny*ny+nz*nz) +vc = geompy.MakeVertex(dx,dy,dz) +sph = geompy.MakeSpherePntR(vc,rad/kk) +shellsph = geompy.SubShapeAll(sph, geompy.ShapeType["SHELL"]) + +fs = [] +vec = geompy.MakeVectorDXDYDZ(0,0,1) +ff = geompy.MakePlane(ps[3],vec,40) +fs.append(ff) +vp = geompy.MakeVertex(c3[0],c3[1],c3[2]+20) +ff = geompy.MakePlane(vp,vec,40) +fs.append(ff) +vp = geompy.MakeVertex(c3[0],c3[1],c3[2]-20) +ff = geompy.MakePlane(vp,vec,40) +fs.append(ff) +vec = geompy.MakeVectorDXDYDZ(1,0,0) +ff = geompy.MakePlane(ps[3],vec,40) +fs.append(ff) +vp = geompy.MakeVertex(c3[0]+20,c3[1],c3[2]) +ff = geompy.MakePlane(vp,vec,40) +fs.append(ff) +vp = geompy.MakeVertex(c3[0]-20,c3[1],c3[2]) +ff = geompy.MakePlane(vp,vec,40) +fs.append(ff) +aPartition = geompy.MakePartition(shellsph,fs) +fs = geompy.SubShapeAllSortedCentres(aPartition, geompy.ShapeType["FACE"]) + +faces.append(fs[0]) +faces.append(fs[1]) +faces.append(fs[2]) +faces.append(fs[3]) +shell = geompy.MakeSewing(faces,1.e-6) +shells.append(shell) +faces = geompy.SubShapeAllSortedCentres(shell, geompy.ShapeType["FACE"]) + + +#=========================================================== +# Create Pipe +#=========================================================== +subbases = [] +Pipe = geompy.MakePipeWithShellSections(shells, subbases, theLocations, WirePath, + theWithContact=0, theWithCorrection=0) + +# add objects in the study +resc = geompy.MakeCompound(shells) +id_sec = geompy.addToStudy(resc,"sections") +id_wire = geompy.addToStudy(WirePath,"WirePath") +id_pipe = geompy.addToStudy(Pipe, "Pipe") + +# display the wire(path), sections and the pipe +gg.createAndDisplayGO(id_wire) +gg.createAndDisplayGO(id_sec) +gg.createAndDisplayGO(id_pipe) +gg.setDisplayMode(id_pipe,1) diff --git a/doc/salome/examples/complex_objs_ex07.py b/doc/salome/examples/complex_objs_ex07.py new file mode 100644 index 000000000..1b37a2e39 --- /dev/null +++ b/doc/salome/examples/complex_objs_ex07.py @@ -0,0 +1,116 @@ +# Creation of a PipeShellsWithoutPath + +import geompy +import math +import salome +gg = salome.ImportComponentGUI("GEOM") + +# Add a section based on quadrangles +# ---------------------------------- +def section(s, p1, p2=None, p3=None, p4=None): + if p2==None: + q = p1 + else: + q = geompy.MakeQuad4Vertices(p1, p2, p3, p4) + pass + s.append(q) + publish(q, "section") + return q + + +# find distance between two points +# ------------------------------- +def Dist(p1,p2): + c1 = geompy.PointCoordinates(p1) + c2 = geompy.PointCoordinates(p2) + return math.sqrt( (c2[0]-c1[0])*(c2[0]-c1[0]) + + (c2[1]-c1[1])*(c2[1]-c1[1]) + + (c2[2]-c1[2])*(c2[2]-c1[2]) ) + + +# return middle point +# ------------------------------- +def MiddleVert(p1,p2): + c1 = geompy.PointCoordinates(p1) + c2 = geompy.PointCoordinates(p2) + return geompy.MakeVertex( (c2[0]+c1[0])/2, (c2[1]+c1[1])/2, (c2[2]+c1[2])/2 ) + + +# Complex section +# result - 16 quads from lines +# pnt - point from path +# vec - direction from path +def MakeComplexSect(pnt,vec,rmax,rmin,nb): + dang = 1.0/nb/2 + cmax = geompy.MakeCircle(pnt,vec,rmax) + cmin = geompy.MakeCircle(pnt,vec,rmin) + faces = [] + for i in range(0,2*nb,2): + p1 = geompy.MakeVertexOnCurve(cmin,dang*i) + p2 = geompy.MakeVertexOnCurve(cmax,dang*(i+1)) + p3 = geompy.MakeVertexOnCurve(cmin,dang*(i+2)) + f = geompy.MakeQuad4Vertices(pnt,p1,p2,p3) + faces.append(f) + pass + shell = geompy.MakeSewing(faces,1.e-6) + return shell + + +#======================================================= +# Create simple path and recieve points +# for section creation +#======================================================= +WirePath = geompy.MakeSketcher("Sketcher:F 0 0:T 60 0:T 40 0:R 0:C 100 90:", + [0, 0, 0, 0, 0, 1, 1, 0, 0]) +vs = geompy.SubShapeAll(WirePath, geompy.ShapeType["VERTEX"]) + +#======================================================= +# Create shell sections +#======================================================= +shells = [] +subbases = [] +locs = [] + +# 1 section +shell = MakeComplexSect(vs[0], geompy.MakeVectorDXDYDZ(1,0,0), 60, 40, 16) +shells.append(shell) +vs1 = geompy.SubShapeAllSortedCentres(shell,geompy.ShapeType["VERTEX"]) +locs.append(vs1[17]) + +# 2 section +shell = MakeComplexSect(vs[1], geompy.MakeVectorDXDYDZ(1,0,0), 80, 30, 16) +shells.append(shell) +vs2 = geompy.SubShapeAllSortedCentres(shell,geompy.ShapeType["VERTEX"]) +locs.append(vs2[17]) + +# 3 section +shell = MakeComplexSect(vs[2], geompy.MakeVectorDXDYDZ(1,0,0), 60, 40, 16) +shells.append(shell) +vs3 = geompy.SubShapeAllSortedCentres(shell,geompy.ShapeType["VERTEX"]) +locs.append(vs3[17]) + +# 4 section +shell = MakeComplexSect(vs[3], geompy.MakeVectorDXDYDZ(0,1,0), 40, 35, 16) +shells.append(shell) +vs4 = geompy.SubShapeAllSortedCentres(shell,geompy.ShapeType["VERTEX"]) +locs.append(vs4[17]) + + +#=========================================================== +# Create Pipe +#=========================================================== + +Pipe = geompy.MakePipeShellsWithoutPath(shells,locs) + +# add objects in the study +resc = geompy.MakeCompound(shells) +id_sec = geompy.addToStudy(resc,"sections") +resl = geompy.MakeCompound(locs) +id_loc = geompy.addToStudy(resl,"locations") +id_pipe = geompy.addToStudy(Pipe, "Pipe") + +# display the sections, locations and pipe +gg.createAndDisplayGO(id_sec) +gg.createAndDisplayGO(id_loc) +gg.createAndDisplayGO(id_pipe) +gg.setDisplayMode(id_pipe,1) diff --git a/doc/salome/examples/complex_objs_ex08.py b/doc/salome/examples/complex_objs_ex08.py new file mode 100644 index 000000000..4777e071b --- /dev/null +++ b/doc/salome/examples/complex_objs_ex08.py @@ -0,0 +1,76 @@ +# Creation of a PipeBiNormalAlongVector + +def MakeHelix(radius, height, rotation, direction): + # - create a helix - + radius = 1.0 * radius + height = 1.0 * height + rotation = 1.0 * rotation + if direction > 0: + direction = +1 + else: + direction = -1 + pass + from math import sqrt + length_z = height + length_xy = radius*rotation + length = sqrt(length_z*length_z + length_xy*length_xy) + import geompy + nb_steps = 1 + epsilon = 1.0e-6 + while 1: + z_step = height / nb_steps + angle_step = rotation / nb_steps + z = 0.0 + angle = 0.0 + helix_points = [] + for n in range(nb_steps+1): + from math import cos, sin + x = radius * cos(angle) + y = radius * sin(angle) + p = geompy.MakeVertex(x, y, z) + helix_points.append( p ) + z += z_step + angle += direction * angle_step + pass + helix = geompy.MakeInterpol(helix_points) + length_test = geompy.BasicProperties(helix)[0] + prec = abs(length-length_test)/length + # print nb_steps, length_test, prec + if prec < epsilon: + break + nb_steps *= 2 + pass + return helix + +def MakeSpring(radius, height, rotation, direction, thread_radius, base_rotation=0.0): + # - create a pipe - + thread_radius = 1.0 * thread_radius + # create a helix + helix = MakeHelix(radius, height, rotation, direction) + # base in the (Ox, Oz) plane + import geompy + p0 = geompy.MakeVertex(radius-3*thread_radius, 0.0, -thread_radius) + p1 = geompy.MakeVertex(radius+3*thread_radius, 0.0, -thread_radius) + p2 = geompy.MakeVertex(radius+3*thread_radius, 0.0, +thread_radius) + p3 = geompy.MakeVertex(radius-3*thread_radius, 0.0, +thread_radius) + e0 = geompy.MakeEdge(p0, p1) + e1 = geompy.MakeEdge(p1, p2) + e2 = geompy.MakeEdge(p2, p3) + e3 = geompy.MakeEdge(p3, p0) + w = geompy.MakeWire([e0, e1, e2, e3]) + # create a base face + base = geompy.MakeFace(w, True) + # create a binormal vector + binormal = geompy.MakeVectorDXDYDZ(0.0, 0.0, 10.0) + # create a pipe + spring = geompy.MakePipeBiNormalAlongVector(base, helix, binormal) + # Publish in the study + geompy.addToStudy(base, "base") + geompy.addToStudy(helix, "helix") + geompy.addToStudy(binormal, "binormal") + geompy.addToStudy(spring, "spring") + return spring + +from math import pi + +spring = MakeSpring(50, 100, 2*pi, 1, 5, pi/2) diff --git a/doc/salome/examples/complex_objs_ex09.py b/doc/salome/examples/complex_objs_ex09.py new file mode 100644 index 000000000..55c347a1f --- /dev/null +++ b/doc/salome/examples/complex_objs_ex09.py @@ -0,0 +1,43 @@ +# Creation of a Middle Path + +import salome +import geompy + +# Create a box +Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) + +# Get two opposite faces +[Face_1,Face_2] = geompy.SubShapes(Box_1, [31, 33]) + +# Get edges +Box_1_edge_12 = geompy.GetSubShape(Box_1, [12]) +Box_1_edge_22 = geompy.GetSubShape(Box_1, [22]) +Box_1_edge_25 = geompy.GetSubShape(Box_1, [25]) +Box_1_edge_29 = geompy.GetSubShape(Box_1, [29]) +Box_1_edge_8 = geompy.GetSubShape(Box_1, [8]) +Box_1_edge_18 = geompy.GetSubShape(Box_1, [18]) +Box_1_edge_26 = geompy.GetSubShape(Box_1, [26]) +Box_1_edge_30 = geompy.GetSubShape(Box_1, [30]) + +# These three calls to RestorePath return the same result +Path_1 = geompy.RestorePath(Box_1, Face_1, Face_2) +Path_2 = geompy.RestorePathEdges(Box_1, [Face_1], [Face_2]) +Path_3 = geompy.RestorePathEdges(Box_1, + [Box_1_edge_12, Box_1_edge_22, Box_1_edge_25, Box_1_edge_29], + [Box_1_edge_8, Box_1_edge_18, Box_1_edge_26, Box_1_edge_30]) + +# Publish created objects +geompy.addToStudy( Box_1, 'Box_1' ) +geompy.addToStudyInFather( Box_1, Face_1, 'Face_1' ) +geompy.addToStudyInFather( Box_1, Face_2, 'Face_2' ) +geompy.addToStudyInFather( Box_1, Box_1_edge_25, 'Box_1:edge_25' ) +geompy.addToStudyInFather( Box_1, Box_1_edge_22, 'Box_1:edge_22' ) +geompy.addToStudyInFather( Box_1, Box_1_edge_12, 'Box_1:edge_12' ) +geompy.addToStudyInFather( Box_1, Box_1_edge_29, 'Box_1:edge_29' ) +geompy.addToStudyInFather( Box_1, Box_1_edge_18, 'Box_1:edge_18' ) +geompy.addToStudyInFather( Box_1, Box_1_edge_26, 'Box_1:edge_26' ) +geompy.addToStudyInFather( Box_1, Box_1_edge_8, 'Box_1:edge_8' ) +geompy.addToStudyInFather( Box_1, Box_1_edge_30, 'Box_1:edge_30' ) +geompy.addToStudy( Path_1, 'Path_1' ) +geompy.addToStudy( Path_2, 'Path_2' ) +geompy.addToStudy( Path_3, 'Path_3' ) diff --git a/doc/salome/examples/complex_objs_ex10.py b/doc/salome/examples/complex_objs_ex10.py new file mode 100644 index 000000000..8a14455ef --- /dev/null +++ b/doc/salome/examples/complex_objs_ex10.py @@ -0,0 +1,24 @@ +# Creation of Tangent Plane On Face + +import salome +import geompy + +# Create Vertexes for curve +Vertex_1 = geompy.MakeVertex(0, 0, 0) +Vertex_2 = geompy.MakeVertex(0, 90, 30) +Vertex_3 = geompy.MakeVertex(100, 90, 0) +Vertex_4 = geompy.MakeVertex(-100, 90, 0) +# Create curve +Curve_1 = geompy.MakeInterpol([Vertex_4, Vertex_2, Vertex_3, Vertex_1]) +# Create Face by Extrusion of the Curve +Extrusion_1 = geompy.MakePrismDXDYDZ(Curve_1, 0, 30, -60) +# Make Tangent on this Extrusion (Face) +Tangent_1 = geompy.MakeTangentPlaneOnFace(Extrusion_1, 0.7, 0.5, 150) +# Publish in the study +geompy.addToStudy( Vertex_1, "Vertex_1" ) +geompy.addToStudy( Vertex_2, "Vertex_2" ) +geompy.addToStudy( Vertex_3, "Vertex_3" ) +geompy.addToStudy( Vertex_4, "Vertex_4" ) +geompy.addToStudy( Curve_1, "Curve_1" ) +geompy.addToStudy( Extrusion_1, "Extrusion_1" ) +geompy.addToStudy( Tangent_1, "Tangent_1" ) diff --git a/doc/salome/examples/free_boundaries.py b/doc/salome/examples/free_boundaries.py new file mode 100644 index 000000000..7582f79dc --- /dev/null +++ b/doc/salome/examples/free_boundaries.py @@ -0,0 +1,79 @@ +# Check Free Boundaries + +import os +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create boxes +box1 = geompy.MakeBox(0,0,0,100,50,100) +box2 = geompy.MakeBox(100,0,0,250,50,100) + +# make a compound +compound = geompy.MakeCompound([box1, box2]) + +# import from *.brep +ImportFromBREP = geompy.ImportBREP(os.getenv("DATA_DIR")+"/Shapes/Brep/flight_solid.brep") + +# get a face +faces = geompy.SubShapeAllSortedCentres(ImportFromBREP, geompy.ShapeType["FACE"]) + +# get the free boundary for face 32 +Res = geompy.GetFreeBoundary(faces[32]) +isSuccess = Res[0] +ClosedWires = Res[1] +OpenWires = Res[2] + +if isSuccess == 1 : + print "Checking free boudaries is OK." +else : + print "Checking free boudaries is KO!" +print "len(ClosedWires) = ", len(ClosedWires) + +i = 0 +for wire in ClosedWires : + wire_name = "Face 32 -> Close wires : WIRE %d"%(i+1) + geompy.addToStudy(ClosedWires[i], wire_name) + if i < len(ClosedWires) : + i = i+ 1 + +print "len(OpenWires) = ", len(OpenWires) + +i = 0 +for wire in OpenWires : + wire_name = "Face 32 -> Open wires : WIRE %d"%(i+1) + geompy.addToStudy(OpenWires[i], wire_name) + if i < len(OpenWires) : + i = i+ 1 + +# get the free boundary for face 41 +Res = geompy.GetFreeBoundary(faces[41]) +isSuccess = Res[0] +ClosedWires = Res[1] +OpenWires = Res[2] + +if isSuccess == 1 : + print "Checking free boudaries is OK." +else : + print "Checking free boudaries is KO!" +print "len(ClosedWires) = ", len(ClosedWires) + +i = 0 +for wire in ClosedWires : + wire_name = "Face 41 -> Close wires : WIRE %d"%(i+1) + geompy.addToStudy(ClosedWires[i], wire_name) + if i < len(ClosedWires) : + i = i+ 1 + +print "len(OpenWires) = ", len(OpenWires) + +i = 0 +for wire in OpenWires : + wire_name = "Face 41 -> Open wires : WIRE %d"%(i+1) + geompy.addToStudy(OpenWires[i], wire_name) + if i < len(OpenWires) : + i = i+ 1 + +# add the imported object to the study +id_ImportFromBREP = geompy.addToStudy(ImportFromBREP, "ImportFromBREP") +salome.sg.updateObjBrowser(1) diff --git a/doc/salome/examples/free_faces.py b/doc/salome/examples/free_faces.py new file mode 100644 index 000000000..16d705614 --- /dev/null +++ b/doc/salome/examples/free_faces.py @@ -0,0 +1,46 @@ +# Check Free Faces + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex(35, 35, 0) +p2 = geompy.MakeVertex(35, 35, 50) +v = geompy.MakeVector(p1, p2) + +# create a cylinder +cylinder = geompy.MakeCone(p1, v, 30, 20, 20) + +# create a cone +cone = geompy.MakeCone(p1, v, 70, 40, 60) + +# make cut +cut = geompy.MakeCut(cone, cylinder) + +# get faces as sub-shapes +faces = [] +faces = geompy.SubShapeAllSortedCentres(cut, geompy.ShapeType["FACE"]) +f_2 = geompy.GetSubShapeID(cut, faces[0]) + +# remove one face from the shape +cut_without_f_2 = geompy.SuppressFaces(cut, [f_2]) + +# suppress the specified wire +result = geompy.GetFreeFacesIDs(cut_without_f_2) +print "A number of free faces is ", len(result) + +# add objects in the study +all_faces = geompy.SubShapeAllSortedCentres(cut_without_f_2, geompy.ShapeType["FACE"]) +for face in all_faces : + sub_shape_id = geompy.GetSubShapeID(cut_without_f_2, face) + if result.count(sub_shape_id) > 0 : + face_name = "Free face %d"%(sub_shape_id) + geompy.addToStudy(face, face_name) + +# in this example all faces from cut_without_f_2 are free +id_cut_without_f_2 = geompy.addToStudy(cut_without_f_2, "Cut without f_2") + +# display the results +gg.createAndDisplayGO(id_cut_without_f_2) +gg.setDisplayMode(id_cut_without_f_2,1) diff --git a/doc/salome/examples/get_non_blocks.py b/doc/salome/examples/get_non_blocks.py new file mode 100644 index 000000000..267fa870a --- /dev/null +++ b/doc/salome/examples/get_non_blocks.py @@ -0,0 +1,26 @@ +# Get Non Blocks + +import geompy +import salome + +# create solids +box = geompy.MakeBoxDXDYDZ(100, 100, 100) +cyl = geompy.MakeCylinderRH(100, 200) + +geompy.addToStudy(box, 'box') +geompy.addToStudy(cyl, 'cyl') + +# make a compound +compound = geompy.MakeCompound([box, cyl]) +geompy.addToStudy(compound, 'compound') + +# explore the compound +pair = geompy.GetNonBlocks(compound) + +if pair[0] is not None: + geompy.addToStudyInFather(compound, pair[0], "GrNonBlocks") + pass + +if pair[1] is not None: + geompy.addToStudyInFather(compound, pair[1], "GrNonQuads") + pass diff --git a/doc/salome/examples/import_export.py b/doc/salome/examples/import_export.py new file mode 100644 index 000000000..ecde2442f --- /dev/null +++ b/doc/salome/examples/import_export.py @@ -0,0 +1,40 @@ +# Import/Export + +import geompy +import salome + +# Example of import from IGES using various formats + +# get a path to SAMPLES_SRC +import os +thePath = os.getenv("DATA_DIR") +# create filenames +theFileName1 = thePath + "/Shapes/Iges/boite-3Dipsos_m.igs" +theFileName2 = thePath + "/Shapes/Iges/boite-3Dipsos_mm.igs" +#print "thePath = ", thePath + +# get units from files +UnitName1 = geompy.GetIGESUnit(theFileName1) +UnitName2 = geompy.GetIGESUnit(theFileName2) +print "UnitName1 = ", UnitName1 +print "UnitName2 = ", UnitName2 + +# import shapes +Shape1 = geompy.ImportIGES(theFileName1) +Shape2 = geompy.ImportIGES(theFileName2) +Shape3 = geompy.ImportFile(theFileName2,"IGES_SCALE") +[Xmin1,Xmax1, Ymin1,Ymax1, Zmin1,Zmax1] = geompy.BoundingBox(Shape1) +[Xmin2,Xmax2, Ymin2,Ymax2, Zmin2,Zmax2] = geompy.BoundingBox(Shape2) +[Xmin3,Xmax3, Ymin3,Ymax3, Zmin3,Zmax3] = geompy.BoundingBox(Shape3) +geompy.addToStudy(Shape1, "3Dipsos_m") +geompy.addToStudy(Shape2, "3Dipsos_mm") +geompy.addToStudy(Shape3, "3Dipsos_mm_scaled") +d1 = (Xmax1-Xmin1)*(Xmax1-Xmin1) + (Ymax1-Ymin1)*(Ymax1-Ymin1) + (Zmax1-Zmin1)*(Zmax1-Zmin1) +d2 = (Xmax2-Xmin2)*(Xmax2-Xmin2) + (Ymax2-Ymin2)*(Ymax2-Ymin2) + (Zmax2-Zmin2)*(Zmax2-Zmin2) +d3 = (Xmax3-Xmin3)*(Xmax3-Xmin3) + (Ymax3-Ymin3)*(Ymax3-Ymin3) + (Zmax3-Zmin3)*(Zmax3-Zmin3) +import math +dd32 = math.sqrt(d3/d2) +dd12 = math.sqrt(d1/d2) +dd31 = math.sqrt(d3/d1) +# values dd31, dd12 and dd31 can be using for checking +print "dd32 = ",dd32," dd12 = ",dd12," dd31 = ",dd31 diff --git a/doc/salome/examples/inertia.py b/doc/salome/examples/inertia.py new file mode 100644 index 000000000..203a39436 --- /dev/null +++ b/doc/salome/examples/inertia.py @@ -0,0 +1,14 @@ +# Inertia + +import geompy +import math + +# create a box +box = geompy.MakeBoxDXDYDZ(100,30,100) +In = geompy.Inertia(box) +print "\nInertia matrix of box 100x30x100:" +print " (", In[0], ", ", In[1], ", ", In[2], ")" +print " (", In[3], ", ", In[4], ", ", In[5], ")" +print " (", In[6], ", ", In[7], ", ", In[8], ")" +print "Main moments of inertia of box 100x30x100:" +print " Ix = ", In[9], ", Iy = ", In[10], ", Iz = ", In[11] diff --git a/doc/salome/examples/min_distance.py b/doc/salome/examples/min_distance.py new file mode 100644 index 000000000..e6048bba2 --- /dev/null +++ b/doc/salome/examples/min_distance.py @@ -0,0 +1,49 @@ +# Minimal Distance + +import geompy + +# Create two curves with three closest points +Vertex_1 = geompy.MakeVertex(0, 0, 0) +Vertex_2 = geompy.MakeVertex(0, 70, 0) +Vertex_3 = geompy.MakeVertex(30, 100, 0) +Vertex_4 = geompy.MakeVertex(60, 70, 0) +Vertex_5 = geompy.MakeVertex(90, 100, 0) +Vertex_6 = geompy.MakeVertex(120, 70, 0) +Vertex_7 = geompy.MakeVertex(120, 0, 0) +Vertex_8 = geompy.MakeVertex(90, -30, 0) +Vertex_9 = geompy.MakeVertex(60, 0, 0) +Vertex_10 = geompy.MakeVertex(30, -30, 0) + +geompy.addToStudy( Vertex_1, 'Vertex_1' ) +geompy.addToStudy( Vertex_2, 'Vertex_2' ) +geompy.addToStudy( Vertex_3, 'Vertex_3' ) +geompy.addToStudy( Vertex_4, 'Vertex_4' ) +geompy.addToStudy( Vertex_5, 'Vertex_5' ) +geompy.addToStudy( Vertex_6, 'Vertex_6' ) +geompy.addToStudy( Vertex_7, 'Vertex_7' ) +geompy.addToStudy( Vertex_8, 'Vertex_8' ) +geompy.addToStudy( Vertex_9, 'Vertex_9' ) +geompy.addToStudy( Vertex_10, 'Vertex_10' ) + +Curve_a = geompy.MakeInterpol([Vertex_2, Vertex_3, Vertex_4, Vertex_5, Vertex_6], False, True) +Curve_b = geompy.MakeInterpol([Vertex_1, Vertex_7, Vertex_8, Vertex_9, Vertex_10], False, True) + +geompy.addToStudy( Curve_a, 'Curve_a' ) +geompy.addToStudy( Curve_b, 'Curve_b' ) + +# Get all closest points +[nbSols, listCoords] = geompy.ClosestPoints(Curve_a, Curve_b) + +for i in range(nbSols): + v1 = geompy.MakeVertex(listCoords[i*6 + 0], listCoords[i*6 + 1], listCoords[i*6 + 2]) + v2 = geompy.MakeVertex(listCoords[i*6 + 3], listCoords[i*6 + 4], listCoords[i*6 + 5]) + + geompy.addToStudy(v1, 'MinDist_%d_Curve_a'%(i+1)) + geompy.addToStudy(v2, 'MinDist_%d_Curve_b'%(i+1)) + +# Get minimum distance +print "Minimal distance between Curve_a and Curve_b is", geompy.MinDistance(Curve_a, Curve_b) + +# Get minimum distance with components along axes +[aDist, DX, DY, DZ] = geompy.MinDistanceComponents(Curve_a, Curve_b) +print "Minimal distance between Curve_a and Curve_b is (", DX, ",", DY, ",", DZ, ")" diff --git a/doc/salome/examples/normal_face.py b/doc/salome/examples/normal_face.py new file mode 100644 index 000000000..572b0f9f8 --- /dev/null +++ b/doc/salome/examples/normal_face.py @@ -0,0 +1,17 @@ +# Normal to a Face + +import geompy +import math + +# create a box +box = geompy.MakeBoxDXDYDZ(100,30,100) + +faces = geompy.SubShapeAllSortedCentres(box, geompy.ShapeType["FACE"]) +face0 = faces[0] +vnorm = geompy.GetNormal(face0) +if vnorm is None: + raise RuntimeError, "GetNormal(face0) failed" +else: + geompy.addToStudy(face0, "Face0") + geompy.addToStudy(vnorm, "Normale to Face0") + print "\nNormale of face has been successfully obtained" diff --git a/doc/salome/examples/notebook_geom.py b/doc/salome/examples/notebook_geom.py new file mode 100644 index 000000000..a84ae87de --- /dev/null +++ b/doc/salome/examples/notebook_geom.py @@ -0,0 +1,21 @@ +# Using SALOME NoteBook + +import geompy +import salome +import salome_notebook +gg = salome.ImportComponentGUI("GEOM") + +# set variables +notebook = salome_notebook.notebook +notebook.set("Length", 150) +notebook.set("Width", 100) + +# create box +box = geompy.MakeBoxDXDYDZ("Length", "Width", 200) + +# add object in the study +id_box = geompy.addToStudy(box,"Box") + +# display the boxes +gg.createAndDisplayGO(id_box) +gg.setDisplayMode(id_box,1) diff --git a/doc/salome/examples/point_coordinates.py b/doc/salome/examples/point_coordinates.py new file mode 100644 index 000000000..802c88ca5 --- /dev/null +++ b/doc/salome/examples/point_coordinates.py @@ -0,0 +1,21 @@ +# Point Coordinates + +import math +import geompy + +# create a point +point = geompy.MakeVertex(15., 23., 80.) + +# get the coordinates of the point and check its values +coords = geompy.PointCoordinates(point) + +# check the obtained coordinate values +tolerance = 1.e-07 +def IsEqual(val1, val2): return (math.fabs(val1 - val2) < tolerance) + +if IsEqual(coords[0], 15.) and IsEqual(coords[1], 23.) and IsEqual(coords[2], 80.): + print "All values are OK." +else : + print "Coordinates of point must be (15, 23, 80), but returned (", + print coords[0], ", ", coords[1], ", ", coords[2], ")" + pass diff --git a/doc/salome/examples/primitives_ex01.py b/doc/salome/examples/primitives_ex01.py new file mode 100644 index 000000000..77db019cd --- /dev/null +++ b/doc/salome/examples/primitives_ex01.py @@ -0,0 +1,27 @@ +# Creation of a Box + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p0 = geompy.MakeVertex(15, 25, 35) +p70 = geompy.MakeVertex(70, 70, 70) + +# create boxes +box1 = geompy.MakeBoxDXDYDZ(10, 20, 30) +box2 = geompy.MakeBox(10,20,30, 15,25,35) +box3 = geompy.MakeBoxTwoPnt(p0, p70) + +# add objects in the study +id_box1 = geompy.addToStudy(box1,"Box1") +id_box2 = geompy.addToStudy(box2,"Box2") +id_box3 = geompy.addToStudy(box3,"Box3") + +# display the boxes +gg.createAndDisplayGO(id_box1) +gg.setDisplayMode(id_box1,1) +gg.createAndDisplayGO(id_box2) +gg.setDisplayMode(id_box2,1) +gg.createAndDisplayGO(id_box3) +gg.setDisplayMode(id_box3,1) diff --git a/doc/salome/examples/primitives_ex02.py b/doc/salome/examples/primitives_ex02.py new file mode 100644 index 000000000..ed6a6f9a6 --- /dev/null +++ b/doc/salome/examples/primitives_ex02.py @@ -0,0 +1,30 @@ +# Creation of a Cylinder + +import geompy +import salome + +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex(25, 35, 45) +p2 = geompy.MakeVertex(70, 70, 70) +v = geompy.MakeVector(p1, p2) + +# create cylinders +height = 40 + +radius1 = 15 +cylinder1 = geompy.MakeCylinder(p1, v, radius1, height) + +radius2 = 30 +cylinder2 = geompy.MakeCylinderRH(radius2, height) + +# add objects in the study +id_cylinder1 = geompy.addToStudy(cylinder1,"Cylinder1") +id_cylinder2 = geompy.addToStudy(cylinder2,"Cylinder2") + +# display the cylinders +gg.createAndDisplayGO(id_cylinder1) +gg.setDisplayMode(id_cylinder1,1) +gg.createAndDisplayGO(id_cylinder2) +gg.setDisplayMode(id_cylinder2,1) diff --git a/doc/salome/examples/primitives_ex03.py b/doc/salome/examples/primitives_ex03.py new file mode 100644 index 000000000..21dbc9e7e --- /dev/null +++ b/doc/salome/examples/primitives_ex03.py @@ -0,0 +1,29 @@ +# Creation of a Sphere + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex +p = geompy.MakeVertex(55, 45, 25) + +# create spheres +radius1 = 20 +sphere1 = geompy.MakeSpherePntR(p, radius1) +radius2 = 15 +sphere2 = geompy.MakeSphere(0, 0, 45, radius2) +radius3 = 30 +sphere3 = geompy.MakeSphereR(radius3) + +# add objects in the study +id_sphere1 = geompy.addToStudy(sphere1,"Sphere1") +id_sphere2 = geompy.addToStudy(sphere2,"Sphere2") +id_sphere3 = geompy.addToStudy(sphere3,"Sphere3") + +# display spheres +gg.createAndDisplayGO(id_sphere1) +gg.setDisplayMode(id_sphere1,1) +gg.createAndDisplayGO(id_sphere2) +gg.setDisplayMode(id_sphere2,1) +gg.createAndDisplayGO(id_sphere3) +gg.setDisplayMode(id_sphere3,1) diff --git a/doc/salome/examples/primitives_ex04.py b/doc/salome/examples/primitives_ex04.py new file mode 100644 index 000000000..99a003a4b --- /dev/null +++ b/doc/salome/examples/primitives_ex04.py @@ -0,0 +1,24 @@ +# Creation of a Torus + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex(35, 40, 45) +p2 = geompy.MakeVertex(35, 45, 70) +v = geompy.MakeVector(p1, p2) + +# create toruses +torus1 = geompy.MakeTorus(p1, v, 20, 10) +torus2 = geompy.MakeTorusRR(30, 15) + +# add objects in the study +id_torus1 = geompy.addToStudy(torus1,"Torus1") +id_torus2 = geompy.addToStudy(torus2,"Torus2") + +# display toruses +gg.createAndDisplayGO(id_torus1) +gg.setDisplayMode(id_torus1,1) +gg.createAndDisplayGO(id_torus2) +gg.setDisplayMode(id_torus2,1) diff --git a/doc/salome/examples/primitives_ex05.py b/doc/salome/examples/primitives_ex05.py new file mode 100644 index 000000000..b563303b2 --- /dev/null +++ b/doc/salome/examples/primitives_ex05.py @@ -0,0 +1,24 @@ +# Creation of a Cone + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex(35, 35, 0) +p2 = geompy.MakeVertex(35, 35, 70) +v = geompy.MakeVector(p1, p2) + +# create cones +cone1 = geompy.MakeCone(p1, v, 17, 1, 20) +cone2 = geompy.MakeConeR1R2H(30, 10, 30) + +# add objects in the study +id_cone1 = geompy.addToStudy(cone1,"Cone1") +id_cone2 = geompy.addToStudy(cone2,"Cone2") + +# display cones +gg.createAndDisplayGO(id_cone1) +gg.setDisplayMode(id_cone1,1) +gg.createAndDisplayGO(id_cone2) +gg.setDisplayMode(id_cone2,1) diff --git a/doc/salome/examples/primitives_ex06.py b/doc/salome/examples/primitives_ex06.py new file mode 100644 index 000000000..c558eafb8 --- /dev/null +++ b/doc/salome/examples/primitives_ex06.py @@ -0,0 +1,35 @@ +# Creation of a Disk + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p0 = geompy.MakeVertex(0., 0., 0.) +px = geompy.MakeVertex(100., 0. , 0. ) +py = geompy.MakeVertex(0. , 100., 0. ) +pz = geompy.MakeVertex(0. , 0. , 100.) + +# create a vector on two points +vxy = geompy.MakeVector(px, py) + +# create a disk in OXY plane +disk1 = geompy.MakeDiskR(100, 1) + +# create a disk from a point, a vector and a radius +disk2 = geompy.MakeDiskPntVecR(pz, vxy, 30) + +#create a circle from three points +disk3 = geompy.MakeDiskThreePnt(p0, px, py) + +# add objects in the study +id_vxy = geompy.addToStudy(vxy, "Vector") +id_disk1 = geompy.addToStudy(disk1,"Disk1") +id_disk2 = geompy.addToStudy(disk2,"Disk2") +id_disk3 = geompy.addToStudy(disk3,"Disk3") + +# display disks +gg.createAndDisplayGO(id_vxy) +gg.createAndDisplayGO(id_disk1) +gg.createAndDisplayGO(id_diks2) +gg.createAndDisplayGO(id_diks3) diff --git a/doc/salome/examples/primitives_ex07.py b/doc/salome/examples/primitives_ex07.py new file mode 100644 index 000000000..75dad1e94 --- /dev/null +++ b/doc/salome/examples/primitives_ex07.py @@ -0,0 +1,31 @@ +# Creation of a Rectangle + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +px = geompy.MakeVertex(100., 0. , 0. ) +py = geompy.MakeVertex(0. , 100., 0. ) + +# create a vector on two points +vxy = geompy.MakeVector(px, py) + +# create a rectangle in OXY plane +face1 = geompy.MakeFaceHW(100, 100, 1) + +# create a rectangle using normal vector +face2 = geompy.MakeFaceObjHW(vxy, 50, 150) + +# create a rectangle from other face +face3 = geompy.MakeFaceObjHW(face2, 150, 50) + +# add objects in the study +id_face1 = geompy.addToStudy(face1,"Face1") +id_face2 = geompy.addToStudy(face2,"Face2") +id_face3 = geompy.addToStudy(face3,"Face3") + +# display rectangles +gg.createAndDisplayGO(id_face1) +gg.createAndDisplayGO(id_face2) +gg.createAndDisplayGO(id_face3) diff --git a/doc/salome/examples/repairing_operations_ex01.py b/doc/salome/examples/repairing_operations_ex01.py new file mode 100644 index 000000000..8a57db040 --- /dev/null +++ b/doc/salome/examples/repairing_operations_ex01.py @@ -0,0 +1,46 @@ +# Shape Processing + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices, an edge, an arc, a wire, a face and a prism +p1 = geompy.MakeVertex(0,0,0) +p2 = geompy.MakeVertex(200,0,0) +p3 = geompy.MakeVertex(100,150,0) +edge = geompy.MakeEdge(p1,p2) +arc = geompy.MakeArc(p1,p3,p2) +wire = geompy.MakeWire([edge,arc]) +face = geompy.MakeFace(wire, 1) +theShape = geompy.MakePrismVecH(face, edge, 130) + +# check the shape at the beginning +print "Before ProcessShape:" +isValid = geompy.CheckShape(theShape) +if isValid == 0: + print "The shape is not valid" +else: + print "The shape seems to be valid" + +# process the Shape +Operators = ["FixShape"] +Parameters = ["FixShape.Tolerance3d"] +Values = ["1e-7"] +PS = geompy.ProcessShape(theShape, Operators, Parameters, Values) + +# check the shape at the end +print "After ProcessShape:" +isValid = geompy.CheckShape(PS) +if isValid == 0: + print "The shape is not valid" + raise RuntimeError, "It seems, that the ProcessShape() has failed" +else: + print "The shape seems to be valid" + +# add in the study and display +Id_Shape = geompy.addToStudy(theShape, "Invalid Shape") +Id_PS = geompy.addToStudy(PS, "Processed Shape") +gg.createAndDisplayGO(Id_Shape) +gg.setDisplayMode(Id_Shape,1) +gg.createAndDisplayGO(Id_PS) +gg.setDisplayMode(Id_PS,1) diff --git a/doc/salome/examples/repairing_operations_ex02.py b/doc/salome/examples/repairing_operations_ex02.py new file mode 100644 index 000000000..f5ee65caf --- /dev/null +++ b/doc/salome/examples/repairing_operations_ex02.py @@ -0,0 +1,28 @@ +# Suppress Faces + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a box +box = geompy.MakeBoxDXDYDZ(200, 200, 200) + +# The list of IDs (IDList) for suppress faces +sup_faces = [] +sup_faces = geompy.SubShapeAllSortedCentres(box, geompy.ShapeType["FACE"]) + +# get indices of the sub-shape +f1_id = geompy.GetSubShapeID(box, sup_faces[3]) + +# remove faces from the given object (shape) +result = geompy.SuppressFaces(box, [f1_id]) + +# add objects in the study +id_box = geompy.addToStudy(box, "Box") +id_result = geompy.addToStudy(result, "Result") + +# display the results +gg.createAndDisplayGO(id_box) +gg.setDisplayMode(id_box,1) +gg.createAndDisplayGO(id_result) +gg.setDisplayMode(id_result,1) diff --git a/doc/salome/examples/repairing_operations_ex03.py b/doc/salome/examples/repairing_operations_ex03.py new file mode 100644 index 000000000..50eec1126 --- /dev/null +++ b/doc/salome/examples/repairing_operations_ex03.py @@ -0,0 +1,30 @@ +# Close Contour + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices and vectors +p0 = geompy.MakeVertex( 0., 0., 0.) +px = geompy.MakeVertex(100., 0., 0.) +py = geompy.MakeVertex( 0., 100., 0.) +py1 = geompy.MakeVertex( 0., 140., 0.) +pz = geompy.MakeVertex( 0., 0., 100.) +vxy = geompy.MakeVector(px, py) + +# create an arc +arc = geompy.MakeArc(py1, pz, px) + +# create a wire +wire = geompy.MakeWire([vxy, arc]) + +# close an open wire by creation of an edge between ends +wire_close = geompy.CloseContour(wire, [1], 0) + +# add objects in the study +id_wire = geompy.addToStudy(wire, "Wire") +id_wire_close = geompy.addToStudy(wire_close, "Wire close") + +# display the results +gg.createAndDisplayGO(id_wire) +gg.createAndDisplayGO(id_wire_close) diff --git a/doc/salome/examples/repairing_operations_ex04.py b/doc/salome/examples/repairing_operations_ex04.py new file mode 100644 index 000000000..fad69131c --- /dev/null +++ b/doc/salome/examples/repairing_operations_ex04.py @@ -0,0 +1,34 @@ +# Suppress Internal Wires + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex(55, 65, 50) +p2 = geompy.MakeVertex(55, 0, 50) +v = geompy.MakeVector(p1, p2) + +# create a cylinder +height = 100 +radius1 = 40 +cylinder = geompy.MakeCylinder(p1, v, radius1, height) + +# create a box +box = geompy.MakeBoxDXDYDZ(100, 100, 100) + +# make a cut +cut = geompy.MakeCut(box, cylinder) + +# suppress all internal wires +result = geompy.SuppressInternalWires(cut, []) + +# add objects in the study +id_cut = geompy.addToStudy(cut, "Cut") +id_result = geompy.addToStudy(result, "Result") + +# display the results +gg.createAndDisplayGO(id_cut) +gg.setDisplayMode(id_cut,1) +gg.createAndDisplayGO(id_result) +gg.setDisplayMode(id_result,1) diff --git a/doc/salome/examples/repairing_operations_ex05.py b/doc/salome/examples/repairing_operations_ex05.py new file mode 100644 index 000000000..f6593b3e8 --- /dev/null +++ b/doc/salome/examples/repairing_operations_ex05.py @@ -0,0 +1,50 @@ +# Suppress Holes + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex(35, 35, 0) +p2 = geompy.MakeVertex(35, 35, 50) +v = geompy.MakeVector(p1, p2) + +# create a cylinder +height = 20 +radius1 = 20 +cylinder = geompy.MakeCylinder(p1, v, radius1, height) + +# create a cone +cone = geompy.MakeCone(p1, v, 70, 0, 80) + +# make a cut +cut = geompy.MakeCut(cone, cylinder) + +# get faces as sub-shapes +faces = [] +faces = geompy.SubShapeAllSortedCentres(cut, geompy.ShapeType["FACE"]) +f_2 = geompy.GetSubShapeID(cut, faces[2]) + +# remove one face from the shape +cut_without_f_2 = geompy.SuppressFaces(cut, [f_2]) + +# get wires as sub-shapes +wires = [] +wires = geompy.SubShapeAllSortedCentres(cut_without_f_2, geompy.ShapeType["WIRE"]) +w_0 = geompy.GetSubShapeID(cut_without_f_2, wires[0]) + +# suppress the selected wire +result = geompy.SuppressHoles(cut_without_f_2, [w_0]) + +# add objects in the study +id_cut = geompy.addToStudy(cut, "Cut") +id_cut_without_f_2 = geompy.addToStudy(cut_without_f_2, "Cut without f_2") +id_result = geompy.addToStudy(result, "Result") + +# display the results +gg.createAndDisplayGO(id_cut) +gg.setDisplayMode(id_cut,1) +gg.createAndDisplayGO(id_cut_without_f_2) +gg.setDisplayMode(id_cut_without_f_2,1) +gg.createAndDisplayGO(id_result) +gg.setDisplayMode(id_result,1) diff --git a/doc/salome/examples/repairing_operations_ex06.py b/doc/salome/examples/repairing_operations_ex06.py new file mode 100644 index 000000000..e6120a7a6 --- /dev/null +++ b/doc/salome/examples/repairing_operations_ex06.py @@ -0,0 +1,39 @@ +# Sewing + +import geompy +import salome +import math +gg = salome.ImportComponentGUI("GEOM") + +# create base points +px = geompy.MakeVertex(100., 0., 0.) +py = geompy.MakeVertex(0., 100., 0.) +pz = geompy.MakeVertex(0., 0., 100.) + +# create base geometry 2D & 3D +vector = geompy.MakeVector(px, py) +arc = geompy.MakeArc(py, pz, px) + +# create base objects +angle = 45. * math.pi / 180 +WantPlanarFace = 1 #True +wire = geompy.MakeWire([vector, arc]) +face = geompy.MakeFace(wire, WantPlanarFace) +face_rot = geompy.MakeRotation(face, vector, angle) + +# make sewing +precision = 0.00001 +sewing = geompy.MakeSewing([face, face_rot], precision) + +# add objects in the study +id_face = geompy.addToStudy(face, "Face") +id_face_rot = geompy.addToStudy(face_rot, "Face rotation") +id_sewing = geompy.addToStudy(sewing, "Sewing") + +# display the results +gg.createAndDisplayGO(id_face) +gg.setDisplayMode(id_face,1) +gg.createAndDisplayGO(id_face_rot) +gg.setDisplayMode(id_face_rot,1) +gg.createAndDisplayGO(id_sewing) +gg.setDisplayMode(id_sewing,1) diff --git a/doc/salome/examples/repairing_operations_ex07.py b/doc/salome/examples/repairing_operations_ex07.py new file mode 100644 index 000000000..6cc688a4e --- /dev/null +++ b/doc/salome/examples/repairing_operations_ex07.py @@ -0,0 +1,32 @@ +# Glue Faces + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create boxes +box1 = geompy.MakeBox(0,0,0,100,50,100) +box2 = geompy.MakeBox(100,0,0,250,50,100) + +# make compound +compound = geompy.MakeCompound([box1, box2]) + +# glue compound's faces +tolerance = 1e-5 +glue = geompy.MakeGlueFaces(compound, tolerance) + +# add objects in study +id_box1 = geompy.addToStudy(box1, "Box1") +id_box2 = geompy.addToStudy(box2, "Box2") +id_compound = geompy.addToStudy(compound, "Compound") +id_glue = geompy.addToStudy(glue, "Glue faces") + +# display results +gg.createAndDisplayGO(id_box1) +gg.setDisplayMode(id_box1,1) +gg.createAndDisplayGO(id_box2) +gg.setDisplayMode(id_box2,1) +gg.createAndDisplayGO(id_compound) +gg.setDisplayMode(id_compound,1) +gg.createAndDisplayGO(id_glue) +gg.setDisplayMode(id_glue,1) diff --git a/doc/salome/examples/repairing_operations_ex08.py b/doc/salome/examples/repairing_operations_ex08.py new file mode 100644 index 000000000..a39d11088 --- /dev/null +++ b/doc/salome/examples/repairing_operations_ex08.py @@ -0,0 +1,30 @@ +# Glue Edges + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create boxes +box1 = geompy.MakeBox(0,0,0,100,50,100) +box2 = geompy.MakeBox(100,0,0,250,50,100) + +# make compound +compound = geompy.MakeCompound([box1, box2]) + +# glue all compound's edges +tolerance = 1e-5 +glue1 = geompy.MakeGlueEdges(compound, tolerance) + +# glue some compound's edges +list_edges = geompy.GetGlueEdges(compound, tolerance) +glue2 = geompy.MakeGlueEdgesByList(compound, tolerance, [list_edges[0], list_edges[2]]) + +# add objects in study +geompy.addToStudy(box1, "Box1") +geompy.addToStudy(box2, "Box2") +geompy.addToStudy(compound, "Compound") +geompy.addToStudy(glue1, "Glue all edges") +geompy.addToStudy(glue2, "Glue two edges") + +if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser(1) diff --git a/doc/salome/examples/repairing_operations_ex09.py b/doc/salome/examples/repairing_operations_ex09.py new file mode 100644 index 000000000..41807fee4 --- /dev/null +++ b/doc/salome/examples/repairing_operations_ex09.py @@ -0,0 +1,33 @@ +# Limit Tolerance + +import geompy +gg = salome.ImportComponentGUI("GEOM") + +# import initial topology +shape1 = geompy.ImportBREP("my_shape_1.brep") +shape2 = geompy.ImportBREP("my_shape_2.brep") + +geompy.addToStudy(shape1, "Shape 1") +geompy.addToStudy(shape2, "Shape 2") + +# perform partition +try: + part = geompy.MakePartition([shape1, shape2]) +except: + # limit tolerance + tolerance = 1e-07 + shape1_lt = geompy.LimitTolerance(shape1, tolerance) + shape2_lt = geompy.LimitTolerance(shape2, tolerance) + + # process shape + good_shape1 = geompy.ProcessShape(shape1_lt, ["FixShape"], ["FixShape.Tolerance3d"], ["1e-7"]) + good_shape2 = geompy.ProcessShape(shape2_lt, ["FixShape"], ["FixShape.Tolerance3d"], ["1e-7"]) + + geompy.addToStudy(good_shape1, "Shape 1 corrected") + geompy.addToStudy(good_shape2, "Shape 2 corrected") + + # perform partition on corrected shapes + part = geompy.MakePartition([good_shape1, good_shape2]) + pass + +geompy.addToStudy(part, "Partition") diff --git a/doc/salome/examples/repairing_operations_ex10.py b/doc/salome/examples/repairing_operations_ex10.py new file mode 100644 index 000000000..7849a7cf5 --- /dev/null +++ b/doc/salome/examples/repairing_operations_ex10.py @@ -0,0 +1,27 @@ +# Add Point on Edge + +import geompy +import salome + +# create vertices +p1 = geompy.MakeVertex(0,0,50) +p2 = geompy.MakeVertex(60,0,50) + +# make an edge +edge = geompy.MakeEdge(p1, p2) #geompy.GetSubShape(box, edge_ind) + +# divide an edge +divide = geompy.DivideEdge(edge, -1, 0.5, 0) + +# add objects in the study +id_edge = geompy.addToStudy(edge, "Edge") +edge_points = geompy.SubShapeAllSortedCentres(edge, geompy.ShapeType["VERTEX"]) +for point in edge_points: + geompy.addToStudyInFather(edge, point, "Edge's point") + +id_divide = geompy.addToStudy(divide, "Divided edge") +edge_points = geompy.SubShapeAllSortedCentres(divide, geompy.ShapeType["VERTEX"]) +for point in edge_points: + geompy.addToStudyInFather(divide, point, "Edge's point after divide") + +salome.sg.updateObjBrowser(1) diff --git a/doc/salome/examples/repairing_operations_ex11.py b/doc/salome/examples/repairing_operations_ex11.py new file mode 100644 index 000000000..396881c72 --- /dev/null +++ b/doc/salome/examples/repairing_operations_ex11.py @@ -0,0 +1,49 @@ +# Fuse Collinear Edges within a Wire + +import geompy +import salome + +# create vertices +p1 = geompy.MakeVertex(0, 0, 0) +p2 = geompy.MakeVertex(70, 0, 0) +p3 = geompy.MakeVertex(70, 50, 0) +p4 = geompy.MakeVertex(70, 80, 0) +p5 = geompy.MakeVertex(50, 80, 0) +p6 = geompy.MakeVertex(20, 80, 0) +p7 = geompy.MakeVertex(0, 80, 0) +p8 = geompy.MakeVertex(0, 30, 0) + +points = [p1, p2, p3, p4, p5, p6, p7, p8] + +# make a wire +wire_1 = geompy.MakePolyline(points, True) + +# suppress some vertices in the wire +wire_2 = geompy.FuseCollinearEdgesWithinWire(wire_1, [p3]) +wire_3 = geompy.FuseCollinearEdgesWithinWire(wire_1, [p5, p6]) + +# suppress all suitable vertices in the wire +wire_4 = geompy.FuseCollinearEdgesWithinWire(wire_1, []) + +wires = [wire_1, wire_2, wire_3, wire_4] + +# add objects in the study +ii = 1 +for point in points: + geompy.addToStudy(point, "p%d"%ii) + ii = ii + 1 + pass + +ii = 1 +for wire in wires: + geompy.addToStudy(wire, "wire_%d"%ii) + wire_points = geompy.SubShapeAllSortedCentres(wire, geompy.ShapeType["VERTEX"]) + jj = 1 + for point in wire_points: + geompy.addToStudyInFather(wire, point, "point_%d"%jj) + jj = jj + 1 + pass + ii = ii + 1 + pass + +salome.sg.updateObjBrowser(1) diff --git a/doc/salome/examples/sketcher.py b/doc/salome/examples/sketcher.py new file mode 100644 index 000000000..8ca1f98ce --- /dev/null +++ b/doc/salome/examples/sketcher.py @@ -0,0 +1,42 @@ +# 2D Sketcher + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p1 = geompy.MakeVertex(70., 0., 0.) +p2 = geompy.MakeVertex(70., 70., 80.) +p3 = geompy.MakeVertex( 0., 70., 0.) + +#create a vector from two points +vector_arc = geompy.MakeVector(p1, p3) + +# create an arc from three points +arc = geompy.MakeArc(p1, p2, p3) + +# create a wire +wire = geompy.MakeWire([vector_arc, arc]) + +# create a planar face +isPlanarWanted = 1 +face = geompy.MakeFace(wire, isPlanarWanted) + +# create a sketcher (face), following the textual description +sketcher1 = geompy.MakeSketcher("Sketcher:F -100 -100:TT 250 -100:R 0:C 100 150:R 0:L 300:WF", + [100,0,0, 1,1,1, -1,1,0]) + +# create a sketcher (wire) on the given face +sketcher2 = geompy.MakeSketcherOnPlane("Sketcher:F 10 -30:R 10:C 20 180:R 15:L 50:WW", face) + +# add objects in the study +id_face = geompy.addToStudy(face,"Face") +id_sketcher1 = geompy.addToStudy(sketcher1,"Sketcher1") +id_sketcher2 = geompy.addToStudy(sketcher2,"Sketcher2") + +# display the first sketcher and the second sketcher with its planar face +gg.createAndDisplayGO(id_face) +gg.setDisplayMode(id_face,1) +gg.setTransparency(id_face,0.5) +gg.createAndDisplayGO(id_sketcher1) +gg.createAndDisplayGO(id_sketcher2) diff --git a/doc/salome/examples/testme.py b/doc/salome/examples/testme.py new file mode 100755 index 000000000..d8a98200d --- /dev/null +++ b/doc/salome/examples/testme.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python + +import unittest, sys + +class SalomeSession(object): + def __init__(self, script): + import runSalome + sys.argv = ["runSalome.py"] + sys.argv += ["--terminal"] + sys.argv += ["--modules=GEOM"] + sys.argv += ["--execute=%s" % script] + clt, d = runSalome.main() + self.port = d['port'] + return + + def __del__(self): + port = self.port + import killSalomeWithPort + killSalomeWithPort.killMyPort(port) + return + pass + +class MyTest(unittest.TestCase): + def testFunction(self): + SalomeSession(sys.argv[1]) + pass + +unittest.main(argv=sys.argv[:1]) diff --git a/doc/salome/examples/tolerance.py b/doc/salome/examples/tolerance.py new file mode 100644 index 000000000..639a676cf --- /dev/null +++ b/doc/salome/examples/tolerance.py @@ -0,0 +1,14 @@ +# Tolerance + +import geompy + +# create a box +box = geompy.MakeBoxDXDYDZ(100,30,100) +Toler = geompy.Tolerance(box) +print "\nBox 100x30x100 tolerance:" +print " Face min. tolerance: ", Toler[0] +print " Face max. tolerance: ", Toler[1] +print " Edge min. tolerance: ", Toler[2] +print " Edge max. tolerance: ", Toler[3] +print " Vertex min. tolerance: ", Toler[4] +print " Vertex max. tolerance: ", Toler[5] diff --git a/doc/salome/examples/topological_geom_objs_ex01.py b/doc/salome/examples/topological_geom_objs_ex01.py new file mode 100644 index 000000000..77c1d1807 --- /dev/null +++ b/doc/salome/examples/topological_geom_objs_ex01.py @@ -0,0 +1,57 @@ +# Creation of an Edge + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# +# create edge by two points +# + +# create vertices +p0 = geompy.MakeVertex(0. , 0. , 0. ) +pxyz = geompy.MakeVertex(100., 100., 100.) + +# create an edge +edge = geompy.MakeEdge(p0, pxyz) + +# add object in the study +id_edge = geompy.addToStudy(edge,"Edge_1") + +# display an edge +gg.createAndDisplayGO(id_edge) + +# +# create edge from wire +# + +# create a circle +c = geompy.MakeCircle(None, None, 100) + +# create a wire +w = geompy.MakeWire([c], 1e-07) + +# create an edge from wire +edge = geompy.MakeEdgeWire(w) + +# add object in the study +id_edge = geompy.addToStudy(edge,"Edge_2") + +# display an edge +gg.createAndDisplayGO(id_edge) + +# +# create edge from existing curve and a length +# + +# create a circle +c = geompy.MakeCircle(None, None, 100) + +# create an edge of length 25.0 from the circle +edge = geompy.MakeEdgeOnCurveByLength(c, 25.0) + +# add object in the study +id_edge = geompy.addToStudy(edge,"Edge_3") + +# display an edge +gg.createAndDisplayGO(id_edge) diff --git a/doc/salome/examples/topological_geom_objs_ex02.py b/doc/salome/examples/topological_geom_objs_ex02.py new file mode 100644 index 000000000..62806d770 --- /dev/null +++ b/doc/salome/examples/topological_geom_objs_ex02.py @@ -0,0 +1,25 @@ +# Creation of a Wire + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +px = geompy.MakeVertex(100., 0. , 0. ) +py = geompy.MakeVertex(0. , 100., 0. ) +pz = geompy.MakeVertex(0. , 0. , 100.) + +# create a vector from two points +vxy = geompy.MakeVector(px, py) + +# create an arc from three points +arc = geompy.MakeArc(py, pz, px) + +# create a wire +wire = geompy.MakeWire([vxy, arc]) + +# add an object in the study +id_wire = geompy.addToStudy(wire,"Wire") + +# display the wire +gg.createAndDisplayGO(id_wire) diff --git a/doc/salome/examples/topological_geom_objs_ex03.py b/doc/salome/examples/topological_geom_objs_ex03.py new file mode 100644 index 000000000..7b1600153 --- /dev/null +++ b/doc/salome/examples/topological_geom_objs_ex03.py @@ -0,0 +1,51 @@ +# Creation of a Face + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices +p0 = geompy.MakeVertex(0. , 0. , 0. ) +px = geompy.MakeVertex(100., 0. , 0. ) +py = geompy.MakeVertex(0. , 100., 0. ) +pz = geompy.MakeVertex(0. , 0. , 100.) +pxyz = geompy.MakeVertex(100., 100., 100.) + +# create a vector from two points +vxy = geompy.MakeVector(px, py) + +# create an arc from three points +arc = geompy.MakeArc(py, pz, px) + +# create a wire +wire = geompy.MakeWire([vxy, arc]) + +# create sketchers +sketcher1 = geompy.MakeSketcher("Sketcher:F -100 -100:TT 250 -100:R 0:C 100 150:R 0:L 300:WW", + [100,0,0, 1,1,1, -1,1,0]) +sketcher2 = geompy.MakeSketcher("Sketcher:F 0 0:TT 70 0:TT 70 70:TT 0 70:WW") +sketcher3 = geompy.MakeSketcher("Sketcher:F 20 20:TT 50 20:TT 50 50:TT 20 50:WW") +isPlanarFace = 1 + +# create a face from the wire +face1 = geompy.MakeFace(wire, isPlanarFace) + +# create faces from two wires +face2 = geompy.MakeFaceWires([wire, sketcher1],isPlanarFace) +face3 = geompy.MakeFaces([sketcher2, sketcher3],isPlanarFace) + +# add objects in the study +id_face1 = geompy.addToStudy(face1,"Face1") +id_face2 = geompy.addToStudy(face2,"Face2") +id_face3 = geompy.addToStudy(face3,"Face3") + +# display the faces +gg.createAndDisplayGO(id_face1) +gg.setDisplayMode(id_face1,1) +gg.setTransparency(id_face1,0.2) +gg.createAndDisplayGO(id_face2) +gg.setDisplayMode(id_face2,1) +gg.setTransparency(id_face2,0.2) +gg.createAndDisplayGO(id_face3) +gg.setDisplayMode(id_face3,1) +gg.setTransparency(id_face3,0.2) diff --git a/doc/salome/examples/topological_geom_objs_ex04.py b/doc/salome/examples/topological_geom_objs_ex04.py new file mode 100644 index 000000000..b85e553f2 --- /dev/null +++ b/doc/salome/examples/topological_geom_objs_ex04.py @@ -0,0 +1,34 @@ +# Creation of a Shell + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +#create vertices +p0 = geompy.MakeVertex( 0., 0., 0.) +pxyz = geompy.MakeVertex( 5., 5., 40.) + +# create sketchers +sketcher1 = geompy.MakeSketcher("Sketcher:F 0 0:TT 70 0:TT 70 70:TT 0 70:WW") +sketcher2 = geompy.MakeSketcher("Sketcher:F 20 20:TT 50 20:TT 50 50:TT 20 50:WW") +isPlanarFace = 1 + +# create a face from two wires +face = geompy.MakeFaces([sketcher1, sketcher2],isPlanarFace) + +# create a prism +prism = geompy.MakePrism(face, p0, pxyz) + +# explode the prism into faces +prism_faces = geompy.SubShapeAllSortedCentres(prism, geompy.ShapeType["FACE"]) + +# create a shell from a set of faces +shell = geompy.MakeShell([prism_faces[0], prism_faces[2], prism_faces[3], + prism_faces[7], prism_faces[9]]) + +# add objects in the study +id_shell = geompy.addToStudy(shell,"Shell") + +# display the shell +gg.createAndDisplayGO(id_shell) +gg.setDisplayMode(id_shell,1) diff --git a/doc/salome/examples/topological_geom_objs_ex05.py b/doc/salome/examples/topological_geom_objs_ex05.py new file mode 100644 index 000000000..700236b03 --- /dev/null +++ b/doc/salome/examples/topological_geom_objs_ex05.py @@ -0,0 +1,36 @@ +# Creation of a Solid + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +#create vertices +p0 = geompy.MakeVertex( 0., 0., 0.) +pz = geompy.MakeVertex( 0., 0., 40.) + +# create sketchers +sketcher = geompy.MakeSketcher("Sketcher:F -50 -50:TT 100 -50:R 0:C 50 70:R 0:L 100:WW") + +# create faces from two wires +face = geompy.MakeFace(sketcher,1) + +# create a prism +prism = geompy.MakePrism(face, p0, pz) + +# explode the prism into faces +prism_faces = geompy.SubShapeAllSortedCentres(prism, geompy.ShapeType["FACE"]) + +# create a shell from a set of faces +shell = geompy.MakeShell([prism_faces[0], prism_faces[1], + prism_faces[3], prism_faces[4], + prism_faces[5], prism_faces[2]]) + +# create a solid, bounded by the given shells +solid = geompy.MakeSolid([shell]) + +# add objects in the study +id_solid = geompy.addToStudy(solid,"Solid") + +# display the solid +gg.createAndDisplayGO(id_solid) +gg.setDisplayMode(id_solid,1) diff --git a/doc/salome/examples/topological_geom_objs_ex06.py b/doc/salome/examples/topological_geom_objs_ex06.py new file mode 100644 index 000000000..071730b52 --- /dev/null +++ b/doc/salome/examples/topological_geom_objs_ex06.py @@ -0,0 +1,28 @@ +# Creation of a Compound + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex( -30., -30., 50.) +p2 = geompy.MakeVertex( -60., -60., 30.) +p3 = geompy.MakeVertex( -30., -30., 10.) + +# create an arc from three points +arc = geompy.MakeArc(p1, p2, p3) +ShapeListCompound = [] +i = 0 +while i <= 3 : + S = geompy.MakeTranslation(arc, i * 50., 0., 0.) + ShapeListCompound.append(S) + i = i + 1 + +# create a compund of the given shapes +compound = geompy.MakeCompound(ShapeListCompound) + +# add object in the study +id_compound = geompy.addToStudy(compound,"Compound") + +# display the compound +gg.createAndDisplayGO(id_compound) diff --git a/doc/salome/examples/transformation_operations_ex01.py b/doc/salome/examples/transformation_operations_ex01.py new file mode 100644 index 000000000..678afa9e2 --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex01.py @@ -0,0 +1,43 @@ +# Translation + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex(10, 40, 0) +p2 = geompy.MakeVertex( 0, 0, 50) +p3 = geompy.MakeVertex(50, 80, 0) +v = geompy.MakeVector(p1, p2) +vt = geompy.MakeVector(p1, p3) + +# create a cylinder +height = 35 +radius1 = 20 +cylinder = geompy.MakeCylinder(p1, v, radius1, height) + +# translate the given object along the vector, specified by its end points +# (all three functions produce the same result) +translation1 = geompy.MakeTranslationTwoPoints(cylinder, p1, p3) +translation2 = geompy.MakeTranslation(cylinder, 40, 40, 0) +translation3 = geompy.MakeTranslationVector(cylinder, vt) +translation4 = geompy.MakeTranslationVectorDistance(cylinder, vt, 200) + +# add objects in the study +id_cylinder = geompy.addToStudy(cylinder, "Cylinder") +id_translation1 = geompy.addToStudy(translation1, "Translation1") +id_translation2 = geompy.addToStudy(translation2, "Translation2") +id_translation3 = geompy.addToStudy(translation3, "Translation3") +id_translation4 = geompy.addToStudy(translation4, "Translation4") + +# display the results +gg.createAndDisplayGO(id_cylinder) +gg.setDisplayMode(id_cylinder,1) +gg.createAndDisplayGO(id_translation1) +gg.setDisplayMode(id_translation1,1) +gg.createAndDisplayGO(id_translation2) +gg.setDisplayMode(id_translation2,1) +gg.createAndDisplayGO(id_translation3) +gg.setDisplayMode(id_translation3,1) +gg.createAndDisplayGO(id_translation4) +gg.setDisplayMode(id_translation4,1) diff --git a/doc/salome/examples/transformation_operations_ex02.py b/doc/salome/examples/transformation_operations_ex02.py new file mode 100644 index 000000000..7abbb7873 --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex02.py @@ -0,0 +1,44 @@ +# Rotation + +import geompy +import salome +import math +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex(10, 40, 0) +p2 = geompy.MakeVertex( 0, 0, 50) +p3 = geompy.MakeVertex(10, 50,-20) +p4 = geompy.MakeVertex(10, 50, 60) +v = geompy.MakeVector(p1, p2) +vr = geompy.MakeVector(p3, p4) + +# create a cylinder +height = 35 +radius1 = 20 +cylinder = geompy.MakeCylinder(p1, v, radius1, height) + +# rotate the given object around the given axis by the given angle +rotation1 = geompy.MakeRotation(cylinder, vr, math.pi) +rotation2 = geompy.MakeRotationThreePoints(cylinder, p4, p1, p2) + +# add objects in the study +id_vr = geompy.addToStudy(vr, "Rotation 1 axis") +id_p4 = geompy.addToStudy(p4, "Rotation 2 center") +id_p1 = geompy.addToStudy(p1, "Rotation 2 point 1") +id_p2 = geompy.addToStudy(p2, "Rotation 2 point 2") +id_cylinder = geompy.addToStudy(cylinder, "Cylinder") +id_rotation1 = geompy.addToStudy(rotation1, "Rotation 1") +id_rotation2 = geompy.addToStudy(rotation2, "Rotation 2") + +# display the results +gg.createAndDisplayGO(id_vr) +gg.createAndDisplayGO(id_p4) +gg.createAndDisplayGO(id_p1) +gg.createAndDisplayGO(id_p2) +gg.createAndDisplayGO(id_cylinder) +gg.setDisplayMode(id_cylinder,1) +gg.createAndDisplayGO(id_rotation1) +gg.createAndDisplayGO(id_rotation2) +gg.setDisplayMode(id_rotation1,1) +gg.setDisplayMode(id_rotation2,1) diff --git a/doc/salome/examples/transformation_operations_ex03.py b/doc/salome/examples/transformation_operations_ex03.py new file mode 100644 index 000000000..3d250fd48 --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex03.py @@ -0,0 +1,43 @@ +# Modify Location + +import geompy +import salome +import math +gg = salome.ImportComponentGUI("GEOM") + +# create a vertex and a vector +p1 = geompy.MakeVertex(10, 40, 0) +p2 = geompy.MakeVertex( 0, 0, 50) +v = geompy.MakeVector(p1, p2) + +# create a cylinder +height = 35 +radius1 = 20 +cylinder = geompy.MakeCylinder(p1, v, radius1, height) +circle = geompy.MakeCircle(p2, v, radius1) + +# create local coordinate systems +cs1 = geompy.MakeMarker( 0, 0, 0, 1,0,0, 0,1,0) +cs2 = geompy.MakeMarker(30,40,40, 1,0,0, 0,1,0) + +# modify the location of the given object +position = geompy.MakePosition(cylinder, cs1, cs2) +position2 = geompy.PositionAlongPath(position, circle, 0.75, 1, 1) + +# add objects in the study +id_cs1 = geompy.addToStudy(cs1, "Coordinate system 1") +id_cs2 = geompy.addToStudy(cs2, "Coordinate system 2") +id_cylinder = geompy.addToStudy(cylinder, "Cylinder") +id_circle = geompy.addToStudy(circle, "Circle") +id_position = geompy.addToStudy(position, "Position") +id_position2 = geompy.addToStudy(position2, "PositionAlongPath") + +# display the results +gg.createAndDisplayGO(id_cylinder) +gg.setDisplayMode(id_cylinder,1) +gg.createAndDisplayGO(id_position) +gg.setDisplayMode(id_position,1) +gg.createAndDisplayGO(id_circle) +gg.setDisplayMode(id_circle,1) +gg.createAndDisplayGO(id_position2) +gg.setDisplayMode(id_position2,1) diff --git a/doc/salome/examples/transformation_operations_ex04.py b/doc/salome/examples/transformation_operations_ex04.py new file mode 100644 index 000000000..28e8b308a --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex04.py @@ -0,0 +1,46 @@ +# Mirror Image + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a box +box = geompy.MakeBoxDXDYDZ(200, 200, 200) + +# create an object, symmetrical to another object through the given plane +p1 = geompy.MakeVertex( 0, 25, 0) +p2 = geompy.MakeVertex( 5, 25, 0) +p3 = geompy.MakeVertex( 0,-30, 40) +plane = geompy.MakePlaneThreePnt(p1, p2, p3, 1000.) +mirror1 = geompy.MakeMirrorByPlane(box, plane) + +# create an object, symmetrical to another object through the given axis +p4 = geompy.MakeVertex( 210, 210, -20) +p5 = geompy.MakeVertex( 210, 210, 220) +axis = geompy.MakeVector(p4, p5) +mirror2 = geompy.MakeMirrorByAxis(box, axis) + +# create an object, symmetrical to another object through the given point +mirror3 = geompy.MakeMirrorByPoint(box, p4) + +# add objects in the study +id_box = geompy.addToStudy(box, "Box") +id_plane = geompy.addToStudy(plane, "Plane") +id_mirror1 = geompy.addToStudy(mirror1, "Mirror plane") +id_axis = geompy.addToStudy(axis, "Axis") +id_mirror2 = geompy.addToStudy(mirror2, "Mirror axis") +id_p4 = geompy.addToStudy(p4, "Point") +id_mirror3 = geompy.addToStudy(mirror3, "Mirror point") + +# display the results +gg.createAndDisplayGO(id_box) +gg.setDisplayMode(id_box,1) +gg.createAndDisplayGO(id_plane) +gg.createAndDisplayGO(id_mirror1) +gg.setDisplayMode(id_mirror1,1) +gg.createAndDisplayGO(id_axis) +gg.createAndDisplayGO(id_mirror2) +gg.setDisplayMode(id_mirror2,1) +gg.createAndDisplayGO(id_p4) +gg.createAndDisplayGO(id_mirror3) +gg.setDisplayMode(id_mirror3,1) diff --git a/doc/salome/examples/transformation_operations_ex05.py b/doc/salome/examples/transformation_operations_ex05.py new file mode 100644 index 000000000..7b906b969 --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex05.py @@ -0,0 +1,24 @@ +# Scale Transform + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a box and a sphere +box = geompy.MakeBoxDXDYDZ(200, 200, 200) + +# scale the given object by the factor +p0 = geompy.MakeVertex(100, 100, 100) +factor = 0.5 +scale = geompy.MakeScaleTransform(box, p0, factor) + +# add objects in the study +id_box = geompy.addToStudy(box, "Box") +id_scale = geompy.addToStudy(scale, "Scale") + +# display the results +gg.createAndDisplayGO(id_box) +gg.setDisplayMode(id_box,1) +gg.setTransparency(id_box,0.5) +gg.createAndDisplayGO(id_scale) +gg.setDisplayMode(id_scale,1) diff --git a/doc/salome/examples/transformation_operations_ex06.py b/doc/salome/examples/transformation_operations_ex06.py new file mode 100644 index 000000000..f6c2adfd4 --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex06.py @@ -0,0 +1,20 @@ +# Offset Surface + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a box and a sphere +box = geompy.MakeBox(20, 20, 20, 200, 200, 200) + +# create a new object as offset of the given object +offset = geompy.MakeOffset(box, 70.) + +# add objects in the study +id_box = geompy.addToStudy(box, "Box") +id_offset = geompy.addToStudy(offset, "Offset") + +# display the results +gg.createAndDisplayGO(id_box) +gg.setDisplayMode(id_box,1) +gg.createAndDisplayGO(id_offset) diff --git a/doc/salome/examples/transformation_operations_ex07.py b/doc/salome/examples/transformation_operations_ex07.py new file mode 100644 index 000000000..c1efc39e3 --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex07.py @@ -0,0 +1,31 @@ +# Projection + +import geompy +import salome + +# create a cylindric face and a curve(edge) +cylinder = geompy.MakeCylinderRH(100, 300) +[face_cyl] = geompy.SubShapes(cylinder, [3]) + +p1 = geompy.MakeVertex(200, 0, 100) +p2 = geompy.MakeVertex(200, 80, 100) +p3 = geompy.MakeVertex(200, 80, 180) +p4 = geompy.MakeVertex(130, 80, 180) +p5 = geompy.MakeVertex(90, 80, 240) + +curve = geompy.MakeInterpol([p1, p2, p3, p4, p5], False, False) + +# create a new object as projection of the +# given curve on the given cylindric face +projection = geompy.MakeProjection(curve, face_cyl) + +# add objects in the study +geompy.addToStudy(cylinder, "cylinder") +geompy.addToStudyInFather(cylinder, face_cyl, "face_cyl") +geompy.addToStudy(p1, "p1") +geompy.addToStudy(p2, "p2") +geompy.addToStudy(p3, "p3") +geompy.addToStudy(p4, "p4") +geompy.addToStudy(p5, "p5") +geompy.addToStudy(curve, "curve") +geompy.addToStudy(projection, "projection") diff --git a/doc/salome/examples/transformation_operations_ex08.py b/doc/salome/examples/transformation_operations_ex08.py new file mode 100644 index 000000000..fb103f950 --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex08.py @@ -0,0 +1,48 @@ +# Multi Translation + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create vertices and vectors +p0 = geompy.MakeVertex( 0., 0., 0.) +px = geompy.MakeVertex(20., 0., 0.) +py = geompy.MakeVertex( 0., 20., 0.) +pz = geompy.MakeVertex( 0., 0., 20.) +pxy = geompy.MakeVertex( 50., 0., 0.) +pxyz = geompy.MakeVertex( 50., 50., 50.) +vz = geompy.MakeVector(p0, pz) +vxy = geompy.MakeVector(px, py) +vtr1d = geompy.MakeVector(p0, pxyz) +vtr2d = geompy.MakeVector(p0, pxy) + +# create an arc +arc = geompy.MakeArc(py, pz, px) + +# create a wire +wire = geompy.MakeWire([vxy, arc]) + +# create a planar face +face = geompy.MakeFace(wire, 1) + +# create a prism +prism = geompy.MakePrismVecH(face, vz, 20.0) + +# translate the given object along the given vector a given number of times +tr1d = geompy.MakeMultiTranslation1D(prism, vtr1d, 20, 4) + +# consequently apply two specified translations to the object a given number of times +tr2d = geompy.MakeMultiTranslation2D(prism, vtr1d, 20, 4, vtr2d, 80, 3) + +# add objects in the study +id_prism = geompy.addToStudy(prism,"Prism") +id_tr1d = geompy.addToStudy(tr1d,"Translation 1D") +id_tr2d = geompy.addToStudy(tr2d,"Translation 2D") + +# display the prism and the results of fillet operation +gg.createAndDisplayGO(id_prism) +gg.setDisplayMode(id_prism,1) +gg.createAndDisplayGO(id_tr1d) +gg.setDisplayMode(id_tr1d,1) +gg.createAndDisplayGO(id_tr2d) +gg.setDisplayMode(id_tr2d,1) diff --git a/doc/salome/examples/transformation_operations_ex09.py b/doc/salome/examples/transformation_operations_ex09.py new file mode 100644 index 000000000..665a2acb3 --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex09.py @@ -0,0 +1,64 @@ +# Multi Rotation + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") +import math + +# create vertices and vectors +p0 = geompy.MakeVertex( 0., 0., 0.) +px = geompy.MakeVertex(20., 0., 0.) +py = geompy.MakeVertex( 0., 20., 0.) +pz = geompy.MakeVertex( 0., 0., 20.) +pxyz = geompy.MakeVertex( 50., 50., 10.) +vz = geompy.MakeVector(p0, pz) +vxy = geompy.MakeVector(px, py) +vrot = geompy.MakeVector(p0, pxyz) + +# create an arc +arc = geompy.MakeArc(py, pz, px) + +# create a wire +wire = geompy.MakeWire([vxy, arc]) + +# create a planar face +face = geompy.MakeFace(wire, 1) + +# create a prism +prism = geompy.MakePrismVecH(face, vz, 20.0) + +# 1. Rotate the prism around the axis vrot 4 times + +# rotation angle = 2 * PI / 4 +rot1da = geompy.MultiRotate1DNbTimes(prism, vrot, 4) + +# by the given angle of 30 degrees +rot1db = geompy.MultiRotate1DByStep(prism, vrot, math.pi/6., 4) + +# 2. Rotate the prism around the axis vrot 4 times +# and translate the result of each rotation 5 times on distance 50 + +# rotation angle = 2 * PI / 4 +rot2da = geompy.MultiRotate2DNbTimes(prism, vrot, 4, 50, 5) + +# by the given angle of 60 degrees +rot2db = geompy.MultiRotate2DByStep(prism, vrot, math.pi/3., 4, 50, 5) + +# add objects in the study +id_prism = geompy.addToStudy(prism,"Prism") +id_rot1da = geompy.addToStudy(rot1da,"Rotation 1D Nb.Times") +id_rot1db = geompy.addToStudy(rot1db,"Rotation 1D By Step") +id_rot2da = geompy.addToStudy(rot2da,"Rotation 2D Nb.Times") +id_rot2db = geompy.addToStudy(rot2db,"Rotation 2D By Step") + +# display the prism and the results of fillet operation +gg.createAndDisplayGO(id_prism) +gg.setDisplayMode(id_prism,1) +gg.createAndDisplayGO(id_rot1da) +gg.setDisplayMode(id_rot1da,1) +gg.createAndDisplayGO(id_rot1db) +gg.setDisplayMode(id_rot1db,1) +gg.createAndDisplayGO(id_rot2da) +gg.setDisplayMode(id_rot2da,1) +gg.createAndDisplayGO(id_rot2db) +gg.setDisplayMode(id_rot2db,1) diff --git a/doc/salome/examples/transformation_operations_ex10.py b/doc/salome/examples/transformation_operations_ex10.py new file mode 100644 index 000000000..cd2527331 --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex10.py @@ -0,0 +1,17 @@ +# Fillet 2D + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create a face in OXY plane +face = geompy.MakeFaceHW(100, 100, 1) +fillet2d = geompy.MakeFillet2D(face, 30, [7, 9]) + +# add objects in the study +id_face = geompy.addToStudy(face,"Face_1") +id_fillet2d = geompy.addToStudy(fillet2d,"Fillet 2D_1") + +# display disks +gg.createAndDisplayGO(id_face) +gg.createAndDisplayGO(id_fillet2d) diff --git a/doc/salome/examples/transformation_operations_ex11.py b/doc/salome/examples/transformation_operations_ex11.py new file mode 100644 index 000000000..f3b4bd095 --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex11.py @@ -0,0 +1,19 @@ +# Fillet 1D + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create box +Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) +# take box edges to create custom complex wire +[Edge_1,Edge_2,Edge_3,Edge_4,Edge_5,Edge_6,Edge_7,Edge_8,Edge_9,Edge_10,Edge_11,Edge_12] = geompy.SubShapeAllSortedCentres(Box_1, geompy.ShapeType["EDGE"]) +# create wire +Wire_1 = geompy.MakeWire([Edge_12, Edge_7, Edge_11, Edge_6, Edge_1,Edge_4]) +# make fillet at given wire vertices with giver radius +Fillet_1D_1 = geompy.MakeFillet1D(Wire_1, 55, [3, 4, 6, 8, 10]) + + +# display disks +gg.createAndDisplayGO(Wire_1) +gg.createAndDisplayGO(Fillet_1D_1) diff --git a/doc/salome/examples/transformation_operations_ex12.py b/doc/salome/examples/transformation_operations_ex12.py new file mode 100644 index 000000000..1f0f31c97 --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex12.py @@ -0,0 +1,53 @@ +# Fillet + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") +radius = 10. +ShapeTypeEdge = geompy.ShapeType["EDGE"] + +# create vertices and vectors +p0 = geompy.MakeVertex( 0., 0., 0.) +px = geompy.MakeVertex(100., 0., 0.) +py = geompy.MakeVertex( 0., 100., 0.) +pz = geompy.MakeVertex( 0., 0., 100.) +vz = geompy.MakeVector(p0, pz) +vxy = geompy.MakeVector(px, py) + +# create an arc +arc = geompy.MakeArc(py, pz, px) + +# create a wire +wire = geompy.MakeWire([vxy, arc]) + +# create a planar face +face = geompy.MakeFace(wire, 1) + +# create a prism +prism = geompy.MakePrismVecH(face, vz, 100.0) + +# get the list of IDs (IDList) for the fillet +prism_edges = geompy.SubShapeAllSortedCentres(prism, ShapeTypeEdge) +IDlist_e = [] +IDlist_e.append(geompy.GetSubShapeID(prism, prism_edges[0])) +IDlist_e.append(geompy.GetSubShapeID(prism, prism_edges[1])) +IDlist_e.append(geompy.GetSubShapeID(prism, prism_edges[2])) + +# make a fillet on the specified edges of the given shape +fillet = geompy.MakeFillet(prism, radius, ShapeTypeEdge, IDlist_e) + +# make a fillet on all edges of the given shape +filletall = geompy.MakeFilletAll(prism, radius) + +# add objects in the study +id_prism = geompy.addToStudy(prism,"Prism") +id_fillet = geompy.addToStudy(fillet,"Fillet") +id_filletall = geompy.addToStudy(filletall,"Fillet all") + +# display the prism and the results of fillet operation +gg.createAndDisplayGO(id_prism) +gg.setDisplayMode(id_prism,1) +gg.createAndDisplayGO(id_fillet) +gg.setDisplayMode(id_fillet,1) +gg.createAndDisplayGO(id_filletall) +gg.setDisplayMode(id_filletall,1) diff --git a/doc/salome/examples/transformation_operations_ex13.py b/doc/salome/examples/transformation_operations_ex13.py new file mode 100644 index 000000000..ecc896e2b --- /dev/null +++ b/doc/salome/examples/transformation_operations_ex13.py @@ -0,0 +1,63 @@ +# Chamfer + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") +d1 = 10. +d2 = 10. +ShapeTypeFace = geompy.ShapeType["FACE"] + +# create vertices and vectors +p0 = geompy.MakeVertex( 0., 0., 0.) +px = geompy.MakeVertex(100., 0., 0.) +py = geompy.MakeVertex( 0., 100., 0.) +pz = geompy.MakeVertex( 0., 0., 100.) +vz = geompy.MakeVector(p0, pz) +vxy = geompy.MakeVector(px, py) + +# create an arc +arc = geompy.MakeArc(py, pz, px) + +# create a wire +wire = geompy.MakeWire([vxy, arc]) + +# create a planar face +face = geompy.MakeFace(wire, 1) + +# create a prism +prism = geompy.MakePrismVecH(face, vz, 100.0) + +# get the list of IDs (IDList) for the chamfer +prism_faces = geompy.SubShapeAllSortedCentres(prism, ShapeTypeFace) +f_ind_1 = geompy.GetSubShapeID(prism, prism_faces[0]) +f_ind_2 = geompy.GetSubShapeID(prism, prism_faces[1]) +IDlist_f = [f_ind_1, f_ind_2] + +# perform a chamfer on the edges common to the specified faces +chamfer_e = geompy.MakeChamferEdge(prism, d1, d2, f_ind_1, f_ind_2) + +# perform a chamfer on all edges of the specified faces +chamfer_f = geompy.MakeChamferFaces(prism, d1, d2, IDlist_f) +chamfer_f1 = geompy.MakeChamfer(prism, d1, d2, ShapeTypeFace, IDlist_f) + +# perform a symmetric chamfer on all edges of the given shape +chamfer_all = geompy.MakeChamferAll(prism, d1) + +# add objects in the study +id_prism = geompy.addToStudy(prism,"Prism") +id_chamfer_e = geompy.addToStudy(chamfer_e,"Chamfer edge") +id_chamfer_f = geompy.addToStudy(chamfer_f,"Chamfer faces") +id_chamfer_f1 = geompy.addToStudy(chamfer_f1,"Chamfer faces 1") +id_chamfer_all = geompy.addToStudy(chamfer_all,"Chamfer all") + +# display the prism and the results of chamfer operation +gg.createAndDisplayGO(id_prism) +gg.setDisplayMode(id_prism,1) +gg.createAndDisplayGO(id_chamfer_e) +gg.setDisplayMode(id_chamfer_e,1) +gg.createAndDisplayGO(id_chamfer_f) +gg.setDisplayMode(id_chamfer_f,1) +gg.createAndDisplayGO(id_chamfer_f1) +gg.setDisplayMode(id_chamfer_f1,1) +gg.createAndDisplayGO(id_chamfer_all) +gg.setDisplayMode(id_chamfer_all,1) diff --git a/doc/salome/examples/viewing_geom_objs_ex01.py b/doc/salome/examples/viewing_geom_objs_ex01.py new file mode 100644 index 000000000..473c7f15a --- /dev/null +++ b/doc/salome/examples/viewing_geom_objs_ex01.py @@ -0,0 +1,17 @@ +# Changing Display Mode + +import salome +import geompy +box = geompy.MakeBox(0,0,0, 50,50,50) +box2 = geompy.MakeBox(-50,-50,-50, 0,0,0) + +sphere = geompy.MakeSphere(50,50,50, 30) +fuse = geompy.MakeBoolean(box,sphere,3) +fuse_id = geompy.addToStudy(fuse,"Fuse") +box_id = geompy.addToStudy(box2, "Box") + +gg = salome.ImportComponentGUI("GEOM") +gg.createAndDisplayGO(fuse_id) +gg.setDisplayMode(fuse_id,1) +gg.createAndDisplayGO(box_id) +gg.setVectorsMode(box_id, 1) diff --git a/doc/salome/examples/viewing_geom_objs_ex02.py b/doc/salome/examples/viewing_geom_objs_ex02.py new file mode 100644 index 000000000..fd8243d2f --- /dev/null +++ b/doc/salome/examples/viewing_geom_objs_ex02.py @@ -0,0 +1,14 @@ +# Changing Color + +import salome +import geompy +box = geompy.MakeBox(0,0,0, 50,50,50) + +sphere = geompy.MakeSphere(50,50,50, 30) +fuse = geompy.MakeBoolean(box,sphere,3) +fuse_id = geompy.addToStudy(fuse,"Fuse") + +gg = salome.ImportComponentGUI("GEOM") +gg.createAndDisplayGO(fuse_id) +gg.setDisplayMode(fuse_id,1) +gg.setColor(fuse_id,218,165,31) diff --git a/doc/salome/examples/viewing_geom_objs_ex03.py b/doc/salome/examples/viewing_geom_objs_ex03.py new file mode 100644 index 000000000..381f0e9ae --- /dev/null +++ b/doc/salome/examples/viewing_geom_objs_ex03.py @@ -0,0 +1,16 @@ +# Changing Transparency + +import salome +import geompy + +box = geompy.MakeBox(0,0,0, 50,50,50) +sphere = geompy.MakeSphere(50,50,50, 30) + +fuse = geompy.MakeBoolean(box,sphere,3) +fuse_id = geompy.addToStudy(fuse,"Fuse") + +gg = salome.ImportComponentGUI("GEOM") +gg.createAndDisplayGO(fuse_id) +gg.setDisplayMode(fuse_id,1) +gg.setColor(fuse_id,218,165,31) +gg.setTransparency(fuse_id,0.5) diff --git a/doc/salome/examples/viewing_geom_objs_ex04.py b/doc/salome/examples/viewing_geom_objs_ex04.py new file mode 100644 index 000000000..cf521f407 --- /dev/null +++ b/doc/salome/examples/viewing_geom_objs_ex04.py @@ -0,0 +1,14 @@ +# Set Point Marker + +import salome +import geompy + +texture = geompy.LoadTexture("/users/user/mytexture.dat") + +v1 = geompy.MakeVertex(0, 0, 0) +v2 = geompy.MakeVertex(100, 0, 0) +v3 = geompy.MakeVertex(0, 100, 0) + +v1.SetMarkerStd(GEOM.MT_O_PLUS, GEOM.MS_25) +v2.SetMarkerStd(GEOM.MT_BALL, GEOM.MS_40) +v3.SetMarkerTexture(texture) diff --git a/doc/salome/examples/whatis.py b/doc/salome/examples/whatis.py new file mode 100644 index 000000000..42e7e4e4d --- /dev/null +++ b/doc/salome/examples/whatis.py @@ -0,0 +1,9 @@ +# What Is + +import geompy + +# create a box +box = geompy.MakeBoxDXDYDZ(100,30,100) +Descr = geompy.WhatIs(box) +print "\nBox 100x30x100 description:" +print Descr diff --git a/doc/salome/examples/working_with_groups_ex01.py b/doc/salome/examples/working_with_groups_ex01.py new file mode 100644 index 000000000..821862f4a --- /dev/null +++ b/doc/salome/examples/working_with_groups_ex01.py @@ -0,0 +1,37 @@ +# Creation of a group + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create two vertices +p0 = geompy.MakeVertex(0. , 0. , 0. ) +p200 = geompy.MakeVertex(200., 200., 200.) + +# create a box from two points +Box = geompy.MakeBoxTwoPnt(p0, p200) + +# create a group from the faces of the box +group = geompy.CreateGroup(Box, geompy.ShapeType["FACE"]) + +# add objects to the group +SubFaceList = geompy.SubShapeAllSortedCentres(Box, geompy.ShapeType["FACE"]) +for i in [0, 3, 5] : + FaceID = geompy.GetSubShapeID(Box, SubFaceList[i]) + geompy.AddObject(group, FaceID) + +# add all selected shapes from the list to the group +# (the program doesn't raise error, if some shapes are already included) +geompy.UnionList(group, [SubFaceList[0], SubFaceList[2], SubFaceList[5]]) + +# remove an object from the group +geompy.RemoveObject(group, FaceID) + +# remove all selected shapes from the group +# (the program doesn't raise error, if some shapes are not included) +geompy.DifferenceList(group, [SubFaceList[2], SubFaceList[3], SubFaceList[4]]) +id_group1 = geompy.addToStudy(group, "Group1") + +# display the contents of the group +gg.createAndDisplayGO(id_group1) +salome.sg.updateObjBrowser(1) diff --git a/doc/salome/examples/working_with_groups_ex02.py b/doc/salome/examples/working_with_groups_ex02.py new file mode 100644 index 000000000..4c415babe --- /dev/null +++ b/doc/salome/examples/working_with_groups_ex02.py @@ -0,0 +1,26 @@ +# Adding an object to the group + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create two vertices +p0 = geompy.MakeVertex(0. , 0. , 0. ) +p200 = geompy.MakeVertex(200., 200., 200.) + +# create a box from two points +Box = geompy.MakeBoxTwoPnt(p0, p200) + +# create a group from the faces of the box +group = geompy.CreateGroup(Box, geompy.ShapeType["FACE"]) + +# add objects to the group +SubFaceList = geompy.SubShapeAllSortedCentres(Box, geompy.ShapeType["FACE"]) +for i in [0, 3, 5] : + FaceID = geompy.GetSubShapeID(Box, SubFaceList[i]) + geompy.AddObject(group, FaceID) +id_group1 = geompy.addToStudy(group, "Group1") + +# display the contents of the group +gg.createAndDisplayGO(id_group1) +salome.sg.updateObjBrowser(1) diff --git a/doc/salome/examples/working_with_groups_ex03.py b/doc/salome/examples/working_with_groups_ex03.py new file mode 100644 index 000000000..2c8a3d5f3 --- /dev/null +++ b/doc/salome/examples/working_with_groups_ex03.py @@ -0,0 +1,33 @@ +# Removing an object from the group + +import geompy +import salome +gg = salome.ImportComponentGUI("GEOM") + +# create two vertices +p0 = geompy.MakeVertex(0. , 0. , 0. ) +p200 = geompy.MakeVertex(200., 200., 200.) + +# create a box from two points +Box = geompy.MakeBoxTwoPnt(p0, p200) + +# create a group from the faces of the box +group = geompy.CreateGroup(Box, geompy.ShapeType["FACE"]) + +# add objects to the group +SubFaceList = geompy.SubShapeAllSortedCentres(Box, geompy.ShapeType["FACE"]) +for i in [0, 3, 5] : + FaceID = geompy.GetSubShapeID(Box, SubFaceList[i]) + geompy.AddObject(group, FaceID) + +# add all selected shapes from the list to the group +# (the program doesn't raise errors, if some shapes are already included) +geompy.UnionList(group, [SubFaceList[0], SubFaceList[2], SubFaceList[5]]) + +# remove an object from the group +geompy.RemoveObject(group, FaceID) +id_group1 = geompy.addToStudy(group, "Group1") + +# display the contents of the group +gg.createAndDisplayGO(id_group1) +salome.sg.updateObjBrowser(1) diff --git a/doc/salome/examples/working_with_groups_ex04.py b/doc/salome/examples/working_with_groups_ex04.py new file mode 100644 index 000000000..945ae61fc --- /dev/null +++ b/doc/salome/examples/working_with_groups_ex04.py @@ -0,0 +1,29 @@ +# Union Groups + +import geompy +import salome + +# create a box and some groups of faces on it +Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) +Group_1 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) +geompy.UnionIDs(Group_1, [13, 23]) +Group_2 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) +geompy.UnionIDs(Group_2, [3, 27]) +Group_3 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) +geompy.UnionIDs(Group_3, [33, 23]) +Group_4 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) +geompy.UnionIDs(Group_4, [31, 27]) + +# union groups +Group_U_1_2 = geompy.UnionGroups(Group_1, Group_2) +Group_UL_3_4 = geompy.UnionListOfGroups([Group_3, Group_4]) + +# publish shapes +geompy.addToStudy(Box_1, 'Box_1') +geompy.addToStudyInFather(Box_1, Group_1, 'Group_1') +geompy.addToStudyInFather(Box_1, Group_2, 'Group_2') +geompy.addToStudyInFather(Box_1, Group_3, 'Group_3') +geompy.addToStudyInFather(Box_1, Group_4, 'Group_4') +geompy.addToStudyInFather(Box_1, Group_U_1_2, 'Group_U_1_2') +geompy.addToStudyInFather(Box_1, Group_UL_3_4, 'Group_UL_3_4') +salome.sg.updateObjBrowser(1) diff --git a/doc/salome/examples/working_with_groups_ex05.py b/doc/salome/examples/working_with_groups_ex05.py new file mode 100644 index 000000000..422c67274 --- /dev/null +++ b/doc/salome/examples/working_with_groups_ex05.py @@ -0,0 +1,29 @@ +# Intersect Groups + +import geompy +import salome + +# create a box and some groups of faces on it +Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) +Group_1 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) +geompy.UnionIDs(Group_1, [13, 23]) +Group_2 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) +geompy.UnionIDs(Group_2, [3, 27]) +Group_3 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) +geompy.UnionIDs(Group_3, [33, 23]) +Group_4 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) +geompy.UnionIDs(Group_4, [31, 27]) + +# intersect groups +Group_I_1_3 = geompy.IntersectGroups(Group_1, Group_3) +Group_IL_1_3 = geompy.IntersectListOfGroups([Group_1, Group_3]) + +# publish shapes +geompy.addToStudy(Box_1, 'Box_1') +geompy.addToStudyInFather(Box_1, Group_1, 'Group_1') +geompy.addToStudyInFather(Box_1, Group_2, 'Group_2') +geompy.addToStudyInFather(Box_1, Group_3, 'Group_3') +geompy.addToStudyInFather(Box_1, Group_4, 'Group_4') +geompy.addToStudyInFather(Box_1, Group_I_1_3, 'Group_I_1_3') +geompy.addToStudyInFather(Box_1, Group_IL_1_3, 'Group_IL_1_3') +salome.sg.updateObjBrowser(1) diff --git a/doc/salome/examples/working_with_groups_ex06.py b/doc/salome/examples/working_with_groups_ex06.py new file mode 100644 index 000000000..65c4fe21e --- /dev/null +++ b/doc/salome/examples/working_with_groups_ex06.py @@ -0,0 +1,29 @@ +# Cut Groups + +import geompy +import salome + +# create a box and some groups of faces on it +Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) +Group_1 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) +geompy.UnionIDs(Group_1, [13, 23]) +Group_2 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) +geompy.UnionIDs(Group_2, [3, 27]) +Group_3 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) +geompy.UnionIDs(Group_3, [33, 23]) +Group_4 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) +geompy.UnionIDs(Group_4, [31, 27]) + +# cut groups +Group_C_2_4 = geompy.CutGroups(Group_2, Group_4) +Group_CL_2_4 = geompy.CutListOfGroups([Group_2], [Group_4]) + +# publish shapes +geompy.addToStudy(Box_1, 'Box_1') +geompy.addToStudyInFather(Box_1, Group_1, 'Group_1') +geompy.addToStudyInFather(Box_1, Group_2, 'Group_2') +geompy.addToStudyInFather(Box_1, Group_3, 'Group_3') +geompy.addToStudyInFather(Box_1, Group_4, 'Group_4') +geompy.addToStudyInFather(Box_1, Group_C_2_4, 'Group_C_2_4') +geompy.addToStudyInFather(Box_1, Group_CL_2_4, 'Group_CL_2_4') +salome.sg.updateObjBrowser(1) diff --git a/doc/salome/gui/GEOM/doxyfile.in b/doc/salome/gui/GEOM/doxyfile.in index 06d9bfd86..267b71c24 100755 --- a/doc/salome/gui/GEOM/doxyfile.in +++ b/doc/salome/gui/GEOM/doxyfile.in @@ -43,7 +43,7 @@ FILE_PATTERNS = *.doc EXCLUDE_PATTERNS = creating_adv_obj.doc EXCLUDE = IMAGE_PATH = @srcdir@/images -EXAMPLE_PATH = @top_srcdir@/src/GEOM_SWIG +EXAMPLE_PATH = @top_srcdir@/src/GEOM_SWIG @top_srcdir@/doc/salome/examples #--------------------------------------------------------------------------- #HTML related options diff --git a/doc/salome/gui/GEOM/images/curve4.png b/doc/salome/gui/GEOM/images/curve4.png index cbb60924d65b40aa01d1bb756aeee2da2b179217..2fe0db0ae2636265ed7b414274a408bf3e8f23d2 100644 GIT binary patch literal 31671 zcmbSy1z1(vzVA|08WaJgLAsT05JbAWrMtUD8U&=fyQLeXySux)8{Y8jch0$Y?|t9B z_wgZOPvPU!_yo-6jZX{*D5IuE8ObH2R8&?>G*pbU1<3E> za_5iN^0)U(f1VO)`9Vzh62JQ}WYjp0{}(>C+am2_HOD2#Ag4Vmw<^sl0U|cbko_9T zGYCX&VXD~=_4-s>L1A(L7Zw63r(tA_40vf|gkp0c2!Zer%X=vDe8nsF zw0hv_SH&*VT&kV#@?i@NzV1@5c)yW=yvJJASGT`985@A$aPx%c|M?NTw0Ok^Q! z887RY8{`y|qXszY-mxPGzz6Kq9t+A-pM8eeXYZkQ96!Qkb5A&;co@FMVYf%ds_N-$ zQQub~@jkI`B-Ln3rIfR3pUu;2oq=z2OQYo_uZp{K2W76d@)q??9y6~& zcZmH<-uNcuPcUk=N%O^TS|f_eu6$KwNUP5;%Bvly**7!^c(+cE2VCo^Xw(K9Pg7nJ ztj)$_3=NJ%6pceh`m-(aZnI|{u! zOfKM3M@Q#0&|SaN-W&<&-Fd}JgG8e3GkyL()88xYq{nCX!}Z{(`m)$d-jd5hvS~uP z*l%b(oKIm=8yCKRb)%w}iBlw^p~#)Rcm7s7knU3A7WeF%-JVF*k@<~*WV`!f7dctp zhs<5C!L8V%v`<+lx77nqScE6^@c#S=^!LS$7MvCg81CpX8%~;|YKUhH@Bv0d(t=8Q zQj7*u`Z#NMC8d*ff&~6Hv;AcvULR#_4}zb80^K&hvkX;_r1{fu`t9?@m=>4Zowg;=wsr=eSaE z?XK0^`a*FbNDPHRc7KtnKiD<1D*Jisn(bYBS(0l)FOnwYlS)tBE${xtoI;dHK%!2OBp#>*?Retgyrv*^y76 z?x$cv<1wz5Cen)?g6MbR{r%iBS9>YMk;53Un-%ep$PJ4obZ93>zqM zBawhH>1@oo6gnh&+z`~2(bknix# zMw{(yWwLFp?|8r+_ajzj-9X~eN?C%M+UT?RdNcRy__(8{Itm?mUB}Qpwxq8aAI*jZ zRN+52($Dw!ElV(7ni~`p(@GRMIUdTHJ?C%5r`ISGV%HE*sVfy1N5;eF zI{R^VN1+t$)4S!}ozl1+x;p~5BZXr1GV4oqkxJ6mk^AHDH_0K^d;6pLsTV3y7(xOn zs~i37?d`GJl#S0aIV3tVsJ1;U>#A(~-h_0cEWav)yWNtRhjN|hJ!#(1v%Ic>}!-1kn zm08oIY&KPJh+-5Yd9Sy+_Lre#Rb~xz1k1|H*8)Y+uwSFZ@{SMvQV2aVDnZ7raSpMx z!u!VQf~s(IEEuBcd3$+W`3VMx)oCnYJ0stmH+z@Bi|fW9LMK}p^IM0{WbI8>-uJdC z#Ww_PVuNRU?9DODfiK^M3Z`XAr*8G*)#?wfa5{%nmEw8592pxcC~^==HNs}UHJO9) zaN+eAY_Agr>YPT4u(|9Amege?4A018sqZ{QlW%( zp%N!*-NOJ$*vqHyhkNu8-> zBlZ>7Ds1UP0Y&LfNy$-+$GtM-P59!k5XYFy!64BOX_7f%gB5U>OXR3|EfuoV8H^X1 z?|=HmYbH5nr;K=My>FiCj{7v+Qb$VgNoweUFFd9X{%n)#d(7kL#-pY{$EXojZL+&NwIIr{`~7Da|Mr!z zFlm+M_$pKt<+y$&yNIe#0(5wC)Sd9^Z`_X@Qa2~VU7Ao;rn7g`4k3gBA=9ik1YT`g zpWYGB#ePbaBpM{n<&?I1mY269CU$n`a;sa3R z#~6vtEEZVSlc$)fVPM=k97Y~q|Tp3hf&Y~0fdrFK94Rzo}MKbGbM%C8Tyz>fva7^PD zEUnxZOEs9QjXs}t7))fZd@dF*HqKD0g`s>lgsgH@SCr%*Kv;8%ufL)g(jPy;?a;SB zJBveLbJJI|vol%ibft^wpO?!2aQTc_iVRa_^1I03iMtx%mk(zzc^Mfi{3Qlhs}aE5 z9Am=7G%*3?TH)`42!xTrzMqx?H&D4BqU#PX}0T;qYRJjdBVce?zf#gw%np#r%W zB~&=WDf}oLmEx?Zy^1TZ(_4uDJkp&-v+{rMla2LX6=6qO0n2InGFPkbm26WHr^V6S$+{F%f*Tt{>*IGX(MX4!&`6c;t&is?Un&@? zh=@pNRcb}~WT3J3z1>GT5Xvw(9A5Goj3Z;+TtRowr)zJ9q2hSNKws0sSEu_pU0q(j z^l!t6b#za@J`PW@EwpnZB&ox>9jPR(2n-vbqO}jd5jJ6F*zwGO@^7pX;Ob9 z_FkVwE^2eJuIA8It|awC>%#EkbZaCU8x#STbmdl3@WmS1ui_?|m=wq~{!Wp+ zWb}+A`|amD6u7aXsquZu1A9|{Bpz-J+}o={&(F12(=}8 zuCBe~v&DJpP1k-=C7~VQ2G%kNJL-;lQ?`SqmTz(B`|sOz!#0ha`UFy2dYPz1AQLl8 z>JX48To9S8r0o;?LvT&yl42LjD=go}FhUdRd%Q|pw7Gnji2{-ur?&SY)>BCBPw}e* z@h;S?u$i7k=6b8T7b+=|kMuqrBsSX{#%IZ>PT7};PatZew*v*-gHiB-@l*P zGKeB9ho?cl(&Vk!x|;G?+uEKt9ln*Hbp6Sl`~rfHP@Vi7f{)Tg1%ZU}=skh>J)?t% z@DTk_fnMEquKq>D=f*liuboqt&s}Owba~=8o z$Ll&lHbKPn(yT~UfQ{7pp*!m*b7>iTQ8t2ea<=7TPFap- zeHUtQ+HtOaKw~%2=V;w>edknvU0i2hQ^)d!`#U&ff2wi3JIQoVk6NWPCwIFamG7y? z7ydCi{oo+_PCc;U!Gq8Ey`Z2kRztKxzif&saLG`Hf`VcV2}(n9EOl=F3B=~zxrY9H zt>fy-dj7PdcdJi`BI*ac23J^lrPfZ3!2N4o`@MVTHxG>{j~o>>nU4E$;|{0LC70%N zwJOIqVgc=QjkcQ$t+&X@db)Zhv!$?V(PgSptq)omDC zigx4+##6@*lgc*?EyvLY`6_S8g7gIH1w}4CDqN=fsRS(5&m%8sq+7h;mm{gem{^!= z6XaA>Tbrxi+(hAz4RdAXrC|kz+S-BCQ!_Ki0gIxrN~+S|qi3h5SJ$h(uCDN!G_EBkgkx>}5GHArQGQZ=UpM!>5lJ^NmA^yh8COx*qBoq4>ax=o|~418s4U zj4VAZ?Hi3RbPJ-e-9Nu9t+TRDJFwDF5jhACl~-p(D9BYzU-R>(N}6p}%dNf-j>Bq1 zKUv%RHHnxyZcT)OY#SwoGH#7cOGdYJ;m-B>&5IWdn1w%oep$Y&3GneSuHb|4yg5#y zGj47nCiF$@Sj>*c;nE)yNNHgk+LbS|M`}6fRG#TcLqH!b;=U&2>OUV3qdl9qD zR)@JzkXqt(R?kIG-@%Bd{|rYpwz4H}0tkceN2ke>9(O0PA>HR1lcH>-%rjG87(sdeB_)kqmM1>vlr7(5u*u?K zZ~L`?hC-B~@elAfk<0C@_%Tt2K|3a*elDSK_R@U5F*!aet3%3G?&$j~Maf4wIo&8aYV)Lk`j90 ze@CLexxTpxSUBQystYg(UormhKU4`aL@cg`LoDH8pu4dNJ+F>`{y4iV<9r3xY zwD~VBeW8h_M1`ZLqxf#$vKa+=>DB{j9~>=XhHlgY1NA2}1LN2+5b zR_NNaKKOqc8D}2O!jM_wI%dZ1BkLzRHb&@m&ukUT^2=hJ_!;|sx z@r$#KHkMbZ>UDO7V|f+ElN79Du^8J;2i!I{E$ewb6!7rym}1eI%|l~jWE2!(^<%X* z$FvTMl{jPJN-k~z8Dx7d|AJ_dBId!NrbZfpiL7gjMj{Ht^(o~CKXI3vApW~jIJM_Z7pr- z85uK&ZA$7|sHv$DNJK_&+CA#Y4H=JmDV0Mk3vBI@D!nV+&~4BG#`6kvQz| zd7&vH68Q5uCBysosFmfi^70p3!+attvq`J(jc+zX@Hh){avbp3M}u-U*?K1iXz1zl zGc)-QG#;X&qW1Q%u~by1eNf@Nbq!g`ERIrsHHRfT5`+r+`1qJ$VLdip42IV*n{|ve z(a85o`WManViKHjWAMgFIYze%(L^DFd^o3wf+{|Ol=TE(c@^@}ZKjVN=ROgvep6f)F zlzbQ+*;#J&wR$9+uXA4vFa-~msH)JzBQ-soKHik@T%8?V#qPomy(8l)8#%dYDJnWT zU$@-rg2uPD_K1Js)R~Qq!P?sTF40+NW`-^2LKp1HBqqkG$9wh_Z^!>NDK3}GRC~L( za3&i&J06#dLyH$|4{}9gqlagDcm*RCcRpZ*eL3ly3W7B>Xwd_WcjNPnt~nD;S&@Pd zEt6}ZD%2iBuo-W*LR)!5y9OuUxF>n>YVLVLljqLSe$%Hg%-;(CNQBb;>zBo^6c2v> z=az#>%a>2NEcV&QFt+Cwk&^TB3-@n=yIbFHb$D%U887;&;G={d zzw+?E8O$3U8d_qpu(2tZyK}hoO>y;|nQu*RY!ttKWRTl&ksNc7H#RUpc*{b@Oj=i6 z%|c1vI^N$u(gWwd2%95#e~5^If#G;*w4PQ_h=71#n|QY5j4VB4lLH|`~UJ~YMfRLX>-5L69h(j8}5h9=HhuBEH;l)rr>r4ZHD1J?pZI8>c+!#=!os zCyfa7wb^y2c)sb240ngR5p%v%nF$F&m_upE2bVVXdNIQS2#BI0V$D5erF8mkAI6jV zwaTczWsBwJ-Q?5Q59aaD0Vf?-liOG}seUXT!5zv9I$3O?Ns_>RFItZV3Bm4-D$bPD56R)-&G#Xz z=!JRZ;;cfcZs;wW_%BePcwhb<+ZrCefUCDf*36oJRp99L8%T~ye$(z(cLC+h#kA(9 z@DgM-6vkItB`mbG_GVXmn?gbp6MHQ!-`u#=9iG!&_cP89YiBc=t5#XwD{E`t)FQ_F z1ij7ec^lD+0!@&?m(Iw<@TC{__?X+R>BLc53j`#uAYDYsua+H3qauSl!FL5uAVwZ) z&^ag83=|DaCX7GdgUmHCVYcY8MI4AeHa@Pbq)bebtx3BD#<4zbtH>xpTTIv~uD5~y zQ18~tY~5PIOKrOU;vv2_r*uTRCNZB*R!EbeS>{_-J8@=xUS9tIEef2s>F;lYKq}%f zP$+JN#c9snxq3%>dL}0i&vL{63LZ+}G|K>(7>$dM4{d7?jE=r6N}RpEySclo_lDo- zwlmh!3JV=D9Tof&crcxR^^ZA~hIB2u{f3_Rf#vLW?}#;>3-i9c9G|Jz#crwqHk?G; zSRe!!i-X$F)Ud>^e`oRHF&IpvMgWM7FPP+4JHBJGnZ%eRgB}}$)x;v6E3?A*GHHC# zUB90Ji&-xs*_}t_l6Uy(2_#W4)A`6Z4Y>se8^Yr&okV}co(X~Qe)~HF|CdPqufaY_ zq+50b&)UNa21tr^#m#7U-mZMC_j7p-yhD(tAWPgyZN&KFZfrGj^Au%2f1RA3?(TU& zAP=qG-P>IyuZ_B?{!A}?GL7YDP7zCbuTF(7f|i&6Xt!!r6HX#V$H+K7F>x?kbr?&p zziKGJa6mrmnVO1`g!lLL0gQFT78x0dj*bpmbwGji z$1&R3*^!Wtq^72xpZ9cFpKkO^aNm!0bqQ){xDTiChv0HbTOL6mN;`d2e0;6cv-UoN zNbMUck*FvfoM*ko($z||BO@516B677EedLNPUmwP(N=H)Bw`PHW&X(zuE#6er*BG6 z;RIY6oTS=Z3I>ui>^c{k?3WKIj|XMqRpKU#lnPgVm@U*}prVdV;M6!@9;6F|fNRYV z3cuK&^^HE9tuo&k%kAjs02?9x{xy!Ldh+t}*4C$aa`_QwKKaGPiw(|~;EBw#;X)wd zrl(jVhz602E?z^IlnRnLV{+UDQB)DKDk`h9lccQFuk(LIg=(8=db~7RI#oi?n(I>q zMSL%{p%AUO{3*d$anC zFxlS9iWep_D(d2Jk(-%W;rh6_Xtl4e?_jZMaM>b4;YCV3s2(g3SVqW4sc6X-l7sP^^7q2U&Ed8yx|i?o9P~>j&C}D<0MhMEm%*gc>knLAUu))rI8swp?b4x( z71ewH*4x{=@PZu0KQBMO6+l2fO*<9HjKqCxW^QiHW);+{)27_~{C0Rib!0yi3ltG{ zl#`23)Bvb(b}TzGQ%=iDSr-xSRzY1YTdOsd&zGWhyQr|Rf3vCP1yyL5q}NOTPc6}J zs1$!%Z;E>jft&M&R{cAgvWm*)+M3^jk)ffK?)w)nUIe032ZV$u{9_K{oLp0p>PP=j zN(~ixvr2q^=i~|ng&8ETsQA<3VXo5dEea<32XnK}Y*o3r7C+i{}JV$HY;oae++W9UnE==YNsu~)}@$p!=xJ5a>uLwVnjg9RsG^j{O49?#6 zGh=`Y*B?wujEb5V8#`NRhhMMi)9Z@~1@GtPR23Dgt=4;f{o+9b{OFHysbum*9IkB9 z6;HuGb1voSRiMT`Xeqyp*X3e2neY+{mowQ~TCxD)c6)hvxi<|uLyLua$7J^h)=Hzn zB+kdXQwb1zJ_s0eR%?R9iQqorzk8?E9Y*ZXUGI3x^>DQc8hK1iOz~tc*PaM+;kXbS zb|x}15VqX-_$h!*I9hI{K*ELKiE z(Nlr!%P$^V985q}J^Rfs|F;zG9|a&M;`cXz?huC)74i#uSMuy5TGL$m$mUXsL=>ON z69}8%j>du1HuEC{B>!gfhbIsi*#8$fJnjZ~VSVH$Uy+fT>EN}Venn20p`)ZHbnQ69 zcV_Bs83Xw9m-l0$f=HD#ft*sSf=F_st1AHZ>hI74Z!fo>d%*BaW+(Oa3=G^joON-z z-geHpM`*~_YMxe}>PzHjZX)rfZ>!#K(mfoVEJoYd68r>)pmUuGA6sts>+#9OK8-Ji zx|tyL*4ZcX2?T5AgZ@;*{?N+a^8JS~ei;8xY5iD}&NX#YO7xrku$!m5B}Ph0vGh$b zMuU1KO6bj_S+cUSDOGQNH?eNdy=Y;ceM6J#O<-jjz>WtS&z?R}C%9R1ld#wK!EkLG z`c*!LS_73-^<@~ejK{w0m8P+HC2!qxa!#|dvN8kT%#%_+Xy7P*?97)RmIOh16@iB zTV*oyOH8Bz?X@!{2@~;k`$Rw1v0RneLbb!Sk)8VT&t*b%{=R7T49it+a`*F{?o|Pp zRM1Vz%gMWOn7QO9n$OpNV5dBNXw9zD(lS?X@|jd9mjPXo%sKnW<>7pPPfr9z0tQL| zb<8j#oTIMt%uFfb_KWgAXy=Qc8s>-Tof2#;EbqK}dU|}2F=8V6B8{Z~mDr7GFchy^ z)j8*bli60+_P)Io77>fZJ#$o*rjz%Gk2Tga3;vz+_e~2OGSN!;@(Pym0=OLRcgDFT z65=>C@1`tQ_4^XWjW)TG4m!n?I(qMKFPnELr^&BAAV6e?cMjQ>7DMH?s|-MzeJzZh zC{9a5URhESSvLVNng-3k=;}q)E#kJ$$E*9EO(FmB@o|_`d3POND{DKui+U~GMmTsX zuOCQ36H`MeIld{mqs#@j*L&MC-QBdoxZIh-oAp{rI*$45-b7kBkd$W^lWLL4=~CMj zsVBd9VGt3pT^{x@_>F~#P#R5i4I^U`d>ZER3znl5CN*!cBWhE}o z6y7YWD?nsuXy}T@wYgi|(s<)k1XvJ?M0yO-dJbmh?D52>kQ@U&!JIux)|xSEZc3}` zs;2$>^U3)-2Y&vi9{4l|(|xpAJ%t#5Nwse&i#I2CvEB|Dl!N}<`*d^VTufAyZX{EK zTht)PnfU_U={P;zBD2(5s(?n4yj9s^NCj+9qG^Ues<5>O^ zwXtnB1Y!i@vb1XR&UU*e-M8f7-nmR^BUA+4jZMnUuMa7iekXlcLlj=CtWV#!zh(8y zQ=-_g2y8HbI41SKWS3`n~wIsR=WI!PY=q4KtEENoKdk)VMAEIn+K}l(kWz6FxO{%UyImy^xfin`>xfbhGW{|AtnhUH-4> zJd-IqhgU?TcZMF8Uc)?d@ZR#g z<(yCaqp=^AmYH!8t$TBa@Tzxo2g7RhMvhQBeR|n?i{vbRvUqttAlO=7eglLZ$m}Lj z{72>FKsyO*=;o}5;OH&Q{*)gN!4cq$jf@X(EvX_66$Ef3Qn|uzUzsj;Z|PTee|P9C zIw^{OkFZFU>B8FTC>BAvL3e2o*2J>AEVHTN<@lsEA_4+&{4<2N)fNxTfH93oTy-0y zths)CT*!&)ng0L5)I)!Qto&6qM)2hF-TE zkPwTC4ggx<{dA1{7JpXWs8J5Eti1~6EOpiIynGOGUp|~OhjZO>u(KQAO@$P-gkKdROw#Kt!N{PG=#*{r*ijB4`c{DRBrF2mE4kT<8Gz~t(OhfudFk>wz- zl=p%ew2<4#T9r;96Xm z2vE5B_=wXn_>vzjB7p!TV?rMUr_i|6%tC4dlQRq3dbeAecvDYV_JN8DM$nstjnaj- zy(R_MeMZ&GNvu5o%pm`gt%)EgOGQC}6g`j?J9vyjKtP~GQB_7JJwHD?hxMYfu+%3x zROUUUiQQN!vEnrl1er_~Nm1bd14{4S%$o~}$M!B(fnv>$*&d;~VS7n(tn7M{R{<6u1 zNy=ese>}{WfbK3#1aMkjL_|bZHexJqy*Ik5yj(|rb82d)awY^sURzqbL=r~_t{a0> zflt=P&S8`D&DC+AlBO_bm>`k-YA4 zCIK6V9vyL#m&e53BuIuTEce6Nh}7fb(|RGh=*>Stgee5A0gogJ6U)sYwM z>x20w^Y+RQbaX})$)Ht9oUN*m9k?LrrD1C z=)syY{RoqyB#mP8FFfhPaPaWx1Id&s9}jXfx0Irsh0AMUhdz#7DEWq_e_bCCfzn3ucO0=)Y4_R3to=U`Q&iIoQnH#0-@ILKF0gKg{nRd)w#y7vUoI4)zknM z2RKA_hb3m>*_jIGL2z5k^x}fB=z9jadCYL8WkiO{s4gQUbzi3t=4|3}WR;{Y&x})g zUpro0*f}{l+1lE&vew9(#J?is9vJ~_;8m6zm*YxC_iIx3iN=i-k!?TvjQORp9V6L# z=;DFH1A~7P{-$()5dL!NC_Ti$3Cx16Ci&xWyG_Uln`rCP4kzCXqBu3L%%goq(D(24 z&gV{-ZlXbF1%=bY?sxv~gHSfeJ8b{=7y_$atQrjcRd;Kx>0+oF@O}wgx3Y6dbu#?f1=qk!5WQUx%+IrT~k-T z8XIejNY%0Jn zqw=AIyqmVtY{4(`uQ+7!wD(}@_LAn#mH5HY$XetS6!Vgkqv_PZs81Vc=#Q@JPIIH# zJD9AHuROB%!Dsi*_JHosgwyx&(t-!LjVbx+Kafp-TNDVrTsY=K5;=mR0p#}_Km6~> zbaGaNt7ce;U(xuY?XM=nLTNos4{y>4DvqSMxVX=Vc=dMoSr3hF4g{^=lN5f9j!b-p zfyKl!Er@N`jVxV9pl6d$HZ&WV8u|)skm0@gyDxc#{QcvZi=40UC#GT=&04cG2|rgJ z|Aatl$@VVGBHH9<-6lUeeh~u9*4*i=hu`%gAi!6=5#T?otJ72_gopR*yf4uu@$`@0 z+}Kz;FQh6&2_FT#_!KwQ&zHPO>gu30_VrQUIo|u2Z}{ZX0XmML4*@pPm6$a8hC6wE zZ4ZTxlEG?Qt6m3KUwR3nPXYn}t^gb2F$@@#$t>4p=FtM^rw;8L3jsO04);HXe)>6D z(~s1MiHYTscLRK*=r~mXL_~%?H;h<>WGbj7zA=KwQ+?k-a!TrUJQ_9h^{q7yoga@s zK0XZ46p2KA)>;pY{#wf4L z3hXc}kq7!X0bDsN#(WTn0p2<*RFe!G1fS@??&SaMS^Il@kZN}U852D)=V=O*cRxXc z9C6v^_q9Bww7Hlx+B;opWKB}eQ45CB z3kIJpCliiOaIk%Nd%@w?pl_n3xyf<1^uQNQd!Jb^C-A+jaE6Up87P#XZL2by&&wEy zqE-Pc-30!JduoVU^33ml)cU|`ZL;Cz4(>#5Jr|R1`3cf2GfIgd(WQpE_{7Bdt~fU5 z{JS)Xq{@K(p~Z;dSufU=yK85GbmV#p>c~aO^?mh57uNUhB?Sb0+qJyCyds4AqDTVo z&^?=DSgrN=`MpmD0C9T)C!K0{FvrTx%?%9=O)Qp>mzq(SnZQg0AAfOu zF%KPth$z*IUbT<{MOG^>EFq%SsFRy`IyCsr-Nph-EOWYv%B-)u+X$5bGp<(sVY54R z@sg1dc43{(xHpO#9-WGehGxSGw4IfsSzd#H@kxDy7nKbt=BGYpf#(b-`(hsPj4Gj%#Y zqI`wo6<_1!7H@Y~*%ucUQU`rLJv{~bd&eKc0oMy0Lc+oQ zot?g))2C-@wLy|BQE9&#T0=vl2|W2`Pw1)&u!d_h*{%d|CSVz z$bTOzC#?#|5LmA0`&b#$Nz#EA(LOfma~JHL#KPc`$> zxnp5k>eu-SQS$Qac8_^FkkVMNLgbA<*}2Qvj-2gH;Ow|AEGmk|kYc7#ZbgNz%KI2) zTbl~{SPMP+(Vnrt=Cl?!CZ$W&?<_@kNzkB!22N^Gzlf!Or3dA4q4S*l}y(!DR zsSnd6O%FHuz-j~_RT#0z%IYc_&a-Y`S&GQcRiGUysi+(-HZ_SkKjVo`8vqLedl2Ea zBvK_O%;&zLq5ns;!0JBU-`8LA90#*ds(DsXASAKYo>@+R`_bh~+MP%RKRQ=|vZ2|Fjg*~}BUqUVgpf+m-=a3`c7AzJ zM4K`I9^>uBzIuZbD=Vv7jn#A7&0~kKXl;m%>&_i^{an>k4D|2y^{S-$Z@eV`pv+2` z|KS=P?cMDv3D+vQx~Xt)jKv!0?~@yoyy)rbnu=*o**ukYQmi&I7$JLCC_(CGHfTAN zI{cCs7&}F?GK-REVnstu7bbQA@#o>u4C1HKWIC-r4tyJsTExYJ^YbZr$tWoU+qH75 zrE*&VlYBTerHJI~$+(c_<+?kb-|6}i1f{YBUnTbip_73J-Obkqn zQG;3?Iwh&8T(?9&~8#C|{_&+psgyyVq-j)##gO_nSXYjtwvAKiW~H=f~6qj7E1@=Tje zZAbivjX4f|*X5V%ll2}-GJkqVZ2|HY`v@pA&0m6Xm?zqsyZU6a8;cr&=jgy!aMqq% zgr<~ZXGR9X#WTOpCUT8K2A(Ds7W@A249zvj(l;=vStL(lMdht>GjHyxYLxGj@F6K; zwJLf9UY~@eeLjs0k5^RK|Ezet>}}P`Y|b!1^Ibh6qG<*~JkDphU%o5<5RgjE_wtMC zbmik0wq;8AYSyP{X>eKXc!Or2rqq1{O48^4*h~jG;1YU|hYUGXs_LOa>Ri6dP3O9Q zIyR+0w|cu%oAn%0Uk6&EDLD!7-e~XjhR$;U!+1W~MG!E5JFQU{d(D&i>$sGUZ<= zMn%WI#90q07r@F$*l%(p321x&b;ZND@61FcSk`dd@?7yccwgmsH9ZFp0#lf;15zvn zCG~uzV>qx_R+>5OZUjv$#a`lZ{nma?Zy0NAf$Hn)b}a|Tyvwi5=GlF-?JHMmYiBZh zvbF39A6-OLFGxuf<>p`ecks)15J|0^h_3kO)gk5NY7$pF+~r*<`^7^8yt{_Kd(zC@ zNWERZ(LY89&kRe`KN!N(Lxqjzl7jr_rKW)!b`8qd{aA-}G}liA!x#33k>xe6JB{nY-IdDYwD=%F2$aVhJndELlf$+7MvmsjjXS3VOL) zs31|bnmw?j@_z**-mcbhOHhG7Xm^%SQ6J0SJ2~TVx{Wk9zajt@Q>N5lx|x4^0bII% z0fj1n&(wGpXiwrvteZ<)UN40=v#u}Bn|sjCp?D_G8aJ6uE@?4W9}RnZdoLeq*^Q>d z9@XmSvTy;`!NO88nI0HWH%t7_3mJ%*Qvx0M1L6q10z?9ct6C^GGLZyR}Y#SQFyGv1w_=*?sO|Jsc zxgAg5I_G2-&i`_Mtq)X7VN5!VK2YyWSecmx%o2b8SR(&8x)LU>E;p{X`3BaTcbYAV zsy89QgkMEd@%>TZ+L{g!i%h2fsD`mM-rU8DNBwga1^--C;hb9PqX9(!8_C(3D9vWF zuEEx*V>scPCtrtZCH3Uw`{(DOoVV838;m#YxSF`Qxy_fqISONn1Gc}amoU%~ zsAT3~iA{~|pX^OmyU)bp!MX`cb#*haps1=h^EURq;mJu?W_{W_b*W*n0jgm~&%djl zzj5qeF=QTcMWHFFXx!a?Ku*}o3V20QrYZ0LzEgL7E!=72owJ0*tk+dgP1@@!RfqMK z_i+tD8T~V!oMZcw-rt+NruAnYE4Sirs-NQZ*08o`_VW^I>WLzy``HI( z&*VQX^zepGp!hwrfP6)z6y2VVL!ecEny7d9C`0l`W02c{@lT+7^cA*KEd@6R8V9w@@3aLjv zipBY#F5dbN$@h5r3R7i|`?Biz1o=HfaOz#in{WZ1EQ`<8i9M++|h6K_Bx9%3@JMyjp3u&Tx3D!%xpTifGVuu&{ox@CrW!!Vcp>Pa*^U&Y>ARNHs#y!;YrMEuSKmqXpuvQ~NZ zy-UR8Z2d<)rGtq(gVAaFpMpq{Eo~!zyR&9WO!MROv7|Ykl%~Zdyy8XHI$W%_ty;0= zl;&704Reenj@SMk6x8WTw+ws}^=lSq%|gkpW;!|Wkd6B9WXx=$l)>Lu9Oox6>QP+(Q$#|mYw?-s+W zKT#U*f@&#OfmobpG;I?9CKn^`($idFC$)idvw2ltdRBTYJ2P_JM@$6>BxpE}xrKrc zluMDNAUzw!SDI+Qk7Yibi#8Q`7dldQ@>3VMO_73p@Qz3={ijaSvyZK+#*Ij&3sE`! z^Y*;w_(-cHyK_%yJfrWjw-{RAtZ~`racfw0rZ0qN=ikdD(F3n%O}iYdVNIfYB5;iq zJE-ABN0=BJUviMcHY7qY>b&eWrcfJP{KsV(!s&UtMs^l+8&LcIm`W_r0sufvHqqQ6 z6P!&x4qWap;^j|FxMln?js6UUW{ft0M>W}nV`d;uh&ctALV#cYDi4@Q;!qe0qeDXG ze1MuX_3a;~fv?n*ajD9$Y7zydPKYXN-&i3h&hg4sjs!Q07}*M2$R)884@S=&+iZ37 zp(Z9P!4RPM>lhnX9rB!o@x$-z7@>)MEifR_FMxJY8g}Uw-jItjp&`H9t!di7eojzs zKS;aS7ib{E9dHxDu2PZ4wJt7AEo4L~oYmWCvp%Eo$WH6HnJE{bmt*!i_Z5XBie?b3yJP!Z=b^yGw-Y;*oK6l~yx+yUHBeF8d;>>GYPbqu{W5L?IZRS(L znVG?VdIh4w=ce<}&dKe=jEGgFxYR12d;T_9hm!`I&-@gRbX8#BvyB%Fl8hvk8dmS( zw6TImGvz<;?p{Yym(G{@*84}qNFR3dNxlzZkc91%L}bJ4BSaj7=;gdnLj+q99vFEa z6`)Q9p>)6a7!8fvB-_7+K=7Xae^HB{GW%96u!-~m*A6*nLv{VpYAKnSCA=7l^!EMB z-Lu3Oz#cu&CO->oJg&2I&rwl9pB)Dd`3Q z0g>(+KuJaE&T)|LkZvSIV(5}?7`mJ9exCDw=X~cp=dC|JF0P9`1MIzL&pr3Oe(Sf^ z+W*F7`~OVT%W12na(|%YFWN?3Jq3>xyYE3>CAjze4G_zqnG8$C$T1We94z!3pZw8q z7+En~!}zgU3F>lLwC$Pt1SvXs(O6qLcc%ScWH-X$nUp{mr98<2`8qSpS0P2G>fzzx z;=&7ZB#3t>D}WrOxs!Tlre3=Wor(aL6!N~xYutNpqUX7yi;D|T#Fe!~8x~0YwGpl( z_*a*&76&dGF{i<6gashU+-&ATjcfkewvRgss05tZ-YS>79V+&odEy{w$=^Ps2m>DC z2(np$E5PhXN=THheEEW9L(9OhJZ|i#Sr!sGzX3P)jce=kii+=lUG94UGE6ps5DJI` z`ubTZ_@V6?AJ26bfNBBwyiBP@>z#KO8WV**Rz#b(!W;c|+vcxB)4gaVhHf8Qoxdxh3R?Pl`FI3m(SQo%q)Mw{2qW-S zNxB^~BGuW!MFK6$c^G@OIw>hkYShrlk7i) zPw&}5Ul~|ZO3eZGZE!L%c_B{Cc|}W{3=ZmaG?51cbG8P}|7cQ}u7q+wf_&wei2LwF zT=ow$uk?o?5E~=~4kzlej(aiy1h#!>*p$h_?!~}kn05PCAiHu5m>vHs5gS2Z_vNfE z|Nc@@`G?UCaEE}_NbD&+QQlu07*3G)dZ2;PVbopu^5N5P@Pv_Hy1qffV5m@4vC%t*Um~4zX+kvQ?@q`)Gh?i?hS?rANjs|dGHws8kig8 zwri9iklB0Ef&o^)MLnb&8oVe!icP;ubDs>Po8vI9qA@LdPNP#x_wHz-jIsMt@V-dr8aCV zDSa!|QakY)PWmYZb;j8)L_?87BL=>HsjhBSt6KfM%09CtMn*Z7>4$=d!&K<1pk;rm zBvWJs1oB2=Yqr_Vb=O^T*VV2KX*t8w0Q zL@$Ua=u2w4wSM3|Gp(#Fb1vVdzTw+BDN4~3^2*jK-bW?iOjjXlj&HcUe<9Sis!PdD zc%m`FQN)qol$hWZt(ZbvKM%!==%?VqU}4+)T|s?VuusJZU;S9VQ4dWp&HOr6?uE$mrSl>QkR8y`=M z9dfwP^#`$8R#xVZo>5e^onY*X{_x?-zQ^F;AgKI>goMPz#QOSfu?K@6lE39muBviV zRK)TUXIInEXkU}H;TL9L2m~Pqk7FYvaiJdxiHOY1%z!|lU8IB{QV+++&f`*Rtnzzr z@OU2@t++946plxv>H3J{I?3l&Oad(>0X^-jt8e#j>oUZ_?Fv!67|Y{~b@HpdnFkF{ zQ^(e897Ze!xyd5to161Ag$`X+?7%8sy>pZ1d)VK1s*);$*0KHDn-#e_iJ3qp(r>@^ z-9CJlfhjzf7&rlH`_fYqaU&8adMfMSAM*{^a=17-cW*%3d3Vkaq)CAe+WuKm zQj+`b?21#Zq3sizARMpo?_c}ZD)yXt!O)9v!pxHaIgvjK+3yDUHz#gbyng$*#!H~z zl8>*E6uBO$|H@yJm5pVbQizcDs5q;mH&9Q1?maG<;Ph%cbxt2U8=i!85Q-TkW$9Zp znXqSGTYi#<{hj57+g+^Si(nrDN85ws_EtB+#x?m&BeE_vI>GV@^jC= zZG|v0Qd{c${O;BEghbrt*HHpuo~>LxFQdb+ zOx`Wc_G@-G`DBzYb1ynSlaq9Po&r2BI|J}|EOOT1O1wTP@P6r@i^FKEsw)i}J!Gz^ zB~2xuA;^lM;bD3@Iso}XuHRW&y6?@u0Gc*yYh-LJA$ThSU-|en#>A+5dJ0PXY-?Kt zJvh)e^*0etMPv+bfc^q7)1bkpr>6y-S7T#iUylL}8faQ&ke zBU#|UbIs8)_ubN!I!jlXPF|ZN8J<>FZB5N^$I>pp4jdt=4!n-(wxLjyG_RB1Y0sTJ zOEr+aQQ99GYOJnr_U;{%n8i$mP(xmJwne3D<(Yy%JqsQTv3up`wD+2w<8-DcSVqiv z!PP9T?xID&-Uvr+&6nS?9OOS_$Mes$sTt2bS5h*30blal*ztL{zO_}Dnd!3B873dY z1e#XTva(%+gLt$@M;q!70zPQ}2+6IhOIFVL909s>z_J|5KD^;#BNWUP&5?62dJ}FY z304H?WdE!f%ej=i=V*j}RWa5c(%?mJ9U9ymNE*{Wms77azO{Mctw+C)`#wW9532Wp zU0Wk|X+=YF^T+hvE6IR_!s;P+_`PPLJE)5%w1FpG+xny=Y+_CD54175Ok&TZBm4#8 zy4i+v))j`a;6l{o@7`IdKAt+R^n{9)82gRhT%-0TRXa$xW$Sb4d*O}UdAPM=X=Ybj@`fk7cGwLahojCV{i zpV$-Pn%df(!*OY8v4R3`E$wQtC-|JFC%VKGB(DrKCV-U-mQdgOTLDVJ#qQ#mHa#-p zviCf-uI|D?Sa^S5^bvbFn!dWKDpIH95Rh5{$cUg|C09K`q%Adm%uk4+VvhShdm<1I`NQlEkcBpCzwIQaD}p#!Priad@a-9Nn}h2A{AR^n-{tkl$0QZg%DeXRu61aMWPRlAFS zAF`pK1nuoPP*cMO23|Ehefrd4tWX!&rN~7*_JAy6zkz_5nBQ$n2cQa}G-V$@HVQmE zF1zVxS4wtZJYhXBJ6Z?5y$E2>(5<#JOqdGryU%i_%RqzD*54Wzf`jo+4l$*!0Vy!mP^H=cK$jx}2<@MPT!{E1{1MBP05nKrMyx)aaq1C@_0{ zSew6W7w)aAT=-*YdBQp_E8U+cs6N}bp$er^S&t}>9+JSp5l!QF>p7H(ZvzS>of0xn zgW}wa+pC}T!jPj+snS_wwa+48B35_9EXr?w?=H`zQZa7gs(>&~i9y%~e~d|Sp75L3 zhrdBLvs!|aj&T_pZ}1p{epluL&M5N^a(=CO2;rC2pihgsh<%SMgV6WMm{FX6k&z6gcLm3XJkpmJ6G{Ff;W$evGA|&cnqcz{S(mb7o2q!z=h% zS>Tpc7`0xF5TdAd;3za>;3UfOynnM#Y&k|u^$z1$>yC6%EHt%c`)+x_W$QgFywr-! z0)F2%%RL*aKVdJs(2U5+vT6udG^a_7(Mcm)hQ%4g1!uX?2s35l&0G)NQznrZqMww@ zg|k@UgU@&GB@{p)KkqvMx4$9{NFDeuH|LXwX4#My7FJg1AMPv&dC<833;bTcuJ(sS zV*b=^)UvYb)>eoY;H$Q_}n#8scWrJ-{*~+p9I<>{>ePxOJ#8;6!*HS|Va;a%gEP<0gDBQ0i=N zJ}}aX=MAC3$gn1BVwQ0AmCM!ot)s^j0NGFZ-N__Kv%ZP*F|Mo*21;^nBGEmWtQ{T8 znwosAt-BB$x@_@jX@($&;s}lgHdSJmQ%+G)K`gJMv{2(~^K?Yp_738pRR&m52 zFPFy8_HANb9P)0-ZlA5i?w6qZ`)!y%Jm7EgYDou8z(ZYH=}I zTDasnz%^Z8NWTHet$}ep4L`pda1tY6;)w2URV^*h)y^|WzEdY#C0GE|+#BP@Nu=Z? z>`abHmP0{1JDRsj% z%!9*HC;pU1rZ;g(Wgm#rs=UXQMX)2fewW#PZe;&4A}2mDSCW;bt4N{BZewG^D*!Lo zVQa-#;4vfq%=knsT5713ZOM7+(!hpcsPDV<~!ou?D-B28>cD4!(V5#DQf_mHERYylh z#cmisqimextH(`YE4MwYY(8qQqy`1f7V01B)WS*-n*$$1^Xo7ZZhD*isA-Qjl`u~@ zt7vi$6*AiB0*8u?h28gG>Pn9;v#4vMqM8H&>tJ4feuL}j?oo=nokiwS+|tQ*W1Q>Z zR*(V?)mpXllz^-~K7p(TX65(q(-sIN#gAPI;SBBdoI0RW&GO`CX95JY*ug~oSk~lU z7#fBR%ya#&CMI6aF`s@3aCpMyo3(ITkE`F+<;7X%{0(;T&u;!d!}05yzrb;oz}0;Z zkDbf?F6zUB17NZCyS=&YilDX!mh%W$Qj+KCjv#qU_>f?!d2;SNH+>>~_?2tm>m&#vVDuqTwL=67FB_oWKZ*jehV0D!k z4GuivDvsw{s&;TtGbXF58SvVN{|=D#1m*z>Y|Gf|(!+#eGPS&n#fWn1crX#0*wSZ5 z(1-k{5IzsdBDzPb5eciFa5g#lW>7fwZCWBfDk>4)$-vaksk0oWV&u?U9-T?=mpD~Z z?W|dD56fk%{c=WuJ@krlARA<^2)pDm{^$%fv6bQ(92wEjxd7{h*Ca zNf8E=N^~@Sp&oF-fLgVE{{`C0@^Vdmy>XpOcUzl8^2OKRe~0dP>K}Sm_#3S)%XG@q zELTK4o_ddAsnh$|KGZb3*LY!xC_VVr&1`RBp-8dI>(#zztzCjkL`)m_-@y0qpM~q+ zlQ-Y(J4$g?mwq?Z$w?Otzh4Zu}&ba9bF6ZN@>ZGHV(77Dyf`S}R&8YOkQ%76}8JQD8oh=OqK~!y0KP~1cn&mn)Dmy~ zrkmnEv@R}@laX*InJ)&YA3gR^PwM6N32ox-TQ58;gJ;JR2W1!II-EK#GGbT1R_(U`U8rkc^CsA`^ki zM+$6I)*Q7w;G(9ab6E#jRAMpR?ePHd1817lDB&is^L>8ADdxIK7%zI~(@%cOf5G)F zJqbP)nYpE38yhLnp}|GpzNs5%JmysnNstO6G6yi-RW%B+xtTsXS`-o5-qYw4kAnJu z@DUMcPOhx2a2%fCQ_Cu18X7PQ@bOWK;N}z;i%s_{L!k)i&-86$z?)Q|Q|M~_Bj^DP zDduM@rDLn4WUJIS^|2IG6O3*ZJn*%OGiX!Ka$aRG7FC4s+ove-n<`6wxX&XN4GCyxp=%6XL zz81rb-l&-O1FRRJ_{3CJZ(pBnkc50%N~7p{cI@q!R$T(S{l3A|WVCE$^K`_0QUL$Z zKarR&@apQ`m`q?17DlInR0oa$5%-j1Z|{b>EOs^j)2|p0slcvGtX8-kQ+wJSwXl!_ zrD&gK2w%SK=gv-g_T|m8s2nAC>`ivk+|*Qles(sOj&o^te13j10I<1l#hIydUP z2Z>yzxau;Snc7=BKGuwjLw=(JZgQ60)gubk@m5w=7WSjPfnh7NY7zT4ECx*;pN{jR zx>iE-=NggocW4ZZyLC14qdp&=b;mFbyk$Z*Un_%pLNEh+pOBF7G2wNR9S`Yha-HM@ z{$^lo@nt=tQ<-F!dSFL*_R43a3ETIE_4-QtS3Qxa(iLg0@Ac*I+w3Pi8YC(( zY%*Rn+L5tNEe#FA!&?1n1o+4KV}q~b>#TwWh{aFc+!z@5Mn@ETdzE^7_qm%U+8LDk zGlu(afAzN(6QV$3z>=dZkYJ#K0ibdP&UvPa#`90ErQWJcjMU73P}K9jd(ZXmud!|9 zhr#wpMN&|Iq5U^%gFJ}1Ru`Nxujx{nR|i-<82l~lc(iqU(gY6P@GT& z3j_kpcn2<9R-Qm0+#gawd@sRI5C!~SZss`=r`d6wU5No5mX@hRL##1o%%+gXmfkx# zeF%g!>c-kc4S;muI4VH=@pC}FOlGEMs5Y#zDv4*`I>z#e+A|NTCMMl{h9 z5B-1!QZDnRf2u+F>I6U%D; zm6Co<^qo)RFRU~`3!vCv;E!k0_%$n9UncQaRysG{rPHF~8{LnhbzW8>_9xt_eHKd( zCmOADvXaV@%3gS^Z&p?DANfXS6~RLhReLC0j)86r^Z*tImJu4-3hNilg)_ML2|xyZ zd;=Ra@1)z#y|l|VW7 zTuPN`_8M0E&v2W6Ysx=BBY=^_@v%s3%1~Ud@gY+SiJ~I==V)Pn2X-}!iK_JBRKg~9 zb{}xPZm!M=6A)A@#G&uxL#VU43JQBjI4n=``l9H__E!TxFsA>0Sf1UZf%&Mani7(y58l7B_Y;J;{M`sjV z+jqAbH%H8V!Obr!$Qo2El~7mbv1$D`^k!h(;e6{U`M9|65w5Tkq2jlRTjzgJrJ#W# z!c?4}@AM@=^rj$VQQTP`&c5+=M>p+t+Ekt16=TD6d%H$yLjf31%Wn_5DS!J;Rhd_S z7$g<_YL)a0K`jo8-aG3`rPY>JcIcd=W$?4W4m(@X^s7riL2f44vW)JI^b&|ky5JQgS-8z%3ynXZLO9Bb`@RqDls@O4znxDNwL5|6c zfLyWBF&XLLC0B!gh85VXHg;B2nQ(Z1zMiHgDLx^M<8bmtW)2&R8q z>N>oB?x<>_udnZGw8L%B`RB>@xx$+H=?bf|v#YW#Y^5d)PS4L2&g#JNYB+U15^b)p z15o3}68@^ENmornXJB?V{614KkbIz>?c(|Ey+@Rk|8|LnPiR=>&51y-6K@ zyoPQD?6fGzvwx6!R}BJo!=3hFN3JtXi6=9arOjrnDczI9 zRA2?fp8->Ng{e+Ru=G5qQsVlSh{@Ko993R|;ZgW)W`iaz9Hx>!a;~NZCYWR{v+Qv? z6*I|3@S(=05Me7@f*k3pr3I)ce%xJR))Gp!Mup%iL(@N42Hk~d( ze>0u`7k~Rn15p~eZlc@|`~&UdW!2PH;->d$Q|^H?xxZ2vg5!Tz>tjiUrLh5GnXM-0 zF{F{iq$?OIA6OhD8mOx;IU1^bc&dN1Ia+{YkIujb@!}F(V>`ML>=od)uWs^wMA{Ub zdjf%YF`lonVM!bNA;TxWTl<+dzq8K0DL=K;53cQh%@+t(ihp4@K&3P|9T+NFM+EL3 z_14Ow*R*UeXWqpKlXm&FrM^yNgyyr8OH~_qDa~AKe|#<+5NrKi(G^1VKCDPRJ&PYm zi@;aYO^wy%cIk}{8?8%MZpxRd>q>fhdUh3S7-D2MauN-f{vf_L*+YJ<5?2B+*8uqk zf!QGM6Po_vi7kP|y4IM|IE%VC6c++1KPg)-v~+c~rk6mW7Csvu+x8;FsJi+c6==&< z*4fFcq|~Q0D4wPu`Wg2?f5Go;pah_M+V%wpe4MV5JsiR>EH3Piw6)nR(?mQCq|G5G z^Ams}Ffa%b-^YdQsYdzr1CCaOVmC80^Sik|mXV!Y)?yE67n)IQ?N=Q0fjk{rXE3~i zT{kCr(BLCHEaA$^{skZPkQJZ${jObs;;yTkz#*e6S$w;`>mhi zmL_ZSpMRxOJ@fGR8A+gTJNs%v8te3szUDKZ>5HaiNKi5B$beM(;N=j)mJo17* z@4klq8bRbZ3#NX4)Sr|HB%}Fwe1s6lBslBn;A%wqe9QaAj5g4zx@wpPofVzh&&Xxa ze+@ug1XkLR-;?t7W6LZ68m@94Jx8nM)FGj&n=(I$#j&D-eC@(@R$`G@zgH3M(d2sr zdO^mV2Zc~Q6B&UBy<7I1XqaEirsfA`m9!{dcI|PN6u&dy;!6-AY;cM)SFDfR6w-AI z10NE(enEwiV;JQxP=EVeUx9Do@gu#(?aFrj^}38PGJfdUp|*YLii+6zed7lZ=+(z= z-IEh~97c*LosdY|JCF-*f2XmJczf5Dkmoq>y$Ap2MD4$4ax;JFy42Oq57R*)?{z+* z?}G=td|7oRKhDr$K>3pk?!rfNH_a}5h4d4l6UHxq5Ktd(s^_%YJL!Ihqvi;vjFkjOYT-*4`uHJN+8-a(IL*lB`}eDh1tllNs6aW9Z7 z(lOZL#ZA_RtWwGjYzN<6jV$p4^m)%cU)4t`s|<^DNT49<>BY5!tkPieC56q0ZT zy|Mg}o1~I|2KD7UbN4Tztx_CW2dFM`LiA21gD;l%3V12P&B^;U<>M|C$eyl5Q0I!l z0G3UrAqds-H2lU!=QkhxX7DNcZc91o0taowxaiyp)#Yb=Y14$XZL19&R$jQm^>Ry-sDyD`bnbj0K_z@BdXcCn{>yj%3f{3xr#fVZv!(g?Q-%%2u8^~5?jc)s z(=o!u3Jh+ZLufHLpX~EX*v%LG^cYi2S}*9bdkm$Q*Mcdheyupg#NdzFeo+=n{<-2* zKeN^!WiGWI{42@axE4XS@bt;?uP|BZ74mP@sVbuEKZ0G&1M8QUW+=-yoK$veIHE>Y zkdx-rBu2m5I5gMO{VwQS$)Y~~^d#PG9xA!b;{rXZEHS-gy$!4JJ*T>b$a|M=5oOg* zrF^$`hWAruo-|R=wlD3AtoAF4I%D9d8EOi;W%eP**;?7-a?8;)RxR9BcSF>@G|nut)9R8}5`gsCc@U@?1l;*fvS)4#Ry)Uv4i{av2l;sHUL48`rW zKw;#Mg{_%Nvy5RhRC2HO&6d?_dlUg?i#0c@1&)pL8CphC*V+(wiZVkt*QZD~hgNJ1 zcEVA-2LD{cIZ+*Bv|c^#RLkr1*wUX!axvKM`SH-4pDFa28KS7^TYvKXVBwH_tnOb4R`AG&5i8|vM|}2Bv1Mc zsb7sD;N}_1Q>FY^tPz)<+JY5FV23&V#(jz^$Y~TYm>)B%bM|ivxIK->weiUo8_N?B z*PG3}L+#HP2TQ);9lw6~-@Cf&f7{P4>UGfjE!C#*>Hfftx4Yf7+tm?FVAt{4cA0RM z3pVQtn!7w=7ki^SqerxPsZI)-P;#Sr^`W(cFmw~m=*39!E>#1k8Z$ono4AT6Ff9?! z*u$XT6k;%Ov#~Aa2&eofutlYaDUu>#4Hfs?*{O%(nb}vgWvPg@h}&LWO{HV#I}8}2 zpD%Ga z*;gNI9doJ7XFA_9*r*7UlZg*fK5?;}KSrbp5>;|}neq`_)HM-o0bD1Af>u}UdzU1C?!uexJPpssH6VG6W zyABL_ybYml7|#&$zwZ=3@VB>D1jblk{Stg=jQMycbjdJd83K!D-m{adg_Zu&pkKPM zbUh2r_*E8ki&7Xmi7$GMSuI-j+Xs5BsiARpOZjoSE5fu&W^GN>6S&7D3rK#ln4UVOKG_X?olW$K$ROzP~ohB*OqE!>TJ-S>!wSzQY{fX`QME`?2 zY(^{s3}SUfS%#epyOxWC4>NcSF`imLZZfIPeB0ZQfGF(nEw-2zJ?xSf(bW(wYI&z6 zT11jB+gi_%PobZ(CjCcL z{zPg=5AVw|Re!H@*7*cp#laNi5Pd@r)N`wb18;7{N?D7V#6S_A8&2~<03BZ6DOZL^#!##X3Vp2@p9wE|Nm5;9p8_SA|tBQ+Ha@NCmEc!ZC?u0(+ zA_fz_({0NS)FtS308q^c!M1@AMpaXt{A-4qx?wHt6D(uA>(f|<8{|=v@lAaPH9w7s zC5QI?UZX!`?nYJ+N9&w(m$1wBFxwva&U*8mHNW5O_7UfF>A}EPBF2s& zKxhD+qN?g0R)f9Kaq_X?c;ZK8lUr^6S9~9Q{Zj}ktj}jeY1vD_w4&>hG`=JpKEYvJ z6F0s+FCxD-FYPL|cl-H2MqaNjcWw63#9;e-O*o}q?R-H8>dCfS%2GHk+0xMlwAzY7 z`4XHghcVvAaYD^-PS8dp8&+&eMRK^HHO)2nT&kpu-M{e35O(>5xV>qB!kzE88v9%a zRNb7-q>>i@`gI+DaW-4)TH&liZ>9$w+7}hB?${2q^*Qa2HrZ~3N{5s--4vKsU)Q`o z!3rGsPRf&TiE6UaU#t$UK}kU#KOfJnRTov^UO`DCVA-`%*h=#9dHJ~vNv~iZqR&`r zCdPwe#&;s4+3LP{LH`_<2nu^|G1hAD)_s}`j1Cv6#p2xug`9!rY=QrbfAZA;uXVO2 z$IR4@INbBPzNq9)p|CSKs;N=CaC-5=S8Uj#t}pRCi z7U8bDBjq~j+}dCqL6P8{kTrR1*si?)USE^DovjeGBh#cmJ8ybHG^EV+VVv(g&S3+s2!EkRf5>b50WR z@En@g)c+3g^aUEa@B1K6omb(w_yi{Re@M->I9wL{V3-y}rJeCm&LE%huS$HPK1rXX zblNC~%5NP^9)-+MX>$3!<{FfvOwsT*1+K(axIPxp}rPV=5Xdr?`?o`<_-;>+WSd3 z*>4}zm41y_rw~cAOLscR{gJpIU2wOoeAj$%V>PYEdmsF*BS9MTxu+k|@yu$veRQGi z4ad8TLk0;6fZ0l!KmH+iV9+yW+U$03^azCaJliVcO=WgCj~G)>2h-9 a7L`GB-Zw929|S)^Ao9}6QpFOl{r?Y`wm`%H literal 26765 zcmbrmbzGF;x-LARgtVlzfOL0Ni%c}-JRd-+P{6y z+UxB7{nq)uKTw!qW}f$n>%Ome3I70=#Y7`P1A#!8a_`@%fItYJfv+i4WZ)4Z8QE?S z=ru_0-CI?UjQvG-O?>!e+sToQF*^Cn4>n;&y-PZ{(Q=1M4QU?n_cr5i=&DF3hMIQ@ zVZ8jq7L&8yvEh)(6wMD+NZq&uNa$gx`@dNBkFXKHu>GWtOcBk7&xQWtHXmu^zRU77 zH#1M1r&LCMEy6YzgCmJr=g<_>ikS0x0ddUzTG*Y3iYf?a(|jbseZP0_nmMfr@oPqs zXOT0mBq{_<;^y7yZ3`^ZF05|!!@#E1yIi5u?@wIyS+yl88Y{cACV#G^D1 z{%_Q;gB*0WtQo%-=;j#)-WJ3-UiVRgUN!kJ`-sS%MuH+#c7su=x)vD@c1=n6Y#ekr zfq&apY5YGOUzQ!8koB`8M&Kh*1*Jpq3lwi#ngj?$vuKba0(NVO-UQ*e<4Hpj<(89) zit>7$zt6@6kf28_#*qJn5&VSbbVq6Tw?Cb#s6-F{^azSK)i4|!mzY*-`Zbz20PZx3 zYBMYLgY`%LfiRAhhJ2<|6Di&(p@U(;Rcvg+72vuN!w08Ugr)Rb8NnG`kMB*|>%Gc5 zQtl8_t`)d;rZax&eRX&t4I!gIqg+_sT8A4vq^a0s+&3SPt_en{so0pW2@Vt$!!t-; z2zXI_iQmfqWuDg&0zpU4B==Y1LN3SFht}v0iVbXjUlw%OMeD^SaH{C~Q>&#`p>_~x zZpFjcLqf}^pCDSUy}FaMWMU4}`gtHA8%H}J?`{|Y)E>}&uNXKpv7y(|D zsofX;?EWc{i}YgY6+gF*;r%Gl+|}Obq@^RaRe6PC5{>SA$l|1+*z!{E>i0n5>(h&v zGU=YT5V9U;nW0)&o`d^Xod|bhF{Cp#uB>O>6j%de>Qepv?=ll3XvHE(1}Lm%(7XA6 zil*g&Q&@L&g&UJ2QRS7$E~rVLMnm+Pwjyy(6;Dd~unX(e|Iz z>wg>E8~pJCcdx54Pzq{+#Ev5i�Q4dJ+=i%V8g{l3X;m-RQnEf_d1~XA~%IEja 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ℜ@RkQo`S3ug#ewv+SA z&wTxbTHHLN{wS^H_>qLi>To`+Jg%@ho`KsJ#0t-yyAJDm$HnX}<)0`RINd_du<`Ri z05S?19H2u^RAhF|YN*(l1Yy(D=D4BI1bZ`y#F`fts(D1r9DLcW#VQ;y0C-eV_p7!S z3X(YO-j&Z?Ywzrw4?#s7ZKI&&t|x+ATwF%0s93obsEs4OsH6F8QRjF8yh78g>MWav z3aVX)8b_MLqxVTVsvl-yW;G~mOmea5g=(Tcw}ZT4J|PBjn^M}qg}g>b3)$`0b}?n! zCm~7Qx9X%FE?2tXpTx0$ywXDz_{sHZXLJP_T?vgeXlOW5)ey95Db0Q1>l8zsh01dif5 zPB~U=-WA_UG!?yfsYZNVoxbo55F`VrZiyZXsOD;Q#S|IcnkcyMs zOFhsJxhEva1c4B7<9;K6%1=evE>=-dFYNq-xEA69V48&;F`WKMVBCa+LH)QbPK?0~ z1Mp9}%Q!<`Pj(TU-WM2R!g|U~MHQd(z=lv`vl?3wd$uMBZ2H1n!F0|i(|*8u>sIvb zE14}8B;_1a^a4m8#b+fBX0RA7?ypxL_PxABa=W9PCx53$^7_m{11SmZNO#zCGN*;n z#lWt96MpxDRBq=ku?9y>9Z=E%@vvRzd7andIFN~FZeigjS&7f)q;t>0Tu;_l!VRc; z%ddJj{6IPd#PME~kUJjqs?+!M6Y=M|J@^ooOF_oJ=h*EwraVDUOQHQvn%;Og=o1+& zlIR0HtV}xq@`1bH*py&{mj$1o;1J7vXt&!uiM^7h6xET}%C^uI)w#UkR@XfEvp+o) z)J@d=Y1=bMGmzcH-->fJh;aZ%u(Ujvm65q568A+lrV+FOj}+Szf)}2i$u->#K(#!Nw>;(e zAQJb~$cPe*4^Fd>DFu50H~j2e8yW5jDjgTMke{~uQ2Emv68^Dkw19i^n?S?>S==%$ z4NQ{rD=M;0d=s;exTU@2CU#b%Y&p=KdwhKQUfNwWRd-i?JVJVXZ(5rBJU;aZ+|> z!W$v0h)HbJCivxk{#mPHn-F+e?uWmWm6g?|KPHA=+nNQ#31%3AX!soWH4hzD@ay*1 z$3I#OteTIPs-Q8p*m&bD!WU73%#of648NpN;nE8ff}c9nz~#?9C)?aLe-fHU*%6rOril!1W(_rW@WV;Oex0B7XR)htT{ zv*JwnqnXBy#zeVys!Xd#=sq0Vw=&wJaRfJ11Yr}?a00>qi1XkGmrN4 zl=OR8A%xU*K?@MRpuqb_71urCDSKyt+r`leGodoeNx_F1?q_I;!?QIffO1j%8`=cj z+)Ja`Wo@o7$D^a8K&Q!sTv3Og!tOx%)poXc6V;Mj_$I=-v%A~)0P_~OCd?KJDl<$U za-z=E)#Xq#2>C}`J}py8mYysru?o{Cv&t$PmuwE=XZh{5afJElF$#Kmyb7%rvx{uL z|6b)~xGg;VOgC;@7@!TOU8YtJ`^U)OxfkeE@ zi%dng8?4hlU3S9nw=rEgQy=A2vCNuyD+N8>_vt&RnF zJ*^Y_#>k@+t@HZ=c|#qHVe!b70wqmRpO>HL71q%M*rLM09Hk3`bNV_#FFnP*HG}?* zIbfmwkZpX%0G`GYw!UQysxN-MhAjmKpJH-Yp$m+K8+ zBGBy=2G_6lIc+p)zC1xmC5O%z4Anv%kIssBo?n!op|`$#FC6^f5CrmET2U(RsqUBm E0v6%3*Z=?k diff --git a/doc/salome/gui/GEOM/images/distance.png b/doc/salome/gui/GEOM/images/distance.png index 594bef905b8b4726328375860e8d3c766bd34d80..31fa829fdea01f24fa2138e7e6ec97b3dbdcb7a4 100755 GIT binary patch literal 21548 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 literal 16262 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 DgnH_# diff --git a/doc/salome/gui/GEOM/images/hide_predef_material.PNG b/doc/salome/gui/GEOM/images/hide_predef_material.PNG new file mode 100755 index 0000000000000000000000000000000000000000..a9516fd003e4fda43155ddf237a37b9fe2794b25 GIT binary patch literal 22756 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 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/images/material.png b/doc/salome/gui/GEOM/images/material.png index 085921468d36bf9daa7df73290fe0e03d246fb18..bcdd1db22661da3386689addfa42c205bdae1648 100644 GIT binary patch literal 36593 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 S`9&=FPv()r!+eP+FaIB!$c0V- literal 33790 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�p^55!5Jlqba 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 diff --git a/doc/salome/gui/GEOM/images/materials_library.png b/doc/salome/gui/GEOM/images/materials_library.png new file mode 100755 index 0000000000000000000000000000000000000000..9ff8c390e7640d4f1e91c69cc034eb244d5ea0a6 GIT binary patch literal 31359 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 T;U>gLW64P?Kg^Xfc>n(aE$G<` literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/images/measures5.png b/doc/salome/gui/GEOM/images/measures5.png index 13af1afdfa7f0112c80a0725a3e3fa828c3b75d9..d2180be634371ff73d46022d56591c28793eaf7a 100755 GIT binary patch literal 20073 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 VY;Ga?0{CX4y%&>yTPULA^FPy$R_Oo$ literal 15614 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 DBkyg! diff --git a/doc/salome/gui/GEOM/images/mtrans2.png b/doc/salome/gui/GEOM/images/mtrans2.png index c61b1c3c140ce43d3b64ef77e8333bcaf23dfc7d..8f051425b4a8fa2be92f66fa5a3c1d79414659fd 100755 GIT binary patch literal 33003 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 RAN(2e?ya4VK>ZMq-lhA|druHTKmnx$ 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⩔Rmw!@6p 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 diff --git a/doc/salome/gui/GEOM/images/neo-mrot2.png b/doc/salome/gui/GEOM/images/neo-mrot2.png index f3f3c347ef64ec51b60409adfd3f2c556ef86a7c..b17098a7591331e3c69ecc52fdbf846fcf098f6e 100755 GIT binary patch literal 30397 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 diff --git a/doc/salome/gui/GEOM/images/pref15.png b/doc/salome/gui/GEOM/images/pref15.png index 3d9e5f6287301645f4f41ecda4eba5b5b81cffb2..f58d7309121558b538a94d5292b5d65b4a6186bc 100755 GIT binary patch literal 75408 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 z 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 literal 9949 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 l`;pIZZJIAu#{| diff --git a/doc/salome/gui/GEOM/images/show_predef_material.PNG b/doc/salome/gui/GEOM/images/show_predef_material.PNG new file mode 100755 index 0000000000000000000000000000000000000000..922abce5a282e52e0772e2d44842e60072f029c4 GIT binary patch literal 26551 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 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/input/boudaries.doc b/doc/salome/gui/GEOM/input/boudaries.doc index 65acdc06a..de1e84a73 100644 --- a/doc/salome/gui/GEOM/input/boudaries.doc +++ b/doc/salome/gui/GEOM/input/boudaries.doc @@ -2,8 +2,10 @@ \page boundaries_page Check Free Boundaries -Detects and highlights wires and edges that are not shared between +Detects and highlights wires and edges that are not shared between two faces and are considered a shape's boundary. +
Creates corresponding objects and publishes them into the study on +"Apply" or "Apply and Close". TUI Command: (NoError, ClosedWires, OpenWires) = geompy.GetFreeBoundary(Shape), where \em Shape is a shape to be @@ -15,4 +17,4 @@ See also a \ref tui_free_boundaries_page "TUI example". \image html repair9.png -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/GEOM/input/bounding_box.doc b/doc/salome/gui/GEOM/input/bounding_box.doc index eeb16c4ff..75b7c7eaf 100644 --- a/doc/salome/gui/GEOM/input/bounding_box.doc +++ b/doc/salome/gui/GEOM/input/bounding_box.doc @@ -2,8 +2,10 @@ \page bounding_box_page Bounding Box -Returns the dimensions of the bounding box for the selected -geometrical object. +Shows the dimensions of the bounding box for the selected +geometrical object. Creates corresponding shape (box) on "Apply". + +\image html measures5.png \note To take into account any possible shape distortion that affects the resulting bounding box, the algorithm enlarges @@ -12,14 +14,10 @@ faces (by iterating through all faces of a shape). This functionallity is implemented in such a way to have a satisfactory performance. -Result: Displays the bounding box dimensions of a -geometrical object in form of a Python Tuple (Xmin, Xmax, Ymin, -Ymax, Zmin, Zmax). -\n TUI Command: geompy.BoundingBox(Shape), where \em Shape +\n TUI Commands: [Xmin,Xmax, Ymin,Ymax, Zmin,Zmax] = geompy.BoundingBox(Shape), +BBox = geompy.MakeBoundingBox(Shape), where \em Shape is the shape for which a bounding box is computed. See also a \ref tui_bounding_box_page "TUI example". -\image html measures5.png - */ diff --git a/doc/salome/gui/GEOM/input/creating_curve.doc b/doc/salome/gui/GEOM/input/creating_curve.doc index 9c3371826..29cbbc8d1 100644 --- a/doc/salome/gui/GEOM/input/creating_curve.doc +++ b/doc/salome/gui/GEOM/input/creating_curve.doc @@ -70,10 +70,15 @@ closed edge.

  • If Reorder vertices taking into account distances is checked, the interpolation algorithm does not follow the order of vertices but searches for the closest vertex.
  • +
  • Tangents are two vectors, defining direction of curve at +its ends. Both or none vectors must be set. This option available only +if two above check boxes are not checked. +
  • \n TUI Command: -geompy.MakeInterpol(ListOfShapes,isClosed,doReordering) +
    geompy.MakeInterpol(ListOfShapes,isClosed,doReordering) +
    geompy.MakeInterpolWithTangents(ListOfShapes,Vector1,Vector2) Analytical Definition diff --git a/doc/salome/gui/GEOM/input/geometry_preferences.doc b/doc/salome/gui/GEOM/input/geometry_preferences.doc index 00301daf9..d0c94768d 100644 --- a/doc/salome/gui/GEOM/input/geometry_preferences.doc +++ b/doc/salome/gui/GEOM/input/geometry_preferences.doc @@ -36,8 +36,10 @@ of values set in spin boxes.
  • Deflection coefficient - allows to define default deflection coefficient for lines and surfaces. A smaller coefficient provides better quality of a shape in the viewer.
  • -
  • Default front material - allows to define default front face material.
  • -
  • Default back material - allows to define default back face material.
  • +
  • Show predefined materials in popup menu - allows to customize the displaying of popup menu with list of +predefined materials.
  • +
  • Default material - allows to define default material.
  • +
  • Subshapes color for editing a group - allows to select default color for subshapes in a group.
  • Edges width - allows to define default width of the edges.
  • Isolines width - allows to define default width of the isolines.
  • Preview edges width - allows to define width of the edges for preview.
  • diff --git a/doc/salome/gui/GEOM/input/geompy.doc b/doc/salome/gui/GEOM/input/geompy.doc index 1ab9a5b9d..f34f87fe1 100644 --- a/doc/salome/gui/GEOM/input/geompy.doc +++ b/doc/salome/gui/GEOM/input/geompy.doc @@ -40,6 +40,7 @@ provided by Geometry module.
  • \ref tui_test_others_page
  • \ref tui_test_spanner_page
  • \ref tui_test_all_page
  • +
  • \ref tui_test_measures_page
  • diff --git a/doc/salome/gui/GEOM/input/material.doc b/doc/salome/gui/GEOM/input/material.doc index 4960e06f3..09791f2f7 100644 --- a/doc/salome/gui/GEOM/input/material.doc +++ b/doc/salome/gui/GEOM/input/material.doc @@ -12,7 +12,21 @@ be changed in the future versions of SALOME Geometry module. \n You can change the material properties of the selected shape(s) in the dedicated dialog box. This dialog box can be invoked from the -context popup menu using "Material properties" item: +context popup menu. + +\n Appearance of popup menu can be customizable via +"Show predefined materials in popup menu" option from preferences. +If this option is switched off, only "Material properties" item will +be shown in popup menu. If this option is on (by default), "Material +properties" item in popup menu will open submenu listing predefined +materials and additionally "Custom..." item. + +\n "Show predefined materials in popup menu" option is switched off: +\image html hide_predef_material.PNG +\n "Show predefined materials in popup menu" option is switched on +\image html show_predef_material.PNG + +\n"Custom..." or "Material properties" item will open dialog box: \image html material.png @@ -22,6 +36,12 @@ shape presentation; - assign one of predefined global materials to the shape; - create a custom material model and apply it to the shape. +\n You also can work with custom materials in the "Materials library" dialog box. +This dialog box can be invoked from the "Tools" main menu using +"Materials library" item: + +\image html materials_library.png + \note This functionality is available in both OCC and VTK 3D viewers. However, note that due to the differencies between underlying API of OCC and VTK libraries the behaviour of the functionality related to @@ -80,8 +100,7 @@ scattered light tends to be red, although the light directly striking objects is white. OpenGL allows you to set the red, green, and blue values for each component of light independently. -\section material Material properties dialog box - +\section material_lib Materials library dialog box The dialog box consists of two parts: - The list box at the left shows all available material models, both predefined by the application and custom one specified by the user. @@ -98,22 +117,8 @@ it simulates light originating from an object. - \b Shininess - \b Type of material model: \em physical or \em artificial. -If the material model is specified as a \em physical one (like \em Gold, -for instance), this means that the color of the shape (more precisely -its \em ambient color) can not be modified. If you assign a physical -material model to the shape, the "Color" menu item will not be -available in the popup menu. - -If the model is non-physical (\em artificial), the color can be changed -to any appopriate one, only other attributes will be constant. In the -dialog box you will be able to modify the color of the shape via the -"Color" button. "Ambient color" button becomes disabled to signalize -that this attribute of the model is ignored. Also, it will be possible -to modify the color of the shape via the -\ref color_page "corresponding popup menu command". - All available predefined material models are shown in the list box of -the Color and Material Properties dialog: +the Materials dialog dialog: - [Current] item in the list corresponds to the material model currently assigned to the selected shape(s). This model can be freely modified by the user. @@ -130,6 +135,26 @@ is shown if the user presses right mouse button in the materials list box. An additional "Rename material" command, available in popup menu, can be used to change the name of material model. +\section material Material properties dialog box + +The dialog box looks like "Materials library" dialog box but has +some additions in the form of selection objects mechanizm and "Color" +property. + +If the material model is specified as a \em physical one (like \em Gold, +for instance), this means that the color of the shape (more precisely +its \em ambient color) can not be modified. If you assign a physical +material model to the shape, the "Color" menu item will not be +available in the popup menu. + +If the model is non-physical (\em artificial), the color can be changed +to any appopriate one, only other attributes will be constant. In the +dialog box you will be able to modify the color of the shape via the +"Color" button. "Ambient color" button becomes disabled to signalize +that this attribute of the model is ignored. Also, it will be possible +to modify the color of the shape via the +\ref color_page "corresponding popup menu command". + Examples: \image html material_OCC.png diff --git a/doc/salome/gui/GEOM/input/min_distance.doc b/doc/salome/gui/GEOM/input/min_distance.doc index 690a17f3a..9653e2210 100644 --- a/doc/salome/gui/GEOM/input/min_distance.doc +++ b/doc/salome/gui/GEOM/input/min_distance.doc @@ -3,14 +3,33 @@ \page min_distance_page Min. Distance Returns the minimum distance between two geometrical objects and -the coordinates of the vector of distance and shows the vector in the viewer. +the coordinates of the vector of distance and shows the distance in +the viewer. -TUI Command: geompy.MinDistance(Shape1, Shape2), -where \em Shape1 and \em Shape2 are shapes between which the minimal +\note The minimal distance searching task can have one or more +solutions, and also it can have an infinite set of solutions. All +found solutions are listed in dedicated combobox. When the user +selects any one of found solutions, presentation is displayed in the +OCC viewer and fields "Length", "DX", "DY" and "DZ" are filled with +corresponding values. If there are no solutions found, text "No +solution found" will be shown instead of solutions list; this could +mean what the task has an infinite number of solutions. + +\n \note Currently used OCCT functionality finds finite number of +solutions even in cases, where an infinite set of solutions exists. + +\n On \b Apply or Apply and Close it creates a set of closest +points of the shapes, corresponding to all found solutions. + +TUI Commands: +\naDist = geompy.MinDistance(Shape1, Shape2), +\n[aDist, DX, DY, DZ] = geompy.MinDistanceComponents(Shape1, Shape2), +\n[nbSols, (x11, y11, z11, x21, y21, z21, ...)] = geompy.ClosestPoints(Shape1, Shape2), +\n where \em Shape1 and \em Shape2 are shapes between which the minimal distance is computed. See also a \ref tui_min_distance_page "TUI example". \image html distance.png -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/GEOM/input/multi_rotation_operation.doc b/doc/salome/gui/GEOM/input/multi_rotation_operation.doc index cdc6234a1..0238f6334 100644 --- a/doc/salome/gui/GEOM/input/multi_rotation_operation.doc +++ b/doc/salome/gui/GEOM/input/multi_rotation_operation.doc @@ -5,24 +5,28 @@ \n To produce a Multi Rotation in the Main Menu select Operations - > Transformation - > Multi Rotation -\n This operation creates several geometrical objects rotated in one -or two dimensions basing on the initial geometrical object. -\n The \b Result will be one or several \b GEOM_Objects (compound). +\n This operation creates a compound of several shapes rotated in one +or two dimensions basing on the initial shape. +\n The \b Result will be one \b GEOM_Object (compound). \n To produce a Simple Multi Rotation (in one dimension) you -need to define a \b Shape to be rotated, an \b Axis of rotation and a -Number of Times the shape must be rotated. Rotation Angle will -be 2 * \a PI / \a NbTimes. Number of shapes in the resulting compound will be equal -to \a NbTimes (if \a NbTimes = 1, the result will contain only the initial -non-transformed shape). -\n TUI Command: geompy.MultiRotate1D(Shape, Axis, NbTimes) -\n Arguments: Name + 1 shape + 1 vector for direction + 1 value -(repetition). +need to define a \b Shape to be rotated, an \b Axis of rotation (DZ by +default), Angle of rotation (optionally) and a Number of Times +the shape must be rotated. If Angular step is not defined +(checkbox is not checked), it will be 2 * \a PI / \a NbTimes. Number +of shape's copies in the resulting compound will be equal to +\a NbTimes (if \a NbTimes = 1, the result will contain only the +initial non-transformed shape). + +\n TUI Commands: +\n geompy.MultiRotate1DNbTimes(Shape, Axis, NbTimes) +\n geompy.MultiRotate1DByStep(Shape, Axis, AngleStep, NbTimes) \b NB! There is another way to execute a Multi-rotation operation, which is currently accessible only via TUI commands: -geompy.MakeMultiRotation1D(Shape, Dir, Point, NbTimes) which works in -the same way, but the Axis is defined by direction and point. +geompy.MakeMultiRotation1DNbTimes(Shape, Dir, Point, NbTimes), +geompy.MakeMultiRotation1DByStep(Shape, Dir, Point, AngleStep, NbTimes), +which works in the same way, but the Axis is defined by direction and point. \image html neo-mrot1.png @@ -31,23 +35,27 @@ the same way, but the Axis is defined by direction and point. \image html multi_rotation1d2.png "The result of a simple multi-rotation" \n Double Multi Rotation (in two dimensions) rotates the given -\b Object around the given \b Axis on the given \b Angle a given -Number of Times and multi-translates each rotation -result. Translation direction passes through the center of gravity of -the rotated shape and its projection on the rotation axis. Number of -shapes in the resulting compound will be equal to \a NbTimes1 x \a NbTimes2 (if -both \a NbTimes1 and \a NbTimes2 are equal to 1, the result will contain +\b Object around the given \b Axis (DZ by default) on the given +\b Angle (optional) a given Number of Times and +multi-translates each rotation result. +If Angular step is not defined (checkbox is not checked), it +will be 2 * \a PI / \a NbTimes. +Translation direction passes through the center of gravity of the +initial shape and its projection on the rotation axis. Number of +shape's copies in the resulting compound will be equal to \a NbTimes1 x \a NbTimes2 +(if both \a NbTimes1 and \a NbTimes2 are equal to 1, the result will contain only the initial non-transformed shape). \b Reverse checkbox allows to set the direction of rotation. -\n TUI Command: geompy.MultiRotate2D(Shape, Axis, Angle, NbTimes1, Step, NbTimes2) -\n Arguments: Name + 1 shape + 1 vector for direction + 1 angle -+ 1 value (repetition) + 1 step value + 1 value (repetition). + +\n TUI Commands: +\n geompy.MultiRotate2DNbTimes(Shape, Axis, NbTimes1, RadialStep, NbTimes2) +\n geompy.MultiRotate2DByStep(Shape, Axis, AngleStep, NbTimes1, RadialStep, NbTimes2) NB! There is another way to execute a Double Multi-rotation operation, which is currently accessible only via TUI commands: -geompy.MakeMultiRotation2D(Shape, Dir, Point, Angle, nbtimes1, Step,nbtimes2) -which works in the same way, -but the Axis is defined by direction and point. +geompy.MakeMultiRotation2DNbTimes(Shape, Dir, Point, NbTimes1, RadialStep, NbTimes2), +geompy.MakeMultiRotation2DByStep(Shape, Dir, Point, AngleStep, NbTimes1, RadialStep, NbTimes2), +which works in the same way, but the Axis is defined by direction and point. \image html neo-mrot2.png diff --git a/doc/salome/gui/GEOM/input/multi_translation_operation.doc b/doc/salome/gui/GEOM/input/multi_translation_operation.doc index 0d084f3c1..6274ad9b4 100644 --- a/doc/salome/gui/GEOM/input/multi_translation_operation.doc +++ b/doc/salome/gui/GEOM/input/multi_translation_operation.doc @@ -7,9 +7,8 @@ select Operations - > Transformation - > Multi Translation \n This operation makes several translations of a shape in \b one or \b two directions. -\n The \b Result will be one or several \b GEOM_Objects -(compound). The total number of shapes in the resulting compound (for -a single initial selected shape) will be equal to: +\n The \b Result will be one \b GEOM_Object (compound). The total +number of shape copies in the resulting compound will be equal to: - in case of \ref single_multi_translation "Single multi translation": \a NbTimes (if \a NbTimes parameter is equal to 1, the result will contain only the initial non-translated shape). @@ -21,14 +20,11 @@ initial shape). \anchor single_multi_translation \n To produce a Simple Multi Translation (in one direction) you need to indicate an \b Object to be translated, a \b Vector of -translation, a \b Step of translation and a Number of Times the -Object should be duplicated. If a curve has been selected instead of -the Vector, only its first and last vertices will be used to get the vector direction -and the dialog preview will display the vector along which the object will be translated. -\n TUI Command: geompy.MakeMultiTranslation1D(Shape, Dir, -Step, NbTimes) -\n Arguments: Name + 1 shape + 1 vector (for direction) + 1 -step value + 1 value (repetition). +translation (DX by default), a \b Step of translation and a Number +of Times the Object should be duplicated. If a curve has been +selected instead of the Vector, only its first and last vertices will +be used to get the vector direction and the dialog preview will +display the vector along which the object will be translated. \image html mtrans1.png @@ -36,12 +32,26 @@ step value + 1 value (repetition). \image html multi_translation1dsn.png "The result of a simple multi-translation" +\n TUI Command: geompy.MakeMultiTranslation1D(Shape, Dir, +Step, NbTimes) +\n Arguments: Name + 1 shape + 1 vector (for direction) + 1 +step value + 1 value (repetition). + \anchor double_multi_translation \n To produce a Double Multi Translation (in two directions) you need to indicate an \b Object to be translated, and, for both axes, a \b -Vector of translation, a \b Step of translation and a Number of Times the shape must be duplicated. -If a curve has been selected instead of the Vector, only its first and last vertices will be used to get the vector direction -and the dialog preview will display the vector along which the object will be translated. +Vector of translation (DX and DY by default), a \b Step of translation +and a Number of Times the shape must be duplicated. +If a curve has been selected instead of the Vector, only its first and +last vertices will be used to get the vector direction and the dialog +preview will display the vector along which the object will be +translated. + +\image html mtrans2.png + +\image html multi_translation_initialsn.png "The initial object" + +\image html multi_translation2dsn.png "The result of a double multi-translation" \n TUI Command: geompy.MakeMultiTranslation2D(Shape, Dir1, Step1, NbTimes1, Dir2, Step2, NbTimes2), where \em Shape is a shape @@ -53,12 +63,6 @@ along \em Dir2. \n Arguments: Name + 1 shape + 2 vectors defining the direction + 2 step values + 2 values (repetitions). -\image html mtrans2.png - -\image html multi_translation_initialsn.png "The initial object" - -\image html multi_translation2dsn.png "The result of a double multi-translation" - Our TUI Scripts provide you with useful examples of the use of \ref tui_multi_translation "Transformation Operations". diff --git a/doc/salome/gui/GEOM/input/tui_3dsketcher.doc b/doc/salome/gui/GEOM/input/tui_3dsketcher.doc index 4916dfce2..9afadc9ca 100755 --- a/doc/salome/gui/GEOM/input/tui_3dsketcher.doc +++ b/doc/salome/gui/GEOM/input/tui_3dsketcher.doc @@ -1,49 +1,7 @@ /*! \page tui_3dsketcher_page 3D Sketcher - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# Create a 3D sketcher (wire) on the given points coordinates -sketcher1 = geompy.Make3DSketcher([ 0,0,0, 50,50,50, 0,50,0, 50,0,50, 10,20,100, 0,0,0 ]) - -# add object in the study -id_sketcher1 = geompy.addToStudy(sketcher1, "Sketcher1") - -# display the sketcher -gg.createAndDisplayGO(id_sketcher1) - -# Create a 3D sketcher (wire) with Sketcher3D interface - -# get the interface instance -sk = geompy.Sketcher3D() - -# add three points with absolute coordinates -# the first point will be the start point of sketcher -# two segments will be added by this command -sk.addPointsAbsolute(1,2,3, 7,0,0, 10,-3.5,-11) - -# add one segment, defined by two angles in "OXY" coordinate system and length -sk.addPointAnglesLength("OXY", 45, 0, 100) - -# add three points with relative coordinates -# three segments will be added by this command -sk.addPointsRelative(20,0,0, 20,0,100, -40,0,-50) - -# set to close the sketcher -sk.close() - -# obtain the sketcher result -sketcher2 = sk.wire() - -# add object in the study -id_sketcher2 = geompy.addToStudy(sketcher2, "Sketcher2") - -# display the sketcher -gg.createAndDisplayGO(id_sketcher2) -\endcode +\include 3dsketcher.py +
    Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_advanced_geom_objs.doc b/doc/salome/gui/GEOM/input/tui_advanced_geom_objs.doc index 1d469e9e8..1f513a496 100644 --- a/doc/salome/gui/GEOM/input/tui_advanced_geom_objs.doc +++ b/doc/salome/gui/GEOM/input/tui_advanced_geom_objs.doc @@ -4,119 +4,18 @@ \anchor tui_creation_pipetshape

    Creation of PipeTShape

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create PipeTShape object -pipetshape = geompy.MakePipeTShape(80.0, 20.0, 200.0, 50.0, 20.0, 200.0) - -# add object in the study -id_pipetshape = geompy.addToStudy(pipetshape[0],"PipeTShape") -# add groups in the study -for g in pipetshape[1:]: - geompy.addToStudyInFather(pipetshape[0], g, g.GetName()) - -# Create junction vertices -P1 = geompy.MakeVertex(0.0, 0.0, 0.0) -P2 = geompy.MakeVertex(400.0, 0.0, 0.0) -P3 = geompy.MakeVertex(200.0, 0.0, 200.0) - -# create PipeTShape object with position -pipetshape_position = geompy.MakePipeTShape(80.0, 20.0, 200.0, 50.0, 20.0, 200.0, True, P1, P2, P3) - -# add object in the study -id_pipetshape_position = geompy.addToStudy(pipetshape_position[0],"PipeTShape_position") -# add groups in the study -for g in pipetshape_position[1:]: - geompy.addToStudyInFather(pipetshape_position[0], g, g.GetName()) - -# create PipeTShape with chamfer object -pipetshapechamfer = geompy.MakePipeTShapeChamfer(80.0, 20.0, 200.0, 50.0, 20.0, 200.0, 20.0, 20.0) - -# add object in the study -id_pipetshapechamfer = geompy.addToStudy(pipetshapechamfer[0],"PipeTShapeChamfer") -# add groups in the study -for g in pipetshapechamfer[1:]: - geompy.addToStudyInFather(pipetshapechamfer[0], g, g.GetName()) - -# create PipeTShape with chamfer object with position -pipetshapechamfer_position = geompy.MakePipeTShapeChamfer(80.0, 20.0, 200.0, 50.0, 20.0, 200.0, 20.0, 20.0, True, P1, P2, P3) - -# add object in the study -id_pipetshapechamfer_position = geompy.addToStudy(pipetshapechamfer_position[0],"PipeTShapeChamfer_position") -# add groups in the study -for g in pipetshapechamfer_position[1:]: - geompy.addToStudyInFather(pipetshapechamfer_position[0], g, g.GetName()) - -# create PipeTShape with fillet object -pipetshapefillet = geompy.MakePipeTShapeFillet(80.0, 20.0, 200.0, 50.0, 20.0, 200.0, 5.0) - -# add object in the study -id_pipetshapefillet = geompy.addToStudy(pipetshapefillet[0],"PipeTShapeFillet") -# add groups in the study -for g in pipetshapefillet[1:]: - geompy.addToStudyInFather(pipetshapefillet[0], g, g.GetName()) - -# create PipeTShape with fillet object with position -pipetshapefillet_position = geompy.MakePipeTShapeFillet(80.0, 20.0, 200.0, 50.0, 20.0, 200.0, 5.0, True, P1, P2, P3) - -# add object in the study -id_pipetshapefillet_position = geompy.addToStudy(pipetshapefillet_position[0],"PipeTShapeFillet_position") -# add groups in the study -for g in pipetshapefillet_position[1:]: - geompy.addToStudyInFather(pipetshapefillet_position[0], g, g.GetName()) - - -# display pipetshapes -gg.createAndDisplayGO(id_pipetshape) -gg.createAndDisplayGO(id_pipetshape_position) -gg.createAndDisplayGO(id_pipetshapechamfer) -gg.createAndDisplayGO(id_pipetshapechamfer_position) -gg.createAndDisplayGO(id_pipetshapefillet) -gg.createAndDisplayGO(id_pipetshapefillet_position) - -\endcode +\include advanced_geom_objs_ex01.py +Download this script \anchor tui_creation_divideddisk

    Creation of DividedDisk

    - -\code -import geompy -import salome -import GEOM -gg = salome.ImportComponentGUI("GEOM") - -# create DividedDisk object -divideddisk = geompy.MakeDividedDisk(100, 1, GEOM.SQUARE) - -# add object in the study -id_divideddisk = geompy.addToStudy(divideddisk,"DividedDisk") - -# display divideddisk -gg.createAndDisplayGO(id_divideddisk) -\endcode +\include advanced_geom_objs_ex02.py +Download this script \anchor tui_creation_dividedcylinder

    Creation of DividedCylinder

    - -\code -import geompy -import salome -import GEOM -gg = salome.ImportComponentGUI("GEOM") - -# create DividedCylinder object -dividedcylinder = geompy.MakeDividedCylinder(100, 300, GEOM.SQUARE) - -# add object in the study -id_dividedcylinder = geompy.addToStudy(dividedcylinder,"DividedCylinder") - -# display dividedcylinder -gg.createAndDisplayGO(id_dividedcylinder) -\endcode +\include advanced_geom_objs_ex03.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_angle.doc b/doc/salome/gui/GEOM/input/tui_angle.doc index fa459d31e..e1618fb30 100644 --- a/doc/salome/gui/GEOM/input/tui_angle.doc +++ b/doc/salome/gui/GEOM/input/tui_angle.doc @@ -1,67 +1,7 @@ /*! \page tui_angle_page Angle - -\code -import salome -salome.salome_init() - -import math -import geompy -geompy.init_geom(salome.myStudy) - -OX = geompy.MakeVectorDXDYDZ(10, 0,0) -OXY = geompy.MakeVectorDXDYDZ(10,10,0) - -# in one plane -Angle = geompy.GetAngle(OX, OXY) - -print "\nAngle between OX and OXY = ", Angle -if math.fabs(Angle - 45.0) > 1e-05: - print " Error: returned angle is", Angle, "while must be 45.0" - pass - -Angle = geompy.GetAngleRadians(OX, OXY) - -print "\nAngle between OX and OXY in radians = ", Angle -if math.fabs(Angle - math.pi/4) > 1e-05: - print " Error: returned angle is", Angle, "while must be pi/4" - pass - -Angle = geompy.GetAngleVectors(OX, OXY, True) - -print "\nAngle between vectors OX and OXY = ", Angle -if math.fabs(Angle - 45.0) > 1e-05: - print " Error: returned angle is", Angle, "while must be 45.0" - pass - -Angle = geompy.GetAngleRadiansVectors(OX, OXY, False) - -print "\nBig angle between vectors OX and OXY in radians = ", Angle -if math.fabs(Angle - math.pi*7./4.) > 1e-05: - print " Error: returned angle is", Angle, "while must be 7*pi/4" - pass - -# not in one plane -OXY_shift = geompy.MakeTranslation(OXY,10,-10,20) -Angle = geompy.GetAngle(OX, OXY_shift) - -print "\nAngle between OX and OXY_shift = ", Angle -if math.fabs(Angle - 45.0) > 1e-05: - print " Error: returned angle is", Angle, "while must be 45.0" - pass - -# not linear -pnt1 = geompy.MakeVertex(0, 0, 0) -pnt2 = geompy.MakeVertex(10, 0, 0) -pnt3 = geompy.MakeVertex(20, 10, 0) -arc = geompy.MakeArc(pnt1, pnt2, pnt3) -Angle = geompy.GetAngle(OX, arc) - -if (math.fabs(Angle + 1.0) > 1e-6 or geompy.MeasuOp.IsDone()): - print "Error. Angle must not be computed on curvilinear edges" - pass - -\endcode +\include angle.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_basic_geom_objs.doc b/doc/salome/gui/GEOM/input/tui_basic_geom_objs.doc index 7f230b142..fcb21c268 100644 --- a/doc/salome/gui/GEOM/input/tui_basic_geom_objs.doc +++ b/doc/salome/gui/GEOM/input/tui_basic_geom_objs.doc @@ -4,423 +4,47 @@ \anchor tui_creation_point

    Creation of a Point

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p0 = geompy.MakeVertex(0., 0., 0.) -p100 = geompy.MakeVertexWithRef(p0, 100., 100., 100.) -px = geompy.MakeVertex(100., 0., 0.) -py = geompy.MakeVertex(0., 100., 0.) -pz = geompy.MakeVertex(0., 0., 100.) -p1 = geompy.MakeVertex(50., 50., 30.) - -# create a curve and vertices on it -Arc = geompy.MakeArc(py, pz, px) -# create a vertex by parameter -p_on_arc = geompy.MakeVertexOnCurve(Arc, 0.25) -# create a vertex by length -p_on_arc2 = geompy.MakeVertexOnCurveByLength(Arc, 50., None) -#create a vertex by point projection -p_on_arc3 = geompy.MakeVertexOnCurveByCoord(Arc, 100, -10, 10) - -# create 2 lines and make a point on its intersection -line_1 = geompy.MakeLineTwoPnt(p0, p100) -line_2 = geompy.MakeLineTwoPnt(p1, pz) -p_inter = geompy.MakeVertexOnLinesIntersection(line_1, line_2) - -# create a face and vertices on it -Add_line = geompy.MakeLineTwoPnt(px, py) -arc_face = geompy.MakeFaceWires([Arc, Add_line], 1) -p_on_face1 = geompy.MakeVertexOnSurface(arc_face, 0.5, 0.5) -p_on_face2 = geompy.MakeVertexOnSurfaceByCoord(arc_face, 35, 35, 35) -p_on_face3 = geompy.MakeVertexInsideFace(arc_face) - - -# add objects in the study -id_p0 = geompy.addToStudy(p0, "Vertex 0") -id_p100 = geompy.addToStudy(p100, "Vertex 100") -id_px = geompy.addToStudy(px, "Vertex X") -id_py = geompy.addToStudy(py, "Vertex Y") -id_pz = geompy.addToStudy(pz, "Vertex Z") -id_Arc = geompy.addToStudy(Arc, "Arc") -id_line_1 = geompy.addToStudy(line_1, "Line 1") -id_line_2 = geompy.addToStudy(line_2, "Line 2") -id_p_on_arc = geompy.addToStudy(p_on_arc, "Vertex on Arc by parameter") -id_p_on_arc2 = geompy.addToStudy(p_on_arc2, "Vertex on Arc by length") -id_p_on_arc3 = geompy.addToStudy(p_on_arc3, "Vertex on Arc by point projection") -id_p_inter = geompy.addToStudy(p_inter, "Vertex on Lines Intersection") -id_p_on_face1 = geompy.addToStudy(p_on_face1, "Vertex on face by parameter") -id_p_on_face2 = geompy.addToStudy(p_on_face2, "Vertex on face by point projection") -id_p_on_face3 = geompy.addToStudy(p_on_face3, "Vertex inside face") - -# display vertices -gg.createAndDisplayGO(id_p0) -gg.createAndDisplayGO(id_p100) -gg.createAndDisplayGO(id_Arc) -gg.createAndDisplayGO(id_p_inter) -gg.createAndDisplayGO(id_p_on_arc) -gg.createAndDisplayGO(id_p_on_arc2) -gg.createAndDisplayGO(id_p_on_arc3) -\endcode +\include basic_geom_objs_ex01.py +Download this script \anchor tui_creation_line

    Creation of a Line

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p0 = geompy.MakeVertex(0., 0., 0.) -p100 = geompy.MakeVertexWithRef(p0, 100., 100., 100.) -px = geompy.MakeVertex(100., 0. , 0. ) -py = geompy.MakeVertex(0. , 100., 0. ) -pz = geompy.MakeVertex(0. , 0. , 100.) - -# create a vector from two points -vxy = geompy.MakeVector(px, py) - -# create a line from a point and a vector -line1 = geompy.MakeLine(pz, vxy) - -#create a line from two points -line2 = geompy.MakeLineTwoPnt(p0, p100) - -# add objects in the study -id_vxy = geompy.addToStudy(vxy, "Vector") -id_line1 = geompy.addToStudy(line1,"Line1") -id_line2 = geompy.addToStudy(line2,"Line2") - -# display lines -gg.createAndDisplayGO(id_vxy) -gg.createAndDisplayGO(id_line1) -gg.createAndDisplayGO(id_line2) -\endcode +\include basic_geom_objs_ex02.py +Download this script \anchor tui_creation_circle

    Creation of a Circle

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p0 = geompy.MakeVertex(0., 0., 0.) -px = geompy.MakeVertex(100., 0. , 0. ) -py = geompy.MakeVertex(0. , 100., 0. ) -pz = geompy.MakeVertex(0. , 0. , 100.) - -# create a vector on two points -vxy = geompy.MakeVector(px, py) - -# create a circle from a point, a vector and a radius -circle1 = geompy.MakeCircle(pz, vxy, 30) - -#create a circle from three points -circle2 = geompy.MakeCircleThreePnt(p0, px, py) - -# add objects in the study -id_vxy = geompy.addToStudy(vxy, "Vector") -id_circle1 = geompy.addToStudy(circle1,"Circle1") -id_circle2 = geompy.addToStudy(circle2,"Circle2") - -# display circles -gg.createAndDisplayGO(id_vxy) -gg.createAndDisplayGO(id_circle1) -gg.createAndDisplayGO(id_circle2) -\endcode +\include basic_geom_objs_ex03.py +Download this script \anchor tui_creation_ellipse

    Creation of an Ellipse

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p0 = geompy.MakeVertex(0., 0., 0.) -p1 = geompy.MakeVertex(50., 50., 50.) -p2 = geompy.MakeVertex(0., 50., 0.) - -# create a normal vector from two points -normal = geompy.MakeVector(p0, p1) - -# create a major axis vector from two points -major = geompy.MakeVector(p0, p2) - -# create an ellipse from a point, a vector and radiuses -ellipse1 = geompy.MakeEllipse(p1, normal, 50, 25) - -# create an ellipse from a point, a normal vector, radiuses and a major axis vector -ellipse2 = geompy.MakeEllipse(p1, normal, 50, 25, major) - -# add objects in the study -id_normal = geompy.addToStudy(normal, "Normal") -id_major = geompy.addToStudy(major, "Major Axis") -id_ellipse1 = geompy.addToStudy(ellipse1, "Ellipse 1") -id_ellipse2 = geompy.addToStudy(ellipse2, "Ellipse 2") - -# display the ellipse and its normal vector -gg.createAndDisplayGO(id_normal) -gg.createAndDisplayGO(id_major) -gg.createAndDisplayGO(id_ellipse1) -gg.createAndDisplayGO(id_ellipse2) -\endcode +\include basic_geom_objs_ex04.py +Download this script \anchor tui_creation_arc

    Creation of an Arc

    +\include basic_geom_objs_ex05.py +Download this script -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p0 = geompy.MakeVertex(0., 0., 0.) -p1 = geompy.MakeVertex(100., 0., 0.) -p2 = geompy.MakeVertex(50., 0., 50.) - -# create an arc from a three points -arc1 = geompy.MakeArc(p0, p1, p2) - -# create an arc from a center point, a start point and end point -arc2 = geompy.MakeArcCenter(p0, p1, p2, 1) - -# create an arc from a center point, a major point and minor point -arc3 = geompy.MakeArcOfEllipse(p0, p1, p2) - -# add objects in the study -id_arc1 = geompy.addToStudy(arc1, "Arc 1") -id_arc2 = geompy.addToStudy(arc2, "Arc 2") -id_arc3 = geompy.addToStudy(arc3, "Arc 3") - -# display the arcs -gg.createAndDisplayGO(id_arc1) -gg.createAndDisplayGO(id_arc2) -gg.createAndDisplayGO(id_arc3) -\endcode - \anchor tui_creation_curve

    Creation of a Curve

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p0 = geompy.MakeVertex(0. , 0. , 0. ) -p1 = geompy.MakeVertex(50. , 100., 200.) -p2 = geompy.MakeVertex(150., 50., 100.) -p3 = geompy.MakeVertex(100., 150., 170.) -p4 = geompy.MakeVertex(200., 200., 150.) - -# create a polyline from a list of points -polyline = geompy.MakePolyline([p0, p1, p2, p3, p4]) - -# create a bezier curve from a list of points -bezier = geompy.MakeBezier([p0, p1, p2, p3, p4]) - -#create a b-spline curve from a list of points -interpol = geompy.MakeInterpol([p0, p1, p2, p3, p4], False) - -#create a polyline using parametric definition of the basic points -param_polyline = geompy.MakeCurveParametric("t", "sin(t)", "cos(t)", 0., 100., 100, geompy.GEOM.Polyline, theNewMethod=True) - -# create a bezier curve using parametric definition of the basic points -param_bezier = geompy.MakeCurveParametric("t", "sin(t)", "cos(t)", 0., 100., 100, geompy.GEOM.Bezier, theNewMethod=True) - -#create a b-spline curve using parametric definition of the basic points -param_interpol = geompy.MakeCurveParametric("t", "sin(t)", "cos(t)", 0., 100., 100, geompy.GEOM.Interpolation, theNewMethod=True) - - - -# add objects in the study -id_p0 = geompy.addToStudy(p0, "Point1") -id_p1 = geompy.addToStudy(p1, "Point2") -id_p2 = geompy.addToStudy(p2, "Point3") -id_p3 = geompy.addToStudy(p3, "Point4") -id_p4 = geompy.addToStudy(p4, "Point5") -id_polyline = geompy.addToStudy(polyline, "Polyline") -id_bezier = geompy.addToStudy(bezier, "Bezier") -id_interpol = geompy.addToStudy(interpol, "Interpol") -id_param_polyline = geompy.addToStudy(param_polyline, "Polyline Parametric") -id_param_bezier = geompy.addToStudy(param_bezier, "Bezier Parametric") -id_param_interpol = geompy.addToStudy(param_interpol, "Interpol Parametric") - - - -# display the points and the curves -gg.createAndDisplayGO(id_p0) -gg.createAndDisplayGO(id_p1) -gg.createAndDisplayGO(id_p2) -gg.createAndDisplayGO(id_p3) -gg.createAndDisplayGO(id_p4) -gg.createAndDisplayGO(id_polyline) -gg.createAndDisplayGO(id_bezier) -gg.createAndDisplayGO(id_interpol) -gg.createAndDisplayGO(id_param_polyline) -gg.createAndDisplayGO(id_param_bezier) -gg.createAndDisplayGO(id_param_interpol) - -\endcode +\include basic_geom_objs_ex06.py +Download this script \anchor tui_creation_vector

    Creation of a Vector

    - -\code -mport geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p1 = geompy.MakeVertex(10., 50., 20.) -p2 = geompy.MakeVertex(70., 70., 70.) - -# create a vector from two points -vector1 = geompy.MakeVector(p1, p2) - -# create a vector from the given components -vector2 = geompy.MakeVectorDXDYDZ(30, 30, 100) - -# add objects in the study -id_p1 = geompy.addToStudy(p1, "Point1") -id_p2 = geompy.addToStudy(p2, "Point2") -id_vector1 = geompy.addToStudy(vector1,"Vector1") -id_vector2 = geompy.addToStudy(vector2,"Vector2") - -# display the points and the vectors -gg.createAndDisplayGO(id_p1) -gg.createAndDisplayGO(id_p2) -gg.createAndDisplayGO(id_vector1) -gg.createAndDisplayGO(id_vector2) -\endcode +\include basic_geom_objs_ex07.py +Download this script \anchor tui_creation_plane

    Creation of a Plane

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p1 = geompy.MakeVertex( 0., 0., 100.) -p2 = geompy.MakeVertex(100., 0., 0.) -p3 = geompy.MakeVertex(200., 200., 200.) -p4 = geompy.MakeVertex(100., 100., 0.) -p5 = geompy.MakeVertex(0. , 100., 0.) - -# create a vectors from the given components -vector1 = geompy.MakeVectorDXDYDZ(100., 100., 100.) -vector2 = geompy.MakeVectorDXDYDZ(-100., 0., 100.) - -# create a vector from two points -vector_arc = geompy.MakeVector(p2, p5) - -# create an arc from three points -arc = geompy.MakeArc(p2, p4, p5) - -# create a wire -wire = geompy.MakeWire([vector_arc, arc]) - -# create a face -isPlanarWanted = 1 -face = geompy.MakeFace(wire, isPlanarWanted) -trimsize = 1000. - -# create a Local Coordinate System - -LCS = geompy.MakeMarker(100., 100., 101., 1, 0, 0, 0, 1, 0) - -# create a plane from a point, a vector and a trimsize -plane1 = geompy.MakePlane(p1, vector1, trimsize) - -# create a plane from three points and a trimsize -plane2 = geompy.MakePlaneThreePnt(p1, p2, p3, trimsize) - -# create a plane from the given face -plane3 = geompy.MakePlaneFace(face, trimsize) - -# create a plane from two vectors and a trimsize -plane4 = geompy.MakePlane2Vec(vector1, vector2, trimsize) - -# create a plane with the Local Coordinate System and a trimsize -plane5 = geompy.MakePlaneLCS(LCS, trimsize, 1) - -# add objects in the study -id_face = geompy.addToStudy(face, "Face") -id_plane1 = geompy.addToStudy(plane1,"Plane1") -id_plane2 = geompy.addToStudy(plane2,"Plane2") -id_plane3 = geompy.addToStudy(plane3,"Plane3") -id_plane4 = geompy.addToStudy(plane4,"Plane4") -id_plane5 = geompy.addToStudy(plane5,"Plane5") - -# display the points and the vectors -gg.createAndDisplayGO(id_face) -gg.createAndDisplayGO(id_plane1) -gg.createAndDisplayGO(id_plane2) -gg.createAndDisplayGO(id_plane3) -gg.createAndDisplayGO(id_plane4) -gg.createAndDisplayGO(id_plane5) -gg.setDisplayMode(id_plane1,1) -gg.setTransparency(id_plane1,0.5) -gg.setDisplayMode(id_plane2,1) -gg.setTransparency(id_plane2,0.5) -gg.setDisplayMode(id_plane3,1) -gg.setTransparency(id_plane3,0.5) -gg.setDisplayMode(id_plane4,1) -gg.setTransparency(id_plane4,0.5) -gg.setDisplayMode(id_plane5,1) -gg.setTransparency(id_plane5,0.5) -\endcode +\include basic_geom_objs_ex08.py +Download this script \anchor tui_creation_lcs

    Creation of a Local Coordinate System

    -\code -import GEOM -import geompy -import math -import SALOMEDS - -#Create vertexes, vectors and shapes to construct local CS -Vertex_1 = geompy.MakeVertex(50, 50, 50) -Vertex_2 = geompy.MakeVertex(70, 70, 70) -Vertex_3 = geompy.MakeVertex(0, 0, 0) -Vector_X = geompy.MakeVectorDXDYDZ(50, 0, 0) -Vector_Y = geompy.MakeVectorDXDYDZ(0, 50, 0) -Face_1 = geompy.MakeFaceHW(100, 100, 1) -Box_1 = geompy.MakeBoxTwoPnt(Vertex_1, Vertex_2) - -#Construct local CS by manual definition -LocalCS_1 = geompy.MakeMarker(0, 0, 0, 1, 0, 0, 0, 1, 0) - -#Construct local CS by center point and two vectors (X and Y directions) -LocalCS_2 = geompy.MakeMarkerPntTwoVec(Vertex_3, Vector_X, Vector_Y) - -#Construct local CS from shape orientation -LocalCS_FACE = geompy.MakeMarkerFromShape(Face_1) -LocalCS_BOX = geompy.MakeMarkerFromShape(Box_1) - -#Add created object to study -geompy.addToStudy( Face_1, "Face_1" ) -geompy.addToStudy( Vertex_1, "Vertex_1" ) -geompy.addToStudy( Vertex_2, "Vertex_2" ) -geompy.addToStudy( Box_1, "Box_1" ) -geompy.addToStudy( Vertex_3, "Vertex_3" ) -geompy.addToStudy( Vector_X, "Vector_X" ) -geompy.addToStudy( Vector_Y, "Vector_Y" ) -geompy.addToStudy( LocalCS_1, "LocalCS_1" ) -geompy.addToStudy( LocalCS_2, "LocalCS_3" ) -geompy.addToStudy( LocalCS_FACE, "LocalCS_FACE" ) -geompy.addToStudy( LocalCS_BOX, "LocalCS_BOX" ) -\endcode +\include basic_geom_objs_ex09.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_basic_operations.doc b/doc/salome/gui/GEOM/input/tui_basic_operations.doc index aec3a7465..3899255b1 100644 --- a/doc/salome/gui/GEOM/input/tui_basic_operations.doc +++ b/doc/salome/gui/GEOM/input/tui_basic_operations.doc @@ -4,138 +4,17 @@ \anchor tui_partition

    Partition

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p0 = geompy.MakeVertex( 0., 0., 0.) -p200 = geompy.MakeVertex(200., 200., 200.) -pz = geompy.MakeVertex( 0., 0., 100.) - -# create a vector -vxyz = geompy.MakeVectorDXDYDZ(100., 100., 100.) - -# create a box from two points -box = geompy.MakeBoxTwoPnt(p0, p200) - -# create a plane -trimsize = 500. -plane = geompy.MakePlane(pz, vxyz, trimsize) - -# create partition objects -partition1 = geompy.MakePartition([box], [plane]) -partition2 = geompy.Partition([box], [plane]) -partition3 = geompy.MakeHalfPartition(box, plane) - -# add objects in the study -id_box = geompy.addToStudy(box,"Box") -id_plane = geompy.addToStudy(plane,"Plane") -id_partition1 = geompy.addToStudy(partition1,"MakePartition") -id_partition2 = geompy.addToStudy(partition2,"Partition") -id_partition3 = geompy.addToStudy(partition3,"MakeHalfPartition") - -# display the partition objects and the plane -gg.createAndDisplayGO(id_box) -gg.setDisplayMode(id_box,1) -gg.createAndDisplayGO(id_plane) -gg.setDisplayMode(id_plane,1) -gg.createAndDisplayGO(id_partition1) -gg.createAndDisplayGO(id_partition2) -gg.createAndDisplayGO(id_partition3) -\endcode +\include basic_operations_ex01.py +Download this script \anchor tui_archimede

    Archimede

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p0 = geompy.MakeVertex( 0., 0., 0.) -p200 = geompy.MakeVertex(200., 200., 200.) - -# create a box from two points -box = geompy.MakeBoxTwoPnt(p0, p200) - -# perform an Archimede operation on the selected shape with selected parameters -weight = 1000000. -waterdensity = 1. -meshingdeflection = 0.01 -archimede = geompy.Archimede(box, weight, waterdensity, meshingdeflection) - -# add objects in the study -id_box = geompy.addToStudy(box,"Box") -id_archimede = geompy.addToStudy(archimede,"Archimede") - -# display the box and the result of Archimede operation -gg.createAndDisplayGO(id_box) -gg.setDisplayMode(id_box,1) -gg.createAndDisplayGO(id_archimede) -gg.setDisplayMode(id_archimede,1) -\endcode +\include basic_operations_ex02.py +Download this script \anchor tui_restore_prs_params

    Restore presentation parameters and sub-shapes

    - -\code -import geompy -import GEOM -import SALOMEDS - -# create a box and a cylinder -box = geompy.MakeBoxDXDYDZ(200, 200, 200) -cyl = geompy.MakeCylinderRH(100, 300) - -# create translated box -vec = geompy.MakeVectorDXDYDZ(100, 50, 0) -tra = geompy.MakeTranslationVector(box, vec) - -# create partition objects -partition1 = geompy.MakePartition([box, cyl]) -partition2 = geompy.MakePartition([box], [cyl]) -partition3 = geompy.MakePartition([box], [tra]) - -# set colours -box.SetColor(SALOMEDS.Color(1,0,0)) -cyl.SetColor(SALOMEDS.Color(0,1,0)) - -# add objects in the study -geompy.addToStudy(box, "Box") -geompy.addToStudy(cyl, "Cylinder") -geompy.addToStudy(vec, "Vector") -geompy.addToStudy(tra, "Translation") -geompy.addToStudy(partition1, "Partition_1") -geompy.addToStudy(partition2, "Partition_2") -geompy.addToStudy(partition3, "Partition_3") - -# Restore presentation parameters and sub-shapes -# different methods can be used to find the sub-shapes in the result: -# GetInPlace, GetSame, GetInPlaceByHistory, GetShapesOnShape. -# By default, GetInPlace method is used (GEOM.FSM_GetInPlace) -geompy.RestoreSubShapes(partition1) - -geompy.RestoreSubShapes(partition2, [], GEOM.FSM_GetInPlace) - -# The list of arguments can be used to avoid restoring all arguments, -# but restore only the passed. -geompy.RestoreSubShapes(partition3, [tra], GEOM.FSM_GetInPlaceByHistory) - -# To find sub-shapes in a transformed shape only one method could be -# used: pass GEOM.FSM_Transformed for that. -# True passed for the last argument, means that the transformed shape -# will inherit colour and sub-shapes from its first argument (see above -# MakeTranslation). -geompy.RestoreSubShapes(tra, [], GEOM.FSM_Transformed, True) - -# Also we could do this directly with method addToStudy: -partition4 = geompy.MakePartition([box, tra]) -geompy.addToStudy(partition4, "Partition_4", True, [], - GEOM.FSM_GetInPlaceByHistory, False) -\endcode +\include basic_operations_ex03.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_basic_properties.doc b/doc/salome/gui/GEOM/input/tui_basic_properties.doc index 4c01ec438..dad8e828b 100644 --- a/doc/salome/gui/GEOM/input/tui_basic_properties.doc +++ b/doc/salome/gui/GEOM/input/tui_basic_properties.doc @@ -1,26 +1,7 @@ /*! \page tui_basic_properties_page Basic Properties - -\code -import geompy -import math - -# create a box -box = geompy.MakeBoxDXDYDZ(100,30,100) -props = geompy.BasicProperties(box) -print "\nBox 100x30x100 Basic Properties:" -print " Wires length: ", props[0] -print " Surface area: ", props[1] -print " Volume : ", props[2] -length = math.sqrt((props[0] - 1840)*(props[0] - 1840)) -area = math.sqrt((props[1] - 32000)*(props[1] - 32000)) -volume = math.sqrt((props[2] - 300000)*(props[2] - 300000)) -if length > 1e-7 or area > 1e-7 or volume > 1e-7: - print "While must be:" - print " Wires length: ", 1840 - print " Surface area: ", 32000 - print " Volume : ", 300000. -\endcode +\include basic_properties.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_blocks_operations.doc b/doc/salome/gui/GEOM/input/tui_blocks_operations.doc index 8544667f1..4acb44f80 100644 --- a/doc/salome/gui/GEOM/input/tui_blocks_operations.doc +++ b/doc/salome/gui/GEOM/input/tui_blocks_operations.doc @@ -4,95 +4,17 @@ \anchor tui_multi_transformation

    Multi Transformation

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p_25_25_50 = geompy.MakeVertex(25., 25., 50.) -p_50_25_25 = geompy.MakeVertex(50., 25., 25.) -p_25_50_25 = geompy.MakeVertex(25., 50., 25.) - -box = geompy.MakeBoxDXDYDZ(50, 50, 50) - -top_face = geompy.GetFaceNearPoint(box, p_25_25_50) -yz_face = geompy.GetFaceNearPoint(box, p_50_25_25) -xz_face = geompy.GetFaceNearPoint(box, p_25_50_25) - -top_face_ind = geompy.GetSubShapeID(box, top_face) -yz_face_ind = geompy.GetSubShapeID(box, yz_face) -xz_face_ind = geompy.GetSubShapeID(box, xz_face) - -# Multi-transformate block and glue the result -box_tr1 = geompy.MakeMultiTransformation1D(box, yz_face_ind, top_face_ind, 3) -box_tr2 = geompy.MakeMultiTransformation2D(box, xz_face_ind, yz_face_ind, 3, top_face_ind, 0, 2) - -# add objects in the study -id_box = geompy.addToStudy(box, "Box") -id_box_tr1 = geompy.addToStudy(box_tr1, "Multi-transformed Block 1D") -id_box_tr2 = geompy.addToStudy(box_tr2, "Multi-transformed Block 2D") - -# display the results -gg.createAndDisplayGO(id_box) -gg.setDisplayMode(id_box,1) -gg.createAndDisplayGO(id_box_tr1) -gg.createAndDisplayGO(id_box_tr2) -\endcode +\include blocks_operations_ex01.py +Download this script \anchor tui_explode_on_blocks

    Explode on Blocks

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a box and a sphere -box = geompy.MakeBoxDXDYDZ(200, 200, 200) -sphere = geompy.MakeSphereR(100) - -# make a compound -compound = geompy.MakeCompound([box, sphere]) - -# get all the blocks of the given compound, by criteria: min_nb_faces <= nb. of faces <= max_nb_faces -min_nb_faces = 6 -max_nb_faces = 6 -make_block_explode = geompy.MakeBlockExplode(compound, min_nb_faces, max_nb_faces) - -# add objects in the study -id_compound = geompy.addToStudy(compound, "Compound") -id_make_block_explode = geompy.addToStudyInFather(compound, make_block_explode[0], "MakeBlockExplode") - -# display the results -gg.createAndDisplayGO(id_compound) -gg.createAndDisplayGO(id_make_block_explode) -gg.setDisplayMode(id_make_block_explode,1) -\endcode +\include blocks_operations_ex02.py +Download this script \anchor tui_propagate

    Propagate

    +\include blocks_operations_ex03.py +Download this script -\code -import geompy -import salome - -# create a box -box = geompy.MakeBoxDXDYDZ(200, 200, 200) - -# build all possible propagation groups -listChains = geompy.Propagate(check_box) - -# add objects in the study -geompy.addToStudy(check_box, "Box") -ii = 1 -for chain in listChains: - geompy.addToStudyInFather(check_box, chain, "propagation chain " + `ii`) - ii = ii + 1 - pass - -salome.sg.updateObjBrowser(1) -\endcode - -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/GEOM/input/tui_boolean_operations.doc b/doc/salome/gui/GEOM/input/tui_boolean_operations.doc index 60563757c..0ab8db001 100644 --- a/doc/salome/gui/GEOM/input/tui_boolean_operations.doc +++ b/doc/salome/gui/GEOM/input/tui_boolean_operations.doc @@ -4,140 +4,22 @@ \anchor tui_fuse

    Fuse

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex(25, 55, 0) -p2 = geompy.MakeVertex( 0, 0, 0) -v = geompy.MakeVector(p1, p2) - -# create a cylinder -height = 35 -radius1 = 20 -cylinder = geompy.MakeCylinder(p1, v, radius1, height) - -# create a sphere -sphere = geompy.MakeSphereR(40) - -# fuse -fuse1 = geompy.MakeFuse(cylinder, sphere) -fuse2 = geompy.MakeBoolean(cylinder, sphere, 3) - -# add objects in the study -id_cylinder = geompy.addToStudy(cylinder, "Cylinder") -id_sphere = geompy.addToStudy(sphere, "Sphere") -id_fuse1 = geompy.addToStudy(fuse1, "Fuse_1") -id_fuse2 = geompy.addToStudy(fuse2, "Fuse_2") - -# display results -gg.createAndDisplayGO(id_cylinder) -gg.setDisplayMode(id_cylinder,1) -gg.createAndDisplayGO(id_sphere) -gg.setDisplayMode(id_sphere,1) -gg.createAndDisplayGO(id_fuse1) -gg.setDisplayMode(id_fuse1,1) -gg.createAndDisplayGO(id_fuse2) -gg.setDisplayMode(id_fuse2,1) -\endcode +\include boolean_operations_ex01.py +Download this script \anchor tui_common

    Common

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex(25, 55, 0) -p2 = geompy.MakeVertex( 0, 0, 0) -v = geompy.MakeVector(p1, p2) - -# create a cylinder -height = 35 -radius1 = 20 -cylinder = geompy.MakeCylinder(p1, v, radius1, height) - -# create a sphere -sphere = geompy.MakeSphereR(40) - -# make common -common = geompy.MakeCommon(cylinder, sphere) - -# add objects in the study -id_common = geompy.addToStudy(common, "Common") - -# display the results -gg.createAndDisplayGO(id_common) -gg.setDisplayMode(id_common,1) -\endcode +\include boolean_operations_ex02.py +Download this script \anchor tui_cut

    Cut

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex(25, 55, 0) -p2 = geompy.MakeVertex( 0, 0, 0) -v = geompy.MakeVector(p1, p2) - -# create a cylinder -height = 35 -radius1 = 20 -cylinder = geompy.MakeCylinder(p1, v, radius1, height) - -# create a sphere -sphere = geompy.MakeSphereR(40) - -#cut -cut = geompy.MakeCut(cylinder, sphere) - -# add objects in the study -id_cut = geompy.addToStudy(cut, "Cut") - -# display the results -gg.createAndDisplayGO(id_cut) -gg.setDisplayMode(id_cut,1) -\endcode +\include boolean_operations_ex03.py +Download this script \anchor tui_section

    Section

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex(25, 55, 0) -p2 = geompy.MakeVertex( 0, 0, 0) -v = geompy.MakeVector(p1, p2) - -# create a cylinder -height = 35 -radius1 = 20 -cylinder = geompy.MakeCylinder(p1, v, radius1, height) - -# create a sphere -sphere = geompy.MakeSphereR(40) - -# make a section -section = geompy.MakeSection(cylinder, sphere) - -# add objects in the study -id_section = geompy.addToStudy(section, "Section") - -# display the results -gg.createAndDisplayGO(id_section) -gg.setDisplayMode(id_section,1) -\endcode +\include boolean_operations_ex04.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_bounding_box.doc b/doc/salome/gui/GEOM/input/tui_bounding_box.doc index 232ab13b4..76d4b4347 100644 --- a/doc/salome/gui/GEOM/input/tui_bounding_box.doc +++ b/doc/salome/gui/GEOM/input/tui_bounding_box.doc @@ -1,17 +1,7 @@ /*! \page tui_bounding_box_page Bounding Box - -\code -import geompy - -# create a box -box = geompy.MakeBoxDXDYDZ(100,30,100) -bb = geompy.BoundingBox(box) -print "\nBounding Box of box 100x30x100:" -print " Xmin = ", bb[0], ", Xmax = ", bb[1] -print " Ymin = ", bb[2], ", Ymax = ", bb[3] -print " Zmin = ", bb[4], ", Zmax = ", bb[5] -\endcode +\include bounding_box.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_building_by_blocks.doc b/doc/salome/gui/GEOM/input/tui_building_by_blocks.doc index 3584c7ef5..77f8e363b 100644 --- a/doc/salome/gui/GEOM/input/tui_building_by_blocks.doc +++ b/doc/salome/gui/GEOM/input/tui_building_by_blocks.doc @@ -3,118 +3,11 @@ \page tui_building_by_blocks_page Building by Blocks

    Quadrangle Face

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p1 = geompy.MakeVertex( 0., 0., 0.) -p2 = geompy.MakeVertex(150., 30., 0.) -p3 = geompy.MakeVertex( 0., 120., 50.) -p4 = geompy.MakeVertex( 0., 40., 70.) - -# create edges -edge1 = geompy.MakeEdge(p1, p2) -edge2 = geompy.MakeEdge(p2, p3) -edge3 = geompy.MakeEdge(p3, p4) -edge4 = geompy.MakeEdge(p4, p1) - -# create a quadrangle face from four edges -qface1 = geompy.MakeQuad(edge1, edge2, edge3, edge4) - -# create a quadrangle face from two edges -qface2 = geompy.MakeQuad2Edges(edge1, edge3) - -# create a quadrangle from four points in its corners -qface3 = geompy.MakeQuad4Vertices(p1, p2, p3, p4) - -# add objects in the study -id_p1 = geompy.addToStudy(p1,"Point1") -id_p2 = geompy.addToStudy(p2,"Point2") -id_p3 = geompy.addToStudy(p3,"Point3") -id_p4 = geompy.addToStudy(p4,"Point4") -id_edge1 = geompy.addToStudy(edge1,"Edge1") -id_edge2 = geompy.addToStudy(edge2,"Edge2") -id_edge3 = geompy.addToStudy(edge3,"Edge3") -id_edge4 = geompy.addToStudy(edge4,"Edge4") -id_qface1 = geompy.addToStudy(qface1,"Qface1") -id_qface2 = geompy.addToStudy(qface2,"Qface2") -id_qface3 = geompy.addToStudy(qface3,"Qface3") - -# display the vertices, the edges and the quadrangle faces -gg.createAndDisplayGO(id_p1) -gg.createAndDisplayGO(id_p2) -gg.createAndDisplayGO(id_p3) -gg.createAndDisplayGO(id_p4) -gg.createAndDisplayGO(id_edge1) -gg.createAndDisplayGO(id_edge2) -gg.createAndDisplayGO(id_edge3) -gg.createAndDisplayGO(id_edge4) -gg.createAndDisplayGO(id_qface1) -gg.setDisplayMode(id_qface1,1) -gg.createAndDisplayGO(id_qface2) -gg.setDisplayMode(id_qface2,1) -gg.createAndDisplayGO(id_qface3) -gg.setDisplayMode(id_qface3,1) -\endcode +\include building_by_blocks_ex01.py +Download this script

    Hexagonal Solid

    +\include building_by_blocks_ex02.py +Download this script -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p0 = geompy.MakeVertex( 0., 0., 0.) -p1 = geompy.MakeVertex( 0., 0., 40.) -p2 = geompy.MakeVertex( 70., -15., 0.) -p3 = geompy.MakeVertex( 70., -15., 70.) - -p4 = geompy.MakeVertex( 0., 70., 0.) -p5 = geompy.MakeVertex( 0., 70., 40.) -p6 = geompy.MakeVertex( 70., 70., 0.) -p7 = geompy.MakeVertex( 70., 70., 70.) - -p8 = geompy.MakeVertex( 0., -50., 0.) -p9 = geompy.MakeVertex( 0., -50., 40.) -p10 = geompy.MakeVertex( 70., -35., 0.) -p11 = geompy.MakeVertex( 70., -35., 70.) - -# create faces -qface1 = geompy.MakeQuad4Vertices(p0, p1, p2, p3) -qface2 = geompy.MakeQuad4Vertices(p4, p5, p6, p7) -qface3 = geompy.MakeQuad4Vertices(p0, p1, p4, p5) -qface4 = geompy.MakeQuad4Vertices(p2, p3, p6, p7) -qface5 = geompy.MakeQuad4Vertices(p0, p2, p4, p6) -qface6 = geompy.MakeQuad4Vertices(p1, p3, p5, p7) -qface7 = geompy.MakeQuad4Vertices(p8, p9, p10, p11) - -# create a hexahedral solid between two given faces -solid1 = geompy.MakeHexa2Faces(qface1, qface7) - -# create a hexahedral solid, bounded by six given faces -solid2 = geompy.MakeHexa(qface1, qface2, qface3, qface4, qface5, qface6) - -# add objects in the study -geompy.addToStudy(qface1,"qface1") -geompy.addToStudy(qface2,"qface2") -geompy.addToStudy(qface3,"qface3") -geompy.addToStudy(qface4,"qface4") -geompy.addToStudy(qface5,"qface5") -geompy.addToStudy(qface6,"qface6") -geompy.addToStudy(qface7,"qface7") - -id_solid1 = geompy.addToStudy(solid1,"Solid1") -id_solid2 = geompy.addToStudy(solid2,"Solid2") - -# display solids -gg.createAndDisplayGO(id_solid1) -gg.setDisplayMode(id_solid1, 1) -gg.createAndDisplayGO(id_solid2) -gg.setDisplayMode(id_solid2, 1) -\endcode - -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/GEOM/input/tui_center_of_mass.doc b/doc/salome/gui/GEOM/input/tui_center_of_mass.doc index 9c9b6f659..49eb49538 100644 --- a/doc/salome/gui/GEOM/input/tui_center_of_mass.doc +++ b/doc/salome/gui/GEOM/input/tui_center_of_mass.doc @@ -1,25 +1,7 @@ /*! \page tui_center_of_mass_page Center of masses - -\code -import geompy -import math - -# create a box -box = geompy.MakeBoxDXDYDZ(100,30,100) -cm = geompy.MakeCDG(box) -if cm is None: - raise RuntimeError, "MakeCDG(box) failed" -else: - print "\nCentre of gravity of box has been successfully obtained:" - coords = geompy.PointCoordinates(cm) - print "(", coords[0], ", ", coords[1], ", ", coords[2], ")" - dx = math.sqrt((coords[0] - 50)*(coords[0] - 50)) - dy = math.sqrt((coords[1] - 15)*(coords[1] - 15)) - dz = math.sqrt((coords[2] - 50)*(coords[2] - 50)) - if dx > 1e-7 or dy > 1e-7 or dz > 1e-7: - print "But must be (50, 15, 50)" -\endcode +\include center_of_mass.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_check_compound_of_blocks.doc b/doc/salome/gui/GEOM/input/tui_check_compound_of_blocks.doc index 1bd2fe9bb..eeb9d92a1 100644 --- a/doc/salome/gui/GEOM/input/tui_check_compound_of_blocks.doc +++ b/doc/salome/gui/GEOM/input/tui_check_compound_of_blocks.doc @@ -1,27 +1,7 @@ /*! \page tui_check_compound_of_blocks_page Check Compound of Blocks - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create boxes -box1 = geompy.MakeBox(0,0,0,100,50,100) -box2 = geompy.MakeBox(100,0,0,250,50,100) - -# make a compound -compound = geompy.MakeCompound([box1, box2]) - -# glue the faces of the compound -tolerance = 1e-5 -glue = geompy.MakeGlueFaces(compound, tolerance) -IsValid = geompy.CheckCompoundOfBlocks(glue) -if IsValid == 0: - raise RuntimeError, "Invalid compound created" -else: - print "\nCompound is valid" -\endcode +\include check_compound_of_blocks.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_check_self_intersections.doc b/doc/salome/gui/GEOM/input/tui_check_self_intersections.doc index e49de0a30..346de0c2b 100644 --- a/doc/salome/gui/GEOM/input/tui_check_self_intersections.doc +++ b/doc/salome/gui/GEOM/input/tui_check_self_intersections.doc @@ -1,17 +1,7 @@ /*! \page tui_check_self_intersections_page Detect Self-intersections - -\code -import geompy - -# create a box -box = geompy.MakeBoxDXDYDZ(100,30,100) -IsValid = geompy.CheckSelfIntersections(box) -if IsValid == 0: - raise RuntimeError, "Box with self-intersections created" -else: - print "\nBox is valid" -\endcode +\include check_self_intersections.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_check_shape.doc b/doc/salome/gui/GEOM/input/tui_check_shape.doc index f9ca32c97..5e11279ef 100644 --- a/doc/salome/gui/GEOM/input/tui_check_shape.doc +++ b/doc/salome/gui/GEOM/input/tui_check_shape.doc @@ -1,17 +1,7 @@ /*! \page tui_check_shape_page Check Shape - -\code -import geompy - -# create a box -box = geompy.MakeBoxDXDYDZ(100,30,100) -IsValid = geompy.CheckShape(box) -if IsValid == 0: - raise RuntimeError, "Invalid box created" -else: - print "\nBox is valid" -\endcode +\include check_shape.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_complex_objs.doc b/doc/salome/gui/GEOM/input/tui_complex_objs.doc index 2cdcf156a..030943956 100644 --- a/doc/salome/gui/GEOM/input/tui_complex_objs.doc +++ b/doc/salome/gui/GEOM/input/tui_complex_objs.doc @@ -4,697 +4,51 @@ \anchor tui_creation_prism

    Creation of a Prism

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex( 0., 0., 0.) -p2 = geompy.MakeVertex( 100., 0., 0.) -p3 = geompy.MakeVertex( 100., 100., 0.) -p4 = geompy.MakeVertex( 0., 100., 0.) -p5 = geompy.MakeVertex( 0., 0., 60.) -p6 = geompy.MakeVertex(-100., 0., 0.) -p7 = geompy.MakeVertex(-100.,-100., 0.) -p8 = geompy.MakeVertex( 0.,-100., 0.) - -# create a vector from the given components -vector = geompy.MakeVectorDXDYDZ(50., 50., 50.) - -#create vectors from two points -vector1_arc1 = geompy.MakeVector(p1, p2) -vector2_arc1 = geompy.MakeVector(p1, p4) -vector1_arc2 = geompy.MakeVector(p1, p6) -vector2_arc2 = geompy.MakeVector(p1, p8) - -# create arcs from three points -arc1 = geompy.MakeArc(p2, p3, p4) -arc2 = geompy.MakeArc(p6, p7, p8) - -# create wires -wire1 = geompy.MakeWire([vector1_arc1, arc1, vector2_arc1]) -wire2 = geompy.MakeWire([vector1_arc2, arc2, vector2_arc2]) - -# create faces -isPlanarWanted = 1 -face1 = geompy.MakeFace(wire1, isPlanarWanted) -face2 = geompy.MakeFace(wire2, isPlanarWanted) - -# create prisms -prism1 = geompy.MakePrism(face2, p1, p5) -prism2 = geompy.MakePrismVecH(face1, vector, 50) -prism3 = geompy.MakePrismVecH2Ways(face1, vector, 50) - -# add objects in the study -id_face1 = geompy.addToStudy(face1,"Face1") -id_face2 = geompy.addToStudy(face2,"Face2") -id_prism1 = geompy.addToStudy(prism1,"Prism1") -id_prism2 = geompy.addToStudy(prism2,"Prism2") -id_prism3 = geompy.addToStudy(prism3,"Prism3") - -# display cylinders -gg.createAndDisplayGO(id_face1) -gg.setDisplayMode(id_face1,1) -gg.createAndDisplayGO(id_face2) -gg.setDisplayMode(id_face2,1) -gg.createAndDisplayGO(id_prism1) -gg.setDisplayMode(id_prism1,1) -gg.createAndDisplayGO(id_prism2) -gg.setDisplayMode(id_prism2,1) -gg.createAndDisplayGO(id_prism3) -gg.setDisplayMode(id_prism3,1) -\endcode +\include complex_objs_ex01.py +Download this script \anchor tui_creation_revolution

    Creation of a Revolution

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex( 10., 10., 10.) -p2 = geompy.MakeVertex( 15., 15., 50.) -p3 = geompy.MakeVertex( 40., 40., 0.) - -#create vectors from two points -vector1 = geompy.MakeVector(p1, p2) -vector2 = geompy.MakeVector(p1, p3) - -# create a vector from the given components -vector3 = geompy.MakeVectorDXDYDZ(-20., -20., 100.) - -# create a wire -wire = geompy.MakeWire([vector1, vector2]) - -# create a revolution -revolution = geompy.MakeRevolution(wire, vector3, 2.3) - -# add objects in the study -id_vector3 = geompy.addToStudy(vector3,"Axis") -id_wire = geompy.addToStudy(wire,"Wire") -id_revolution = geompy.addToStudy(revolution,"Revolution") - -# display the vector, the wire and the revolution -gg.createAndDisplayGO(id_vector3) -gg.createAndDisplayGO(id_wire) -gg.createAndDisplayGO(id_revolution) -gg.setDisplayMode(id_revolution,1) -\endcode +\include complex_objs_ex02.py +Download this script \anchor tui_creation_filling

    Creation of a Filling

    +\include complex_objs_ex03.py +Download this script -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -mindeg = 2 -maxdeg = 5 -tol3d = 0.0001 -tol2d = 0.0001 -nbiter = 5 - -# create a vertex and a vector -p1 = geompy.MakeVertex( -30., -30., 50.) -p2 = geompy.MakeVertex( -60., -60., 30.) -p3 = geompy.MakeVertex( -30., -30., 10.) - -# create an arc from three points -arc = geompy.MakeArc(p1, p2, p3) -ShapeListCompound = [] -i = 0 -while i <= 3 : - S = geompy.MakeTranslation(arc, i * 50., 0., 0.) - ShapeListCompound.append(S) - i = i + 1 - -compound = geompy.MakeCompound(ShapeListCompound) - -# create a filling -filling = geompy.MakeFilling(compound, mindeg, maxdeg, tol3d, tol2d, nbiter) - -# add objects in the study -id_compound = geompy.addToStudy(compound,"Compound") -id_filling = geompy.addToStudy(filling,"Filling") - -# display the compound and the filling -gg.createAndDisplayGO(id_compound) -gg.createAndDisplayGO(id_filling) -gg.setDisplayMode(id_filling,1) -\endcode - \anchor tui_creation_pipe

    Creation of a Pipe

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p0 = geompy.MakeVertex(0. , 0. , 0. ) -px = geompy.MakeVertex(100., 0. , 0. ) -py = geompy.MakeVertex(0. , 100., 0. ) -pz = geompy.MakeVertex(0. , 0. , 100.) -pxyz = geompy.MakeVertex(100., 100., 100.) - -# create a vector from two points -vxy = geompy.MakeVector(px, py) - -# create an arc from three points -arc = geompy.MakeArc(py, pz, px) - -# create a wire -wire = geompy.MakeWire([vxy, arc]) - -# create an edge -edge = geompy.MakeEdge(p0, pxyz) - -# create a pipe -pipe = geompy.MakePipe(wire, edge) - -# add objects in the study -id_wire = geompy.addToStudy(wire,"Wire") -id_edge = geompy.addToStudy(edge,"Edge") -id_pipe = geompy.addToStudy(pipe,"Pipe") - -# display the wire, the edge (path) and the pipe -gg.createAndDisplayGO(id_wire) -gg.createAndDisplayGO(id_edge) -gg.createAndDisplayGO(id_pipe) -gg.setDisplayMode(id_pipe,1) -\endcode +\include complex_objs_ex04.py +Download this script \anchor tui_creation_pipe_with_diff_sec

    Creation of a PipeWithDifferentSections

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -Wire_1 = geompy.MakeSketcher("Sketcher:F 0 0:TT 100 0:R 0:C 100 90:T 0 200", [0, 0, 0, 0, 0, 1, 1, 0, -0]) -edges = geompy.SubShapeAll(Wire_1, geompy.ShapeType["EDGE"]) -vertices = geompy.SubShapeAll(Wire_1, geompy.ShapeType["VERTEX"]) - -# create sections -circles=[] -circles.append(geompy.MakeCircle(vertices[0], edges[0], 20)) -circles.append(geompy.MakeCircle(vertices[1], edges[0], 40)) -circles.append(geompy.MakeCircle(vertices[2], edges[2], 30)) -circles.append(geompy.MakeCircle(vertices[3], edges[2], 20)) - -# create pipe -Pipe = geompy.MakePipeWithDifferentSections(circles, vertices, Wire_1, 0, 0) - -# add objects in the study -geompy.addToStudy(circles[0], "circles1") -geompy.addToStudy(circles[1], "circles2") -geompy.addToStudy(circles[2], "circles3") -geompy.addToStudy(circles[3], "circles4") -id_wire = geompy.addToStudy(Wire_1, "Path") -id_pipe = geompy.addToStudy(Pipe, "Pipe") - -# display the wire(path) and the pipe -gg.createAndDisplayGO(id_wire) -gg.createAndDisplayGO(id_pipe) -gg.setDisplayMode(id_pipe,1) -\endcode +\include complex_objs_ex05.py +Download this script \anchor tui_creation_pipe_with_shell_sec

    Creation of a PipeWithShellSections

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create path -WirePath = geompy.MakeSketcher("Sketcher:F 0 0:TT 100 0:R 0:C 100 90:T 0 200", [0, 0, 0, 0, 0, 1, 1, 0, -0]) - -#======================================================= -# Create shell sections -#======================================================= -ps = [Vertex_1,Vertex_2,Vertex_3,Vertex_4] -theLocations = [Vertex_1, Vertex_2, Vertex_3, Vertex_4] -VC = geompy.MakeCompound(theLocations) -geompy.addToStudy(VC,"VC") -vs = [Edge_1,Edge_1,Edge_3,Edge_3] -hs = [20,40,30,20] -shells = [] -subbases = [] - -# 1 section -c0 = geompy.PointCoordinates(ps[0]) -c1 = geompy.PointCoordinates(ps[1]) -nx = c1[0] - c0[0] -ny = c1[1] - c0[1] -nz = c1[2] - c0[2] - -faces = [] -f1 = geompy.MakeSketcher("Sketcher:F 0 0:TT 20 0:TT 20 20:TT 0 20:WF", - [c0[0], c0[1], c0[2], nx, ny, nz, 0, 0, 1]) -f2 = geompy.MakeSketcher("Sketcher:F 0 0:TT 0 20:TT -20 20:TT -20 0:WF", - [c0[0], c0[1], c0[2], nx, ny, nz, 0, 0, 1]) -f3 = geompy.MakeSketcher("Sketcher:F 0 0:TT -20 0:TT -20 -20:TT 0 -20:WF", - [c0[0], c0[1], c0[2], nx, ny, nz, 0, 0, 1]) -f4 = geompy.MakeSketcher("Sketcher:F 0 0:TT 0 -20:TT 20 -20:TT 20 0:WF", - [c0[0], c0[1], c0[2], nx, ny, nz, 0, 0, 1]) -faces.append(f1) -faces.append(f2) -faces.append(f3) -faces.append(f4) -shell = geompy.MakeSewing(faces,1.e-6) -shells.append(shell) -faces = geompy.SubShapeAllSortedCentres(shell, geompy.ShapeType["FACE"]) -subbases.append(faces[0]) - -# 2 section -faces = [] - -w = geompy.MakeSketcher("Sketcher:F 20 20:TT 0 20:TT 0 0:TT 20 0", - [c1[0], c1[1], c1[2], nx, ny, nz, 0, 0, 1]) -[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) -arc = MakeArc(w,3,-1) -w = geompy.MakeWire([e1,e2,e3,arc]) -f1 = geompy.MakeFace(w,1) - -w = geompy.MakeSketcher("Sketcher:F -20 0:TT 0 0:TT 0 20:TT -20 20", - [c1[0], c1[1], c1[2], nx, ny, nz, 0, 0, 1]) -[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) -arc = MakeArc(w,3,-1) -w = geompy.MakeWire([e1,e2,e3,arc]) -f2 = geompy.MakeFace(w,1) - -w = geompy.MakeSketcher("Sketcher:F 20 0:TT 0 0:TT 0 -20:TT 20 -20", - [c1[0], c1[1], c1[2], nx, ny, nz, 0, 0, 1]) -[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) -arc = MakeArc(w,3,-1) -w = geompy.MakeWire([e1,e2,e3,arc]) -f3 = geompy.MakeFace(w,1) - -w = geompy.MakeSketcher("Sketcher:F -20 -20:TT 0 -20:TT 0 0:TT -20 0", - [c1[0], c1[1], c1[2], nx, ny, nz, 0, 0, 1]) -[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) -arc = MakeArc(w,3,-1) -w = geompy.MakeWire([e1,e2,e3,arc]) -f4 = geompy.MakeFace(w,1) - -faces.append(f1) -faces.append(f2) -faces.append(f3) -faces.append(f4) -shell = geompy.MakeSewing(faces,1.e-6) -shells.append(shell) -faces = geompy.SubShapeAllSortedCentres(shell, geompy.ShapeType["FACE"]) -subbases.append(faces[0]) - -# 3 section -faces = [] -c2 = geompy.PointCoordinates(ps[2]) -c3 = geompy.PointCoordinates(ps[3]) -nx = c3[0] - c2[0] -ny = c3[1] - c2[1] -nz = c3[2] - c2[2] - -w = geompy.MakeSketcher("Sketcher:F 20 20:TT 0 20:TT 0 0:TT 20 0", - [c2[0], c2[1], c2[2], nx, ny, nz, 0, 0, 1]) -[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) -arc = MakeArc(w,3,1) -w = geompy.MakeWire([e1,e2,e3,arc]) -f1 = geompy.MakeFace(w,1) - -w = geompy.MakeSketcher("Sketcher:F -20 0:TT 0 0:TT 0 20:TT -20 20", - [c2[0], c2[1], c2[2], nx, ny, nz, 0, 0, 1]) -[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) -arc = MakeArc(w,3,1) -w = geompy.MakeWire([e1,e2,e3,arc]) -f2 = geompy.MakeFace(w,1) - -w = geompy.MakeSketcher("Sketcher:F 20 0:TT 0 0:TT 0 -20:TT 20 -20", - [c2[0], c2[1], c2[2], nx, ny, nz, 0, 0, 1]) -[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) -arc = MakeArc(w,3,1) -w = geompy.MakeWire([e1,e2,e3,arc]) -f3 = geompy.MakeFace(w,1) - -w = geompy.MakeSketcher("Sketcher:F -20 -20:TT 0 -20:TT 0 0:TT -20 0", - [c2[0], c2[1], c2[2], nx, ny, nz, 0, 0, 1]) -[e1,e2,e3] = geompy.SubShapeAll(w, geompy.ShapeType["EDGE"]) -arc = MakeArc(w,3,1) -w = geompy.MakeWire([e1,e2,e3,arc]) -f4 = geompy.MakeFace(w,1) - -faces.append(f1) -faces.append(f2) -faces.append(f3) -faces.append(f4) -shell = geompy.MakeSewing(faces,1.e-6) -shells.append(shell) -faces = geompy.SubShapeAllSortedCentres(shell, geompy.ShapeType["FACE"]) -subbases.append(faces[2]) - -# 4 section -faces = [] - -kk = 4 -dx = c3[0] - nx/kk -dy = c3[1] - ny/kk -dz = c3[2] - nz/kk -rad = math.sqrt(nx*nx+ny*ny+nz*nz) -vc = geompy.MakeVertex(dx,dy,dz) -sph = geompy.MakeSpherePntR(vc,rad/kk) -shellsph = geompy.SubShapeAll(sph, geompy.ShapeType["SHELL"]) - -fs = [] -vec = geompy.MakeVectorDXDYDZ(0,0,1) -ff = geompy.MakePlane(ps[3],vec,40) -fs.append(ff) -vp = geompy.MakeVertex(c3[0],c3[1],c3[2]+20) -ff = geompy.MakePlane(vp,vec,40) -fs.append(ff) -vp = geompy.MakeVertex(c3[0],c3[1],c3[2]-20) -ff = geompy.MakePlane(vp,vec,40) -fs.append(ff) -vec = geompy.MakeVectorDXDYDZ(1,0,0) -ff = geompy.MakePlane(ps[3],vec,40) -fs.append(ff) -vp = geompy.MakeVertex(c3[0]+20,c3[1],c3[2]) -ff = geompy.MakePlane(vp,vec,40) -fs.append(ff) -vp = geompy.MakeVertex(c3[0]-20,c3[1],c3[2]) -ff = geompy.MakePlane(vp,vec,40) -fs.append(ff) -aPartition = geompy.MakePartition(shellsph,fs) -fs = geompy.SubShapeAllSortedCentres(aPartition, geompy.ShapeType["FACE"]) - -faces.append(fs[0]) -faces.append(fs[1]) -faces.append(fs[2]) -faces.append(fs[3]) -shell = geompy.MakeSewing(faces,1.e-6) -shells.append(shell) -faces = geompy.SubShapeAllSortedCentres(shell, geompy.ShapeType["FACE"]) - - -#=========================================================== -# Create Pipe -#=========================================================== -subbases = [] -Pipe = geompy.MakePipeWithShellSections(shells, subbases, theLocations, WirePath, - theWithContact=0, theWithCorrection=0) - -# add objects in the study -resc = geompy.MakeCompound(shells) -id_sec = geompy.addToStudy(resc,"sections") -id_wire = geompy.addToStudy(WirePath,"WirePath") -id_pipe = geompy.addToStudy(Pipe, "Pipe") - -# display the wire(path), sections and the pipe -gg.createAndDisplayGO(id_wire) -gg.createAndDisplayGO(id_sec) -gg.createAndDisplayGO(id_pipe) -gg.setDisplayMode(id_pipe,1) -\endcode - +\include complex_objs_ex06.py +Download this script \anchor tui_creation_pipe_without_path

    Creation of a PipeShellsWithoutPath

    - -\code -import geompy -import math -import salome -gg = salome.ImportComponentGUI("GEOM") - -# Add a section based on quadrangles -# ---------------------------------- -def section(s, p1, p2=None, p3=None, p4=None): - if p2==None: - q = p1 - else: - q = geompy.MakeQuad4Vertices(p1, p2, p3, p4) - pass - s.append(q) - publish(q, "section") - return q - - -# find distance between two points -# ------------------------------- -def Dist(p1,p2): - c1 = geompy.PointCoordinates(p1) - c2 = geompy.PointCoordinates(p2) - return math.sqrt( (c2[0]-c1[0])*(c2[0]-c1[0]) + - (c2[1]-c1[1])*(c2[1]-c1[1]) + - (c2[2]-c1[2])*(c2[2]-c1[2]) ) - - -# return middle point -# ------------------------------- -def MiddleVert(p1,p2): - c1 = geompy.PointCoordinates(p1) - c2 = geompy.PointCoordinates(p2) - return geompy.MakeVertex( (c2[0]+c1[0])/2, (c2[1]+c1[1])/2, (c2[2]+c1[2])/2 ) - - -# Complex section -# result - 16 quads from lines -# pnt - point from path -# vec - direction from path -def MakeComplexSect(pnt,vec,rmax,rmin,nb): - dang = 1.0/nb/2 - cmax = geompy.MakeCircle(pnt,vec,rmax) - cmin = geompy.MakeCircle(pnt,vec,rmin) - faces = [] - for i in range(0,2*nb,2): - p1 = geompy.MakeVertexOnCurve(cmin,dang*i) - p2 = geompy.MakeVertexOnCurve(cmax,dang*(i+1)) - p3 = geompy.MakeVertexOnCurve(cmin,dang*(i+2)) - f = geompy.MakeQuad4Vertices(pnt,p1,p2,p3) - faces.append(f) - pass - shell = geompy.MakeSewing(faces,1.e-6) - return shell - - -#======================================================= -# Create simple path and recieve points -# for section creation -#======================================================= -WirePath = geompy.MakeSketcher("Sketcher:F 0 0:T 60 0:T 40 0:R 0:C 100 90:", - [0, 0, 0, 0, 0, 1, 1, 0, 0]) -vs = geompy.SubShapeAll(WirePath, geompy.ShapeType["VERTEX"]) - -#======================================================= -# Create shell sections -#======================================================= -shells = [] -subbases = [] -locs = [] - -# 1 section -shell = MakeComplexSect(vs[0], geompy.MakeVectorDXDYDZ(1,0,0), 60, 40, 16) -shells.append(shell) -vs1 = geompy.SubShapeAllSortedCentres(shell,geompy.ShapeType["VERTEX"]) -locs.append(vs1[17]) - -# 2 section -shell = MakeComplexSect(vs[1], geompy.MakeVectorDXDYDZ(1,0,0), 80, 30, 16) -shells.append(shell) -vs2 = geompy.SubShapeAllSortedCentres(shell,geompy.ShapeType["VERTEX"]) -locs.append(vs2[17]) - -# 3 section -shell = MakeComplexSect(vs[2], geompy.MakeVectorDXDYDZ(1,0,0), 60, 40, 16) -shells.append(shell) -vs3 = geompy.SubShapeAllSortedCentres(shell,geompy.ShapeType["VERTEX"]) -locs.append(vs3[17]) - -# 4 section -shell = MakeComplexSect(vs[3], geompy.MakeVectorDXDYDZ(0,1,0), 40, 35, 16) -shells.append(shell) -vs4 = geompy.SubShapeAllSortedCentres(shell,geompy.ShapeType["VERTEX"]) -locs.append(vs4[17]) - - -#=========================================================== -# Create Pipe -#=========================================================== - -Pipe = geompy.MakePipeShellsWithoutPath(shells,locs) - -# add objects in the study -resc = geompy.MakeCompound(shells) -id_sec = geompy.addToStudy(resc,"sections") -resl = geompy.MakeCompound(locs) -id_loc = geompy.addToStudy(resl,"locations") -id_pipe = geompy.addToStudy(Pipe, "Pipe") - -# display the sections, locations and pipe -gg.createAndDisplayGO(id_sec) -gg.createAndDisplayGO(id_loc) -gg.createAndDisplayGO(id_pipe) -gg.setDisplayMode(id_pipe,1) -\endcode +\include complex_objs_ex07.py +Download this script \anchor tui_creation_pipe_binormal_along_vector

    Creation of a PipeBiNormalAlongVector

    - -\code -def MakeHelix(radius, height, rotation, direction): - # - create a helix - - radius = 1.0 * radius - height = 1.0 * height - rotation = 1.0 * rotation - if direction > 0: - direction = +1 - else: - direction = -1 - pass - from math import sqrt - length_z = height - length_xy = radius*rotation - length = sqrt(length_z*length_z + length_xy*length_xy) - import geompy - nb_steps = 1 - epsilon = 1.0e-6 - while 1: - z_step = height / nb_steps - angle_step = rotation / nb_steps - z = 0.0 - angle = 0.0 - helix_points = [] - for n in range(nb_steps+1): - from math import cos, sin - x = radius * cos(angle) - y = radius * sin(angle) - p = geompy.MakeVertex(x, y, z) - helix_points.append( p ) - z += z_step - angle += direction * angle_step - pass - helix = geompy.MakeInterpol(helix_points) - length_test = geompy.BasicProperties(helix)[0] - prec = abs(length-length_test)/length - # print nb_steps, length_test, prec - if prec < epsilon: - break - nb_steps *= 2 - pass - return helix - -def MakeSpring(radius, height, rotation, direction, thread_radius, base_rotation=0.0): - # - create a pipe - - thread_radius = 1.0 * thread_radius - # create a helix - helix = MakeHelix(radius, height, rotation, direction) - # base in the (Ox, Oz) plane - import geompy - p0 = geompy.MakeVertex(radius-3*thread_radius, 0.0, -thread_radius) - p1 = geompy.MakeVertex(radius+3*thread_radius, 0.0, -thread_radius) - p2 = geompy.MakeVertex(radius+3*thread_radius, 0.0, +thread_radius) - p3 = geompy.MakeVertex(radius-3*thread_radius, 0.0, +thread_radius) - e0 = geompy.MakeEdge(p0, p1) - e1 = geompy.MakeEdge(p1, p2) - e2 = geompy.MakeEdge(p2, p3) - e3 = geompy.MakeEdge(p3, p0) - w = geompy.MakeWire([e0, e1, e2, e3]) - # create a base face - base = geompy.MakeFace(w, True) - # create a binormal vector - binormal = geompy.MakeVectorDXDYDZ(0.0, 0.0, 10.0) - # create a pipe - spring = geompy.MakePipeBiNormalAlongVector(base, helix, binormal) - # Publish in the study - geompy.addToStudy(base, "base") - geompy.addToStudy(helix, "helix") - geompy.addToStudy(binormal, "binormal") - geompy.addToStudy(spring, "spring") - return spring - -from math import pi - -spring = MakeSpring(50, 100, 2*pi, 1, 5, pi/2) -\endcode - +\include complex_objs_ex08.py +Download this script \anchor tui_creation_pipe_path

    Creation of a Middle Path

    - -\code -import salome -import geompy - -# Create a box -Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) - -# Get two opposite faces -[Face_1,Face_2] = geompy.SubShapes(Box_1, [31, 33]) - -# Get edges -Box_1_edge_12 = geompy.GetSubShape(Box_1, [12]) -Box_1_edge_22 = geompy.GetSubShape(Box_1, [22]) -Box_1_edge_25 = geompy.GetSubShape(Box_1, [25]) -Box_1_edge_29 = geompy.GetSubShape(Box_1, [29]) -Box_1_edge_8 = geompy.GetSubShape(Box_1, [8]) -Box_1_edge_18 = geompy.GetSubShape(Box_1, [18]) -Box_1_edge_26 = geompy.GetSubShape(Box_1, [26]) -Box_1_edge_30 = geompy.GetSubShape(Box_1, [30]) - -# These three calls to RestorePath return the same result -Path_1 = geompy.RestorePath(Box_1, Face_1, Face_2) -Path_2 = geompy.RestorePathEdges(Box_1, [Face_1], [Face_2]) -Path_3 = geompy.RestorePathEdges(Box_1, - [Box_1_edge_12, Box_1_edge_22, Box_1_edge_25, Box_1_edge_29], - [Box_1_edge_8, Box_1_edge_18, Box_1_edge_26, Box_1_edge_30]) - -# Publish created objects -geompy.addToStudy( Box_1, 'Box_1' ) -geompy.addToStudyInFather( Box_1, Face_1, 'Face_1' ) -geompy.addToStudyInFather( Box_1, Face_2, 'Face_2' ) -geompy.addToStudyInFather( Box_1, Box_1_edge_25, 'Box_1:edge_25' ) -geompy.addToStudyInFather( Box_1, Box_1_edge_22, 'Box_1:edge_22' ) -geompy.addToStudyInFather( Box_1, Box_1_edge_12, 'Box_1:edge_12' ) -geompy.addToStudyInFather( Box_1, Box_1_edge_29, 'Box_1:edge_29' ) -geompy.addToStudyInFather( Box_1, Box_1_edge_18, 'Box_1:edge_18' ) -geompy.addToStudyInFather( Box_1, Box_1_edge_26, 'Box_1:edge_26' ) -geompy.addToStudyInFather( Box_1, Box_1_edge_8, 'Box_1:edge_8' ) -geompy.addToStudyInFather( Box_1, Box_1_edge_30, 'Box_1:edge_30' ) -geompy.addToStudy( Path_1, 'Path_1' ) -geompy.addToStudy( Path_2, 'Path_2' ) -geompy.addToStudy( Path_3, 'Path_3' ) -\endcode +\include complex_objs_ex09.py +Download this script

    Creation of Tangent Plane On Face

    -\code -import salome -import geompy - -# Create Vertexes for curve -Vertex_1 = geompy.MakeVertex(0, 0, 0) -Vertex_2 = geompy.MakeVertex(0, 90, 30) -Vertex_3 = geompy.MakeVertex(100, 90, 0) -Vertex_4 = geompy.MakeVertex(-100, 90, 0) -# Create curve -Curve_1 = geompy.MakeInterpol([Vertex_4, Vertex_2, Vertex_3, Vertex_1]) -# Create Face by Extrusion of the Curve -Extrusion_1 = geompy.MakePrismDXDYDZ(Curve_1, 0, 30, -60) -# Make Tangent on this Extrusion (Face) -Tangent_1 = geompy.MakeTangentPlaneOnFace(Extrusion_1, 0.7, 0.5, 150) -# Publish in the study -geompy.addToStudy( Vertex_1, "Vertex_1" ) -geompy.addToStudy( Vertex_2, "Vertex_2" ) -geompy.addToStudy( Vertex_3, "Vertex_3" ) -geompy.addToStudy( Vertex_4, "Vertex_4" ) -geompy.addToStudy( Curve_1, "Curve_1" ) -geompy.addToStudy( Extrusion_1, "Extrusion_1" ) -geompy.addToStudy( Tangent_1, "Tangent_1" ) -\endcode +\include complex_objs_ex10.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_free_boundaries.doc b/doc/salome/gui/GEOM/input/tui_free_boundaries.doc index b764df1b2..fb0420c6d 100644 --- a/doc/salome/gui/GEOM/input/tui_free_boundaries.doc +++ b/doc/salome/gui/GEOM/input/tui_free_boundaries.doc @@ -1,85 +1,7 @@ /*! \page tui_free_boundaries_page Check Free Boundaries - -\code -import os -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create boxes -box1 = geompy.MakeBox(0,0,0,100,50,100) -box2 = geompy.MakeBox(100,0,0,250,50,100) - -# make a compound -compound = geompy.MakeCompound([box1, box2]) - -# import from *.brep -ImportFromBREP = geompy.ImportBREP(os.getenv("DATA_DIR")+"/Shapes/Brep/flight_solid.brep") - -# get a face -faces = geompy.SubShapeAllSortedCentres(ImportFromBREP, geompy.ShapeType["FACE"]) - -# get the free boundary for face 32 -Res = geompy.GetFreeBoundary(faces[32]) -isSuccess = Res[0] -ClosedWires = Res[1] -OpenWires = Res[2] - -if isSuccess == 1 : - print "Checking free boudaries is OK." -else : - print "Checking free boudaries is KO!" -print "len(ClosedWires) = ", len(ClosedWires) - -i = 0 -for wire in ClosedWires : - wire_name = "Face 32 -> Close wires : WIRE %d"%(i+1) - geompy.addToStudy(ClosedWires[i], wire_name) - if i < len(ClosedWires) : - i = i+ 1 - -print "len(OpenWires) = ", len(OpenWires) - -i = 0 -for wire in OpenWires : - wire_name = "Face 32 -> Open wires : WIRE %d"%(i+1) - geompy.addToStudy(OpenWires[i], wire_name) - if i < len(OpenWires) : - i = i+ 1 - -# get the free boundary for face 41 -Res = geompy.GetFreeBoundary(faces[41]) -isSuccess = Res[0] -ClosedWires = Res[1] -OpenWires = Res[2] - -if isSuccess == 1 : - print "Checking free boudaries is OK." -else : - print "Checking free boudaries is KO!" -print "len(ClosedWires) = ", len(ClosedWires) - -i = 0 -for wire in ClosedWires : - wire_name = "Face 41 -> Close wires : WIRE %d"%(i+1) - geompy.addToStudy(ClosedWires[i], wire_name) - if i < len(ClosedWires) : - i = i+ 1 - -print "len(OpenWires) = ", len(OpenWires) - -i = 0 -for wire in OpenWires : - wire_name = "Face 41 -> Open wires : WIRE %d"%(i+1) - geompy.addToStudy(OpenWires[i], wire_name) - if i < len(OpenWires) : - i = i+ 1 - -# add the imported object to the study -id_ImportFromBREP = geompy.addToStudy(ImportFromBREP, "ImportFromBREP") -salome.sg.updateObjBrowser(1) -\endcode +\include free_boundaries.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_free_faces.doc b/doc/salome/gui/GEOM/input/tui_free_faces.doc index 7fd302288..00ae5bd23 100644 --- a/doc/salome/gui/GEOM/input/tui_free_faces.doc +++ b/doc/salome/gui/GEOM/input/tui_free_faces.doc @@ -1,52 +1,7 @@ /*! \page tui_free_faces_page Check Free Faces - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex(35, 35, 0) -p2 = geompy.MakeVertex(35, 35, 50) -v = geompy.MakeVector(p1, p2) - -# create a cylinder -cylinder = geompy.MakeCone(p1, v, 30, 20, 20) - -# create a cone -cone = geompy.MakeCone(p1, v, 70, 40, 60) - -# make cut -cut = geompy.MakeCut(cone, cylinder) - -# get faces as sub-shapes -faces = [] -faces = geompy.SubShapeAllSortedCentres(cut, geompy.ShapeType["FACE"]) -f_2 = geompy.GetSubShapeID(cut, faces[0]) - -# remove one face from the shape -cut_without_f_2 = geompy.SuppressFaces(cut, [f_2]) - -# suppress the specified wire -result = geompy.GetFreeFacesIDs(cut_without_f_2) -print "A number of free faces is ", len(result) - -# add objects in the study -all_faces = geompy.SubShapeAllSortedCentres(cut_without_f_2, geompy.ShapeType["FACE"]) -for face in all_faces : - sub_shape_id = geompy.GetSubShapeID(cut_without_f_2, face) - if result.count(sub_shape_id) > 0 : - face_name = "Free face %d"%(sub_shape_id) - geompy.addToStudy(face, face_name) - -# in this example all faces from cut_without_f_2 are free -id_cut_without_f_2 = geompy.addToStudy(cut_without_f_2, "Cut without f_2") - -# display the results -gg.createAndDisplayGO(id_cut_without_f_2) -gg.setDisplayMode(id_cut_without_f_2,1) -\endcode +\include free_faces.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_get_non_blocks.doc b/doc/salome/gui/GEOM/input/tui_get_non_blocks.doc index b83ea9647..ca7a98d8f 100644 --- a/doc/salome/gui/GEOM/input/tui_get_non_blocks.doc +++ b/doc/salome/gui/GEOM/input/tui_get_non_blocks.doc @@ -1,32 +1,7 @@ /*! \page tui_get_non_blocks_page Get Non Blocks - -\code -import geompy -import salome - -# create solids -box = geompy.MakeBoxDXDYDZ(100, 100, 100) -cyl = geompy.MakeCylinderRH(100, 200) - -geompy.addToStudy(box, 'box') -geompy.addToStudy(cyl, 'cyl') - -# make a compound -compound = geompy.MakeCompound([box, cyl]) -geompy.addToStudy(compound, 'compound') - -# explore the compound -pair = geompy.GetNonBlocks(compound) - -if pair[0] is not None: - geompy.addToStudyInFather(compound, pair[0], "GrNonBlocks") - pass - -if pair[1] is not None: - geompy.addToStudyInFather(compound, pair[1], "GrNonQuads") - pass -\endcode +\include get_non_blocks.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_import_export.doc b/doc/salome/gui/GEOM/input/tui_import_export.doc index cdd8c4ea0..52adf987e 100644 --- a/doc/salome/gui/GEOM/input/tui_import_export.doc +++ b/doc/salome/gui/GEOM/input/tui_import_export.doc @@ -1,45 +1,7 @@ /*! \page tui_import_export_page Import/Export -\code -import geompy -import salome - -# Example of import from IGES using various formats - -# get a path to SAMPLES_SRC -import os -thePath = os.getenv("DATA_DIR") -# create filenames -theFileName1 = thePath + "/Shapes/Iges/boite-3Dipsos_m.igs" -theFileName2 = thePath + "/Shapes/Iges/boite-3Dipsos_mm.igs" -#print "thePath = ", thePath - -# get units from files -UnitName1 = geompy.GetIGESUnit(theFileName1) -UnitName2 = geompy.GetIGESUnit(theFileName2) -print "UnitName1 = ", UnitName1 -print "UnitName2 = ", UnitName2 - -# import shapes -Shape1 = geompy.ImportIGES(theFileName1) -Shape2 = geompy.ImportIGES(theFileName2) -Shape3 = geompy.ImportFile(theFileName2,"IGES_SCALE") -[Xmin1,Xmax1, Ymin1,Ymax1, Zmin1,Zmax1] = geompy.BoundingBox(Shape1) -[Xmin2,Xmax2, Ymin2,Ymax2, Zmin2,Zmax2] = geompy.BoundingBox(Shape2) -[Xmin3,Xmax3, Ymin3,Ymax3, Zmin3,Zmax3] = geompy.BoundingBox(Shape3) -geompy.addToStudy(Shape1, "3Dipsos_m") -geompy.addToStudy(Shape2, "3Dipsos_mm") -geompy.addToStudy(Shape3, "3Dipsos_mm_scaled") -d1 = (Xmax1-Xmin1)*(Xmax1-Xmin1) + (Ymax1-Ymin1)*(Ymax1-Ymin1) + (Zmax1-Zmin1)*(Zmax1-Zmin1) -d2 = (Xmax2-Xmin2)*(Xmax2-Xmin2) + (Ymax2-Ymin2)*(Ymax2-Ymin2) + (Zmax2-Zmin2)*(Zmax2-Zmin2) -d3 = (Xmax3-Xmin3)*(Xmax3-Xmin3) + (Ymax3-Ymin3)*(Ymax3-Ymin3) + (Zmax3-Zmin3)*(Zmax3-Zmin3) -import math -dd32 = math.sqrt(d3/d2) -dd12 = math.sqrt(d1/d2) -dd31 = math.sqrt(d3/d1) -# values dd31, dd12 and dd31 can be using for checking -print "dd32 = ",dd32," dd12 = ",dd12," dd31 = ",dd31 -\endcode +\include import_export.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_inertia.doc b/doc/salome/gui/GEOM/input/tui_inertia.doc index 29530e292..a62b20784 100644 --- a/doc/salome/gui/GEOM/input/tui_inertia.doc +++ b/doc/salome/gui/GEOM/input/tui_inertia.doc @@ -1,20 +1,7 @@ /*! \page tui_inertia_page Inertia - -\code -import geompy -import math - -# create a box -box = geompy.MakeBoxDXDYDZ(100,30,100) -In = geompy.Inertia(box) -print "\nInertia matrix of box 100x30x100:" -print " (", In[0], ", ", In[1], ", ", In[2], ")" -print " (", In[3], ", ", In[4], ", ", In[5], ")" -print " (", In[6], ", ", In[7], ", ", In[8], ")" -print "Main moments of inertia of box 100x30x100:" -print " Ix = ", In[9], ", Iy = ", In[10], ", Iz = ", In[11] -\endcode +\include inertia.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_min_distance.doc b/doc/salome/gui/GEOM/input/tui_min_distance.doc index e26e219f9..db024ca4b 100644 --- a/doc/salome/gui/GEOM/input/tui_min_distance.doc +++ b/doc/salome/gui/GEOM/input/tui_min_distance.doc @@ -1,15 +1,7 @@ /*! \page tui_min_distance_page Minimal Distance - -\code -import geompy - -# create boxes -box1 = geompy.MakeBoxDXDYDZ(100,30,100) -box2 = geompy.MakeBox(105,0,0,200,30,100) -min_dist = geompy.MinDistance(box1,box2) -print "\nMinimal distance between box1 and box2 = ", min_dist -\endcode +\include min_distance.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_normal_face.doc b/doc/salome/gui/GEOM/input/tui_normal_face.doc index 0c81116a8..7d31fcc26 100644 --- a/doc/salome/gui/GEOM/input/tui_normal_face.doc +++ b/doc/salome/gui/GEOM/input/tui_normal_face.doc @@ -1,23 +1,7 @@ /*! \page tui_normal_face_page Normal to a Face - -\code -import geompy -import math - -# create a box -box = geompy.MakeBoxDXDYDZ(100,30,100) - -faces = geompy.SubShapeAllSortedCentres(box, geompy.ShapeType["FACE"]) -face0 = faces[0] -vnorm = geompy.GetNormal(face0) -if vnorm is None: - raise RuntimeError, "GetNormal(face0) failed" -else: - geompy.addToStudy(face0, "Face0") - geompy.addToStudy(vnorm, "Normale to Face0") - print "\nNormale of face has been successfully obtained" -\endcode +\include normal_face.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_notebook_geom.doc b/doc/salome/gui/GEOM/input/tui_notebook_geom.doc index 629ce6329..8db9c59d2 100644 --- a/doc/salome/gui/GEOM/input/tui_notebook_geom.doc +++ b/doc/salome/gui/GEOM/input/tui_notebook_geom.doc @@ -3,27 +3,7 @@ \page tui_notebook_geom_page Using SALOME NoteBook \anchor tui_notebook_geom - -\code -import geompy -import salome -import salome_notebook -gg = salome.ImportComponentGUI("GEOM") - -# set variables -notebook = salome_notebook.notebook -notebook.set("Length", 150) -notebook.set("Width", 100) - -# create box -box = geompy.MakeBoxDXDYDZ("Length", "Width", 200) - -# add object in the study -id_box = geompy.addToStudy(box,"Box") - -# display the boxes -gg.createAndDisplayGO(id_box) -gg.setDisplayMode(id_box,1) -\endcode +\include notebook_geom.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_point_coordinates.doc b/doc/salome/gui/GEOM/input/tui_point_coordinates.doc index 0f138367b..6fbb9c9a6 100644 --- a/doc/salome/gui/GEOM/input/tui_point_coordinates.doc +++ b/doc/salome/gui/GEOM/input/tui_point_coordinates.doc @@ -1,27 +1,7 @@ /*! \page tui_point_coordinates_page Point Coordinates +\include point_coordinates.py +Download this script -\code -import math -import geompy - -# create a point -point = geompy.MakeVertex(15., 23., 80.) - -# get the coordinates of the point and check its values -coords = geompy.PointCoordinates(point) - -# check the obtained coordinate values -tolerance = 1.e-07 -def IsEqual(val1, val2): return (math.fabs(val1 - val2) < tolerance) - -if IsEqual(coords[0], 15.) and IsEqual(coords[1], 23.) and IsEqual(coords[2], 80.): - print "All values are OK." -else : - print "Coordinates of point must be (15, 23, 80), but returned (", - print coords[0], ", ", coords[1], ", ", coords[2], ")" - pass -\endcode - -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/GEOM/input/tui_primitives.doc b/doc/salome/gui/GEOM/input/tui_primitives.doc index af7670ea8..9c4f49d55 100644 --- a/doc/salome/gui/GEOM/input/tui_primitives.doc +++ b/doc/salome/gui/GEOM/input/tui_primitives.doc @@ -4,230 +4,37 @@ \anchor tui_creation_box

    Creation of a Box

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p0 = geompy.MakeVertex(15, 25, 35) -p70 = geompy.MakeVertex(70, 70, 70) - -# create boxes -box1 = geompy.MakeBoxDXDYDZ(10, 20, 30) -box2 = geompy.MakeBox(10,20,30, 15,25,35) -box3 = geompy.MakeBoxTwoPnt(p0, p70) - -# add objects in the study -id_box1 = geompy.addToStudy(box1,"Box1") -id_box2 = geompy.addToStudy(box2,"Box2") -id_box3 = geompy.addToStudy(box3,"Box3") - -# display the boxes -gg.createAndDisplayGO(id_box1) -gg.setDisplayMode(id_box1,1) -gg.createAndDisplayGO(id_box2) -gg.setDisplayMode(id_box2,1) -gg.createAndDisplayGO(id_box3) -gg.setDisplayMode(id_box3,1) -\endcode +\include primitives_ex01.py +Download this script \anchor tui_creation_cylinder

    Creation of a Cylinder

    - -\code -import geompy -import salome - -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex(25, 35, 45) -p2 = geompy.MakeVertex(70, 70, 70) -v = geompy.MakeVector(p1, p2) - -# create cylinders -height = 40 - -radius1 = 15 -cylinder1 = geompy.MakeCylinder(p1, v, radius1, height) - -radius2 = 30 -cylinder2 = geompy.MakeCylinderRH(radius2, height) - -# add objects in the study -id_cylinder1 = geompy.addToStudy(cylinder1,"Cylinder1") -id_cylinder2 = geompy.addToStudy(cylinder2,"Cylinder2") - -# display the cylinders -gg.createAndDisplayGO(id_cylinder1) -gg.setDisplayMode(id_cylinder1,1) -gg.createAndDisplayGO(id_cylinder2) -gg.setDisplayMode(id_cylinder2,1) -\endcode +\include primitives_ex02.py +Download this script \anchor tui_creation_sphere

    Creation of a Sphere

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex -p = geompy.MakeVertex(55, 45, 25) - -# create spheres -radius1 = 20 -sphere1 = geompy.MakeSpherePntR(p, radius1) -radius2 = 15 -sphere2 = geompy.MakeSphere(0, 0, 45, radius2) -radius3 = 30 -sphere3 = geompy.MakeSphereR(radius3) - -# add objects in the study -id_sphere1 = geompy.addToStudy(sphere1,"Sphere1") -id_sphere2 = geompy.addToStudy(sphere2,"Sphere2") -id_sphere3 = geompy.addToStudy(sphere3,"Sphere3") - -# display spheres -gg.createAndDisplayGO(id_sphere1) -gg.setDisplayMode(id_sphere1,1) -gg.createAndDisplayGO(id_sphere2) -gg.setDisplayMode(id_sphere2,1) -gg.createAndDisplayGO(id_sphere3) -gg.setDisplayMode(id_sphere3,1) -\endcode +\include primitives_ex03.py +Download this script \anchor tui_creation_torus

    Creation of a Torus

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex(35, 40, 45) -p2 = geompy.MakeVertex(35, 45, 70) -v = geompy.MakeVector(p1, p2) - -# create toruses -torus1 = geompy.MakeTorus(p1, v, 20, 10) -torus2 = geompy.MakeTorusRR(30, 15) - -# add objects in the study -id_torus1 = geompy.addToStudy(torus1,"Torus1") -id_torus2 = geompy.addToStudy(torus2,"Torus2") - -# display toruses -gg.createAndDisplayGO(id_torus1) -gg.setDisplayMode(id_torus1,1) -gg.createAndDisplayGO(id_torus2) -gg.setDisplayMode(id_torus2,1) -\endcode +\include primitives_ex04.py +Download this script \anchor tui_creation_cone

    Creation of a Cone

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex(35, 35, 0) -p2 = geompy.MakeVertex(35, 35, 70) -v = geompy.MakeVector(p1, p2) - -# create cones -cone1 = geompy.MakeCone(p1, v, 17, 1, 20) -cone2 = geompy.MakeConeR1R2H(30, 10, 30) - -# add objects in the study -id_cone1 = geompy.addToStudy(cone1,"Cone1") -id_cone2 = geompy.addToStudy(cone2,"Cone2") - -# display cones -gg.createAndDisplayGO(id_cone1) -gg.setDisplayMode(id_cone1,1) -gg.createAndDisplayGO(id_cone2) -gg.setDisplayMode(id_cone2,1) -\endcode +\include primitives_ex05.py +Download this script \anchor tui_creation_disk

    Creation of a Disk

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p0 = geompy.MakeVertex(0., 0., 0.) -px = geompy.MakeVertex(100., 0. , 0. ) -py = geompy.MakeVertex(0. , 100., 0. ) -pz = geompy.MakeVertex(0. , 0. , 100.) - -# create a vector on two points -vxy = geompy.MakeVector(px, py) - -# create a disk in OXY plane -disk1 = geompy.MakeDiskR(100, 1) - -# create a disk from a point, a vector and a radius -disk2 = geompy.MakeDiskPntVecR(pz, vxy, 30) - -#create a circle from three points -disk3 = geompy.MakeDiskThreePnt(p0, px, py) - -# add objects in the study -id_vxy = geompy.addToStudy(vxy, "Vector") -id_disk1 = geompy.addToStudy(disk1,"Disk1") -id_disk2 = geompy.addToStudy(disk2,"Disk2") -id_disk3 = geompy.addToStudy(disk3,"Disk3") - -# display disks -gg.createAndDisplayGO(id_vxy) -gg.createAndDisplayGO(id_disk1) -gg.createAndDisplayGO(id_diks2) -gg.createAndDisplayGO(id_diks3) -\endcode +\include primitives_ex06.py +Download this script \anchor tui_creation_squareface

    Creation of a Rectangle

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -px = geompy.MakeVertex(100., 0. , 0. ) -py = geompy.MakeVertex(0. , 100., 0. ) - -# create a vector on two points -vxy = geompy.MakeVector(px, py) - -# create a rectangle in OXY plane -face1 = geompy.MakeFaceHW(100, 100, 1) - -# create a rectangle using normal vector -face2 = geompy.MakeFaceObjHW(vxy, 50, 150) - -# create a rectangle from other face -face3 = geompy.MakeFaceObjHW(face2, 150, 50) - -# add objects in the study -id_face1 = geompy.addToStudy(face1,"Face1") -id_face2 = geompy.addToStudy(face2,"Face2") -id_face3 = geompy.addToStudy(face3,"Face3") - -# display rectangles -gg.createAndDisplayGO(id_face1) -gg.createAndDisplayGO(id_face2) -gg.createAndDisplayGO(id_face3) -\endcode +\include primitives_ex07.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_repairing_operations.doc b/doc/salome/gui/GEOM/input/tui_repairing_operations.doc index 0ce8b63db..286731970 100644 --- a/doc/salome/gui/GEOM/input/tui_repairing_operations.doc +++ b/doc/salome/gui/GEOM/input/tui_repairing_operations.doc @@ -4,444 +4,57 @@ \anchor tui_shape_processing

    Shape Processing

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices, an edge, an arc, a wire, a face and a prism -p1 = geompy.MakeVertex(0,0,0) -p2 = geompy.MakeVertex(200,0,0) -p3 = geompy.MakeVertex(100,150,0) -edge = geompy.MakeEdge(p1,p2) -arc = geompy.MakeArc(p1,p3,p2) -wire = geompy.MakeWire([edge,arc]) -face = geompy.MakeFace(wire, 1) -theShape = geompy.MakePrismVecH(face, edge, 130) - -# check the shape at the beginning -print "Before ProcessShape:" -isValid = geompy.CheckShape(theShape) -if isValid == 0: - print "The shape is not valid" -else: - print "The shape seems to be valid" - -# process the Shape -Operators = ["FixShape"] -Parameters = ["FixShape.Tolerance3d"] -Values = ["1e-7"] -PS = geompy.ProcessShape(theShape, Operators, Parameters, Values) - -# check the shape at the end -print "After ProcessShape:" -isValid = geompy.CheckShape(PS) -if isValid == 0: - print "The shape is not valid" - raise RuntimeError, "It seems, that the ProcessShape() has failed" -else: - print "The shape seems to be valid" - -# add in the study and display -Id_Shape = geompy.addToStudy(theShape, "Invalid Shape") -Id_PS = geompy.addToStudy(PS, "Processed Shape") -gg.createAndDisplayGO(Id_Shape) -gg.setDisplayMode(Id_Shape,1) -gg.createAndDisplayGO(Id_PS) -gg.setDisplayMode(Id_PS,1) -\endcode +\include repairing_operations_ex01.py +Download this script \anchor tui_suppress_faces

    Suppress Faces

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a box -box = geompy.MakeBoxDXDYDZ(200, 200, 200) - -# The list of IDs (IDList) for suppress faces -sup_faces = [] -sup_faces = geompy.SubShapeAllSortedCentres(box, geompy.ShapeType["FACE"]) - -# get indices of the sub-shape -f1_id = geompy.GetSubShapeID(box, sup_faces[3]) - -# remove faces from the given object (shape) -result = geompy.SuppressFaces(box, [f1_id]) - -# add objects in the study -id_box = geompy.addToStudy(box, "Box") -id_result = geompy.addToStudy(result, "Result") - -# display the results -gg.createAndDisplayGO(id_box) -gg.setDisplayMode(id_box,1) -gg.createAndDisplayGO(id_result) -gg.setDisplayMode(id_result,1) -\endcode +\include repairing_operations_ex02.py +Download this script \anchor tui_close_contour

    Close Contour

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices and vectors -p0 = geompy.MakeVertex( 0., 0., 0.) -px = geompy.MakeVertex(100., 0., 0.) -py = geompy.MakeVertex( 0., 100., 0.) -py1 = geompy.MakeVertex( 0., 140., 0.) -pz = geompy.MakeVertex( 0., 0., 100.) -vxy = geompy.MakeVector(px, py) - -# create an arc -arc = geompy.MakeArc(py1, pz, px) - -# create a wire -wire = geompy.MakeWire([vxy, arc]) - -# close an open wire by creation of an edge between ends -wire_close = geompy.CloseContour(wire, [1], 0) - -# add objects in the study -id_wire = geompy.addToStudy(wire, "Wire") -id_wire_close = geompy.addToStudy(wire_close, "Wire close") - -# display the results -gg.createAndDisplayGO(id_wire) -gg.createAndDisplayGO(id_wire_close) -\endcode +\include repairing_operations_ex03.py +Download this script \anchor tui_suppress_internal_wires

    Suppress Internal Wires

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex(55, 65, 50) -p2 = geompy.MakeVertex(55, 0, 50) -v = geompy.MakeVector(p1, p2) - -# create a cylinder -height = 100 -radius1 = 40 -cylinder = geompy.MakeCylinder(p1, v, radius1, height) - -# create a box -box = geompy.MakeBoxDXDYDZ(100, 100, 100) - -# make a cut -cut = geompy.MakeCut(box, cylinder) - -# suppress all internal wires -result = geompy.SuppressInternalWires(cut, []) - -# add objects in the study -id_cut = geompy.addToStudy(cut, "Cut") -id_result = geompy.addToStudy(result, "Result") - -# display the results -gg.createAndDisplayGO(id_cut) -gg.setDisplayMode(id_cut,1) -gg.createAndDisplayGO(id_result) -gg.setDisplayMode(id_result,1) -\endcode +\include repairing_operations_ex04.py +Download this script \anchor tui_suppress_holes

    Suppress Holes

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex(35, 35, 0) -p2 = geompy.MakeVertex(35, 35, 50) -v = geompy.MakeVector(p1, p2) - -# create a cylinder -height = 20 -radius1 = 20 -cylinder = geompy.MakeCylinder(p1, v, radius1, height) - -# create a cone -cone = geompy.MakeCone(p1, v, 70, 0, 80) - -# make a cut -cut = geompy.MakeCut(cone, cylinder) - -# get faces as sub-shapes -faces = [] -faces = geompy.SubShapeAllSortedCentres(cut, geompy.ShapeType["FACE"]) -f_2 = geompy.GetSubShapeID(cut, faces[2]) - -# remove one face from the shape -cut_without_f_2 = geompy.SuppressFaces(cut, [f_2]) - -# get wires as sub-shapes -wires = [] -wires = geompy.SubShapeAllSortedCentres(cut_without_f_2, geompy.ShapeType["WIRE"]) -w_0 = geompy.GetSubShapeID(cut_without_f_2, wires[0]) - -# suppress the selected wire -result = geompy.SuppressHoles(cut_without_f_2, [w_0]) - -# add objects in the study -id_cut = geompy.addToStudy(cut, "Cut") -id_cut_without_f_2 = geompy.addToStudy(cut_without_f_2, "Cut without f_2") -id_result = geompy.addToStudy(result, "Result") - -# display the results -gg.createAndDisplayGO(id_cut) -gg.setDisplayMode(id_cut,1) -gg.createAndDisplayGO(id_cut_without_f_2) -gg.setDisplayMode(id_cut_without_f_2,1) -gg.createAndDisplayGO(id_result) -gg.setDisplayMode(id_result,1) -\endcode +\include repairing_operations_ex05.py +Download this script \anchor tui_sewing

    Sewing

    - -\code -import geompy -import salome -import math -gg = salome.ImportComponentGUI("GEOM") - -# create base points -px = geompy.MakeVertex(100., 0., 0.) -py = geompy.MakeVertex(0., 100., 0.) -pz = geompy.MakeVertex(0., 0., 100.) - -# create base geometry 2D & 3D -vector = geompy.MakeVector(px, py) -arc = geompy.MakeArc(py, pz, px) - -# create base objects -angle = 45. * math.pi / 180 -WantPlanarFace = 1 #True -wire = geompy.MakeWire([vector, arc]) -face = geompy.MakeFace(wire, WantPlanarFace) -face_rot = geompy.MakeRotation(face, vector, angle) - -# make sewing -precision = 0.00001 -sewing = geompy.MakeSewing([face, face_rot], precision) - -# add objects in the study -id_face = geompy.addToStudy(face, "Face") -id_face_rot = geompy.addToStudy(face_rot, "Face rotation") -id_sewing = geompy.addToStudy(sewing, "Sewing") - -# display the results -gg.createAndDisplayGO(id_face) -gg.setDisplayMode(id_face,1) -gg.createAndDisplayGO(id_face_rot) -gg.setDisplayMode(id_face_rot,1) -gg.createAndDisplayGO(id_sewing) -gg.setDisplayMode(id_sewing,1) -\endcode +\include repairing_operations_ex06.py +Download this script \anchor tui_glue_faces

    Glue Faces

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create boxes -box1 = geompy.MakeBox(0,0,0,100,50,100) -box2 = geompy.MakeBox(100,0,0,250,50,100) - -# make compound -compound = geompy.MakeCompound([box1, box2]) - -# glue compound's faces -tolerance = 1e-5 -glue = geompy.MakeGlueFaces(compound, tolerance) - -# add objects in study -id_box1 = geompy.addToStudy(box1, "Box1") -id_box2 = geompy.addToStudy(box2, "Box2") -id_compound = geompy.addToStudy(compound, "Compound") -id_glue = geompy.addToStudy(glue, "Glue faces") - -# display results -gg.createAndDisplayGO(id_box1) -gg.setDisplayMode(id_box1,1) -gg.createAndDisplayGO(id_box2) -gg.setDisplayMode(id_box2,1) -gg.createAndDisplayGO(id_compound) -gg.setDisplayMode(id_compound,1) -gg.createAndDisplayGO(id_glue) -gg.setDisplayMode(id_glue,1) -\endcode +\include repairing_operations_ex07.py +Download this script \anchor tui_glue_edges

    Glue Edges

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create boxes -box1 = geompy.MakeBox(0,0,0,100,50,100) -box2 = geompy.MakeBox(100,0,0,250,50,100) - -# make compound -compound = geompy.MakeCompound([box1, box2]) - -# glue all compound's edges -tolerance = 1e-5 -glue1 = geompy.MakeGlueEdges(compound, tolerance) - -# glue some compound's edges -list_edges = geompy.GetGlueEdges(compound, tolerance) -glue2 = geompy.MakeGlueEdgesByList(compound, tolerance, [list_edges[0], list_edges[2]]) - -# add objects in study -geompy.addToStudy(box1, "Box1") -geompy.addToStudy(box2, "Box2") -geompy.addToStudy(compound, "Compound") -geompy.addToStudy(glue1, "Glue all edges") -geompy.addToStudy(glue2, "Glue two edges") - -if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) -\endcode +\include repairing_operations_ex08.py +Download this script \anchor tui_limit_tolerance

    Limit Tolerance

    - -\code -import geompy -gg = salome.ImportComponentGUI("GEOM") - -# import initial topology -shape1 = geompy.ImportBREP("my_shape_1.brep") -shape2 = geompy.ImportBREP("my_shape_2.brep") - -geompy.addToStudy(shape1, "Shape 1") -geompy.addToStudy(shape2, "Shape 2") - -# perform partition -try: - part = geompy.MakePartition([shape1, shape2]) -except: - # limit tolerance - tolerance = 1e-07 - shape1_lt = geompy.LimitTolerance(shape1, tolerance) - shape2_lt = geompy.LimitTolerance(shape2, tolerance) - - # process shape - good_shape1 = geompy.ProcessShape(shape1_lt, ["FixShape"], ["FixShape.Tolerance3d"], ["1e-7"]) - good_shape2 = geompy.ProcessShape(shape2_lt, ["FixShape"], ["FixShape.Tolerance3d"], ["1e-7"]) - - geompy.addToStudy(good_shape1, "Shape 1 corrected") - geompy.addToStudy(good_shape2, "Shape 2 corrected") - - # perform partition on corrected shapes - part = geompy.MakePartition([good_shape1, good_shape2]) - pass - -geompy.addToStudy(part, "Partition") -\endcode +\include repairing_operations_ex09.py +Download this script \anchor tui_add_point_on_edge

    Add Point on Edge

    - -\code -import geompy -import salome - -# create vertices -p1 = geompy.MakeVertex(0,0,50) -p2 = geompy.MakeVertex(60,0,50) - -# make an edge -edge = geompy.MakeEdge(p1, p2) #geompy.GetSubShape(box, edge_ind) - -# divide an edge -divide = geompy.DivideEdge(edge, -1, 0.5, 0) - -# add objects in the study -id_edge = geompy.addToStudy(edge, "Edge") -edge_points = geompy.SubShapeAllSortedCentres(edge, geompy.ShapeType["VERTEX"]) -for point in edge_points: - geompy.addToStudyInFather(edge, point, "Edge's point") - -id_divide = geompy.addToStudy(divide, "Divided edge") -edge_points = geompy.SubShapeAllSortedCentres(divide, geompy.ShapeType["VERTEX"]) -for point in edge_points: - geompy.addToStudyInFather(divide, point, "Edge's point after divide") - -salome.sg.updateObjBrowser(1) -\endcode +\include repairing_operations_ex10.py +Download this script \anchor tui_fuse_collinear_edges

    Fuse Collinear Edges within a Wire

    - -\code -import geompy -import salome - -# create vertices -p1 = geompy.MakeVertex(0, 0, 0) -p2 = geompy.MakeVertex(70, 0, 0) -p3 = geompy.MakeVertex(70, 50, 0) -p4 = geompy.MakeVertex(70, 80, 0) -p5 = geompy.MakeVertex(50, 80, 0) -p6 = geompy.MakeVertex(20, 80, 0) -p7 = geompy.MakeVertex(0, 80, 0) -p8 = geompy.MakeVertex(0, 30, 0) - -points = [p1, p2, p3, p4, p5, p6, p7, p8] - -# make a wire -wire_1 = geompy.MakePolyline(points, True) - -# suppress some vertices in the wire -wire_2 = geompy.FuseCollinearEdgesWithinWire(wire_1, [p3]) -wire_3 = geompy.FuseCollinearEdgesWithinWire(wire_1, [p5, p6]) - -# suppress all suitable vertices in the wire -wire_4 = geompy.FuseCollinearEdgesWithinWire(wire_1, []) - -wires = [wire_1, wire_2, wire_3, wire_4] - -# add objects in the study -ii = 1 -for point in points: - geompy.addToStudy(point, "p%d"%ii) - ii = ii + 1 - pass - -ii = 1 -for wire in wires: - geompy.addToStudy(wire, "wire_%d"%ii) - wire_points = geompy.SubShapeAllSortedCentres(wire, geompy.ShapeType["VERTEX"]) - jj = 1 - for point in wire_points: - geompy.addToStudyInFather(wire, point, "point_%d"%jj) - jj = jj + 1 - pass - ii = ii + 1 - pass - -salome.sg.updateObjBrowser(1) -\endcode +\include repairing_operations_ex11.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_sketcher.doc b/doc/salome/gui/GEOM/input/tui_sketcher.doc index e344eae27..be24fd763 100644 --- a/doc/salome/gui/GEOM/input/tui_sketcher.doc +++ b/doc/salome/gui/GEOM/input/tui_sketcher.doc @@ -1,48 +1,7 @@ /*! \page tui_sketcher_page 2D Sketcher - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p1 = geompy.MakeVertex(70., 0., 0.) -p2 = geompy.MakeVertex(70., 70., 80.) -p3 = geompy.MakeVertex( 0., 70., 0.) - -#create a vector from two points -vector_arc = geompy.MakeVector(p1, p3) - -# create an arc from three points -arc = geompy.MakeArc(p1, p2, p3) - -# create a wire -wire = geompy.MakeWire([vector_arc, arc]) - -# create a planar face -isPlanarWanted = 1 -face = geompy.MakeFace(wire, isPlanarWanted) - -# create a sketcher (face), following the textual description -sketcher1 = geompy.MakeSketcher("Sketcher:F -100 -100:TT 250 -100:R 0:C 100 150:R 0:L 300:WF", - [100,0,0, 1,1,1, -1,1,0]) - -# create a sketcher (wire) on the given face -sketcher2 = geompy.MakeSketcherOnPlane("Sketcher:F 10 -30:R 10:C 20 180:R 15:L 50:WW", face) - -# add objects in the study -id_face = geompy.addToStudy(face,"Face") -id_sketcher1 = geompy.addToStudy(sketcher1,"Sketcher1") -id_sketcher2 = geompy.addToStudy(sketcher2,"Sketcher2") - -# display the first sketcher and the second sketcher with its planar face -gg.createAndDisplayGO(id_face) -gg.setDisplayMode(id_face,1) -gg.setTransparency(id_face,0.5) -gg.createAndDisplayGO(id_sketcher1) -gg.createAndDisplayGO(id_sketcher2) -\endcode +\include sketcher.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_tolerance.doc b/doc/salome/gui/GEOM/input/tui_tolerance.doc index 55151302a..4da20b249 100644 --- a/doc/salome/gui/GEOM/input/tui_tolerance.doc +++ b/doc/salome/gui/GEOM/input/tui_tolerance.doc @@ -1,20 +1,7 @@ /*! \page tui_tolerance_page Tolerance - -\code -import geompy - -# create a box -box = geompy.MakeBoxDXDYDZ(100,30,100) -Toler = geompy.Tolerance(box) -print "\nBox 100x30x100 tolerance:" -print " Face min. tolerance: ", Toler[0] -print " Face max. tolerance: ", Toler[1] -print " Edge min. tolerance: ", Toler[2] -print " Edge max. tolerance: ", Toler[3] -print " Vertex min. tolerance: ", Toler[4] -print " Vertex max. tolerance: ", Toler[5] -\endcode +\include tolerance.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_topological_geom_objs.doc b/doc/salome/gui/GEOM/input/tui_topological_geom_objs.doc index e314abc85..2b9f5d1c2 100644 --- a/doc/salome/gui/GEOM/input/tui_topological_geom_objs.doc +++ b/doc/salome/gui/GEOM/input/tui_topological_geom_objs.doc @@ -4,258 +4,32 @@ \anchor tui_creation_edge

    Creation of an Edge

    +\include topological_geom_objs_ex01.py +Download this script -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# -# create edge by two points -# - -# create vertices -p0 = geompy.MakeVertex(0. , 0. , 0. ) -pxyz = geompy.MakeVertex(100., 100., 100.) - -# create an edge -edge = geompy.MakeEdge(p0, pxyz) - -# add object in the study -id_edge = geompy.addToStudy(edge,"Edge_1") - -# display an edge -gg.createAndDisplayGO(id_edge) - -# -# create edge from wire -# - -# create a circle -c = geompy.MakeCircle(None, None, 100) - -# create a wire -w = geompy.MakeWire([c], 1e-07) - -# create an edge from wire -edge = geompy.MakeEdgeWire(w) - -# add object in the study -id_edge = geompy.addToStudy(edge,"Edge_2") - -# display an edge -gg.createAndDisplayGO(id_edge) - -# -# create edge from existing curve and a length -# - -# create a circle -c = geompy.MakeCircle(None, None, 100) - -# create an edge of length 25.0 from the circle -edge = geompy.MakeEdgeOnCurveByLength(c, 25.0) - -# add object in the study -id_edge = geompy.addToStudy(edge,"Edge_3") - -# display an edge -gg.createAndDisplayGO(id_edge) - -\endcode - \anchor tui_creation_wire

    Creation of a Wire

    +\include topological_geom_objs_ex02.py +Download this script -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -px = geompy.MakeVertex(100., 0. , 0. ) -py = geompy.MakeVertex(0. , 100., 0. ) -pz = geompy.MakeVertex(0. , 0. , 100.) - -# create a vector from two points -vxy = geompy.MakeVector(px, py) - -# create an arc from three points -arc = geompy.MakeArc(py, pz, px) - -# create a wire -wire = geompy.MakeWire([vxy, arc]) - -# add an object in the study -id_wire = geompy.addToStudy(wire,"Wire") - -# display the wire -gg.createAndDisplayGO(id_wire) -\endcode - \anchor tui_creation_face

    Creation of a Face

    +\include topological_geom_objs_ex03.py +Download this script -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices -p0 = geompy.MakeVertex(0. , 0. , 0. ) -px = geompy.MakeVertex(100., 0. , 0. ) -py = geompy.MakeVertex(0. , 100., 0. ) -pz = geompy.MakeVertex(0. , 0. , 100.) -pxyz = geompy.MakeVertex(100., 100., 100.) - -# create a vector from two points -vxy = geompy.MakeVector(px, py) - -# create an arc from three points -arc = geompy.MakeArc(py, pz, px) - -# create a wire -wire = geompy.MakeWire([vxy, arc]) - -# create sketchers -sketcher1 = geompy.MakeSketcher("Sketcher:F -100 -100:TT 250 -100:R 0:C 100 150:R 0:L 300:WW", - [100,0,0, 1,1,1, -1,1,0]) -sketcher2 = geompy.MakeSketcher("Sketcher:F 0 0:TT 70 0:TT 70 70:TT 0 70:WW") -sketcher3 = geompy.MakeSketcher("Sketcher:F 20 20:TT 50 20:TT 50 50:TT 20 50:WW") -isPlanarFace = 1 - -# create a face from the wire -face1 = geompy.MakeFace(wire, isPlanarFace) - -# create faces from two wires -face2 = geompy.MakeFaceWires([wire, sketcher1],isPlanarFace) -face3 = geompy.MakeFaces([sketcher2, sketcher3],isPlanarFace) - -# add objects in the study -id_face1 = geompy.addToStudy(face1,"Face1") -id_face2 = geompy.addToStudy(face2,"Face2") -id_face3 = geompy.addToStudy(face3,"Face3") - -# display the faces -gg.createAndDisplayGO(id_face1) -gg.setDisplayMode(id_face1,1) -gg.setTransparency(id_face1,0.2) -gg.createAndDisplayGO(id_face2) -gg.setDisplayMode(id_face2,1) -gg.setTransparency(id_face2,0.2) -gg.createAndDisplayGO(id_face3) -gg.setDisplayMode(id_face3,1) -gg.setTransparency(id_face3,0.2) -\endcode - \anchor tui_creation_shell

    Creation of a Shell

    +\include topological_geom_objs_ex04.py +Download this script -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -#create vertices -p0 = geompy.MakeVertex( 0., 0., 0.) -pxyz = geompy.MakeVertex( 5., 5., 40.) - -# create sketchers -sketcher1 = geompy.MakeSketcher("Sketcher:F 0 0:TT 70 0:TT 70 70:TT 0 70:WW") -sketcher2 = geompy.MakeSketcher("Sketcher:F 20 20:TT 50 20:TT 50 50:TT 20 50:WW") -isPlanarFace = 1 - -# create a face from two wires -face = geompy.MakeFaces([sketcher1, sketcher2],isPlanarFace) - -# create a prism -prism = geompy.MakePrism(face, p0, pxyz) - -# explode the prism into faces -prism_faces = geompy.SubShapeAllSortedCentres(prism, geompy.ShapeType["FACE"]) - -# create a shell from a set of faces -shell = geompy.MakeShell([prism_faces[0], prism_faces[2], prism_faces[3], - prism_faces[7], prism_faces[9]]) - -# add objects in the study -id_shell = geompy.addToStudy(shell,"Shell") - -# display the shell -gg.createAndDisplayGO(id_shell) -gg.setDisplayMode(id_shell,1) -\endcode - \anchor tui_creation_solid

    Creation of a Solid

    +\include topological_geom_objs_ex05.py +Download this script -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -#create vertices -p0 = geompy.MakeVertex( 0., 0., 0.) -pz = geompy.MakeVertex( 0., 0., 40.) - -# create sketchers -sketcher = geompy.MakeSketcher("Sketcher:F -50 -50:TT 100 -50:R 0:C 50 70:R 0:L 100:WW") - -# create faces from two wires -face = geompy.MakeFace(sketcher,1) - -# create a prism -prism = geompy.MakePrism(face, p0, pz) - -# explode the prism into faces -prism_faces = geompy.SubShapeAllSortedCentres(prism, geompy.ShapeType["FACE"]) - -# create a shell from a set of faces -shell = geompy.MakeShell([prism_faces[0], prism_faces[1], - prism_faces[3], prism_faces[4], - prism_faces[5], prism_faces[2]]) - -# create a solid, bounded by the given shells -solid = geompy.MakeSolid([shell]) - -# add objects in the study -id_solid = geompy.addToStudy(solid,"Solid") - -# display the solid -gg.createAndDisplayGO(id_solid) -gg.setDisplayMode(id_solid,1) -\endcode - \anchor tui_creation_compound

    Creation of a Compound

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex( -30., -30., 50.) -p2 = geompy.MakeVertex( -60., -60., 30.) -p3 = geompy.MakeVertex( -30., -30., 10.) - -# create an arc from three points -arc = geompy.MakeArc(p1, p2, p3) -ShapeListCompound = [] -i = 0 -while i <= 3 : - S = geompy.MakeTranslation(arc, i * 50., 0., 0.) - ShapeListCompound.append(S) - i = i + 1 - -# create a compund of the given shapes -compound = geompy.MakeCompound(ShapeListCompound) - -# add object in the study -id_compound = geompy.addToStudy(compound,"Compound") - -# display the compound -gg.createAndDisplayGO(id_compound) -\endcode +\include topological_geom_objs_ex06.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_transformation_operations.doc b/doc/salome/gui/GEOM/input/tui_transformation_operations.doc index 09744cddf..10e392ec0 100644 --- a/doc/salome/gui/GEOM/input/tui_transformation_operations.doc +++ b/doc/salome/gui/GEOM/input/tui_transformation_operations.doc @@ -4,552 +4,67 @@ \anchor tui_translation

    Translation

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex(10, 40, 0) -p2 = geompy.MakeVertex( 0, 0, 50) -p3 = geompy.MakeVertex(50, 80, 0) -v = geompy.MakeVector(p1, p2) -vt = geompy.MakeVector(p1, p3) - -# create a cylinder -height = 35 -radius1 = 20 -cylinder = geompy.MakeCylinder(p1, v, radius1, height) - -# translate the given object along the vector, specified by its end points -# (all three functions produce the same result) -translation1 = geompy.MakeTranslationTwoPoints(cylinder, p1, p3) -translation2 = geompy.MakeTranslation(cylinder, 40, 40, 0) -translation3 = geompy.MakeTranslationVector(cylinder, vt) -translation4 = geompy.MakeTranslationVectorDistance(cylinder, vt, 200) - -# add objects in the study -id_cylinder = geompy.addToStudy(cylinder, "Cylinder") -id_translation1 = geompy.addToStudy(translation1, "Translation1") -id_translation2 = geompy.addToStudy(translation2, "Translation2") -id_translation3 = geompy.addToStudy(translation3, "Translation3") -id_translation4 = geompy.addToStudy(translation4, "Translation4") - -# display the results -gg.createAndDisplayGO(id_cylinder) -gg.setDisplayMode(id_cylinder,1) -gg.createAndDisplayGO(id_translation1) -gg.setDisplayMode(id_translation1,1) -gg.createAndDisplayGO(id_translation2) -gg.setDisplayMode(id_translation2,1) -gg.createAndDisplayGO(id_translation3) -gg.setDisplayMode(id_translation3,1) -gg.createAndDisplayGO(id_translation4) -gg.setDisplayMode(id_translation4,1) -\endcode +\include transformation_operations_ex01.py +Download this script \anchor tui_rotation

    Rotation

    - -\code -import geompy -import salome -import math -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex(10, 40, 0) -p2 = geompy.MakeVertex( 0, 0, 50) -p3 = geompy.MakeVertex(10, 50,-20) -p4 = geompy.MakeVertex(10, 50, 60) -v = geompy.MakeVector(p1, p2) -vr = geompy.MakeVector(p3, p4) - -# create a cylinder -height = 35 -radius1 = 20 -cylinder = geompy.MakeCylinder(p1, v, radius1, height) - -# rotate the given object around the given axis by the given angle -rotation1 = geompy.MakeRotation(cylinder, vr, math.pi) -rotation2 = geompy.MakeRotationThreePoints(cylinder, p4, p1, p2) - -# add objects in the study -id_vr = geompy.addToStudy(vr, "Rotation 1 axis") -id_p4 = geompy.addToStudy(p4, "Rotation 2 center") -id_p1 = geompy.addToStudy(p1, "Rotation 2 point 1") -id_p2 = geompy.addToStudy(p2, "Rotation 2 point 2") -id_cylinder = geompy.addToStudy(cylinder, "Cylinder") -id_rotation1 = geompy.addToStudy(rotation1, "Rotation 1") -id_rotation2 = geompy.addToStudy(rotation2, "Rotation 2") - -# display the results -gg.createAndDisplayGO(id_vr) -gg.createAndDisplayGO(id_p4) -gg.createAndDisplayGO(id_p1) -gg.createAndDisplayGO(id_p2) -gg.createAndDisplayGO(id_cylinder) -gg.setDisplayMode(id_cylinder,1) -gg.createAndDisplayGO(id_rotation1) -gg.createAndDisplayGO(id_rotation2) -gg.setDisplayMode(id_rotation1,1) -gg.setDisplayMode(id_rotation2,1) -\endcode +\include transformation_operations_ex02.py +Download this script \anchor tui_modify_location

    Modify Location

    - -\code -import geompy -import salome -import math -gg = salome.ImportComponentGUI("GEOM") - -# create a vertex and a vector -p1 = geompy.MakeVertex(10, 40, 0) -p2 = geompy.MakeVertex( 0, 0, 50) -v = geompy.MakeVector(p1, p2) - -# create a cylinder -height = 35 -radius1 = 20 -cylinder = geompy.MakeCylinder(p1, v, radius1, height) -circle = geompy.MakeCircle(p2, v, radius1) - -# create local coordinate systems -cs1 = geompy.MakeMarker( 0, 0, 0, 1,0,0, 0,1,0) -cs2 = geompy.MakeMarker(30,40,40, 1,0,0, 0,1,0) - -# modify the location of the given object -position = geompy.MakePosition(cylinder, cs1, cs2) -position2 = geompy.PositionAlongPath(position, circle, 0.75, 1, 1) - -# add objects in the study -id_cs1 = geompy.addToStudy(cs1, "Coordinate system 1") -id_cs2 = geompy.addToStudy(cs2, "Coordinate system 2") -id_cylinder = geompy.addToStudy(cylinder, "Cylinder") -id_circle = geompy.addToStudy(circle, "Circle") -id_position = geompy.addToStudy(position, "Position") -id_position2 = geompy.addToStudy(position2, "PositionAlongPath") - -# display the results -gg.createAndDisplayGO(id_cylinder) -gg.setDisplayMode(id_cylinder,1) -gg.createAndDisplayGO(id_position) -gg.setDisplayMode(id_position,1) -gg.createAndDisplayGO(id_circle) -gg.setDisplayMode(id_circle,1) -gg.createAndDisplayGO(id_position2) -gg.setDisplayMode(id_position2,1) -\endcode +\include transformation_operations_ex03.py +Download this script \anchor tui_mirror

    Mirror Image

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a box -box = geompy.MakeBoxDXDYDZ(200, 200, 200) - -# create an object, symmetrical to another object through the given plane -p1 = geompy.MakeVertex( 0, 25, 0) -p2 = geompy.MakeVertex( 5, 25, 0) -p3 = geompy.MakeVertex( 0,-30, 40) -plane = geompy.MakePlaneThreePnt(p1, p2, p3, 1000.) -mirror1 = geompy.MakeMirrorByPlane(box, plane) - -# create an object, symmetrical to another object through the given axis -p4 = geompy.MakeVertex( 210, 210, -20) -p5 = geompy.MakeVertex( 210, 210, 220) -axis = geompy.MakeVector(p4, p5) -mirror2 = geompy.MakeMirrorByAxis(box, axis) - -# create an object, symmetrical to another object through the given point -mirror3 = geompy.MakeMirrorByPoint(box, p4) - -# add objects in the study -id_box = geompy.addToStudy(box, "Box") -id_plane = geompy.addToStudy(plane, "Plane") -id_mirror1 = geompy.addToStudy(mirror1, "Mirror plane") -id_axis = geompy.addToStudy(axis, "Axis") -id_mirror2 = geompy.addToStudy(mirror2, "Mirror axis") -id_p4 = geompy.addToStudy(p4, "Point") -id_mirror3 = geompy.addToStudy(mirror3, "Mirror point") - -# display the results -gg.createAndDisplayGO(id_box) -gg.setDisplayMode(id_box,1) -gg.createAndDisplayGO(id_plane) -gg.createAndDisplayGO(id_mirror1) -gg.setDisplayMode(id_mirror1,1) -gg.createAndDisplayGO(id_axis) -gg.createAndDisplayGO(id_mirror2) -gg.setDisplayMode(id_mirror2,1) -gg.createAndDisplayGO(id_p4) -gg.createAndDisplayGO(id_mirror3) -gg.setDisplayMode(id_mirror3,1) -\endcode +\include transformation_operations_ex04.py +Download this script \anchor tui_scale

    Scale Transform

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a box and a sphere -box = geompy.MakeBoxDXDYDZ(200, 200, 200) - -# scale the given object by the factor -p0 = geompy.MakeVertex(100, 100, 100) -factor = 0.5 -scale = geompy.MakeScaleTransform(box, p0, factor) - -# add objects in the study -id_box = geompy.addToStudy(box, "Box") -id_scale = geompy.addToStudy(scale, "Scale") - -# display the results -gg.createAndDisplayGO(id_box) -gg.setDisplayMode(id_box,1) -gg.setTransparency(id_box,0.5) -gg.createAndDisplayGO(id_scale) -gg.setDisplayMode(id_scale,1) -\endcode +\include transformation_operations_ex05.py +Download this script \anchor tui_offset

    Offset Surface

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a box and a sphere -box = geompy.MakeBox(20, 20, 20, 200, 200, 200) - -# create a new object as offset of the given object -offset = geompy.MakeOffset(box, 70.) - -# add objects in the study -id_box = geompy.addToStudy(box, "Box") -id_offset = geompy.addToStudy(offset, "Offset") - -# display the results -gg.createAndDisplayGO(id_box) -gg.setDisplayMode(id_box,1) -gg.createAndDisplayGO(id_offset) -\endcode +\include transformation_operations_ex06.py +Download this script \anchor tui_projection

    Projection

    - -\code -import geompy -import salome - -# create a cylindric face and a curve(edge) -cylinder = geompy.MakeCylinderRH(100, 300) -[face_cyl] = geompy.SubShapes(cylinder, [3]) - -p1 = geompy.MakeVertex(200, 0, 100) -p2 = geompy.MakeVertex(200, 80, 100) -p3 = geompy.MakeVertex(200, 80, 180) -p4 = geompy.MakeVertex(130, 80, 180) -p5 = geompy.MakeVertex(90, 80, 240) - -curve = geompy.MakeInterpol([p1, p2, p3, p4, p5], False, False) - -# create a new object as projection of the -# given curve on the given cylindric face -projection = geompy.MakeProjection(curve, face_cyl) - -# add objects in the study -geompy.addToStudy(cylinder, "cylinder") -geompy.addToStudyInFather(cylinder, face_cyl, "face_cyl") -geompy.addToStudy(p1, "p1") -geompy.addToStudy(p2, "p2") -geompy.addToStudy(p3, "p3") -geompy.addToStudy(p4, "p4") -geompy.addToStudy(p5, "p5") -geompy.addToStudy(curve, "curve") -geompy.addToStudy(projection, "projection") -\endcode +\include transformation_operations_ex07.py +Download this script \anchor tui_multi_translation

    Multi Translation

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices and vectors -p0 = geompy.MakeVertex( 0., 0., 0.) -px = geompy.MakeVertex(20., 0., 0.) -py = geompy.MakeVertex( 0., 20., 0.) -pz = geompy.MakeVertex( 0., 0., 20.) -pxy = geompy.MakeVertex( 50., 0., 0.) -pxyz = geompy.MakeVertex( 50., 50., 50.) -vz = geompy.MakeVector(p0, pz) -vxy = geompy.MakeVector(px, py) -vtr1d = geompy.MakeVector(p0, pxyz) -vtr2d = geompy.MakeVector(p0, pxy) - -# create an arc -arc = geompy.MakeArc(py, pz, px) - -# create a wire -wire = geompy.MakeWire([vxy, arc]) - -# create a planar face -face = geompy.MakeFace(wire, 1) - -# create a prism -prism = geompy.MakePrismVecH(face, vz, 20.0) - -# translate the given object along the given vector a given number of times -tr1d = geompy.MakeMultiTranslation1D(prism, vtr1d, 20, 4) - -# consequently apply two specified translations to the object a given number of times -tr2d = geompy.MakeMultiTranslation2D(prism, vtr1d, 20, 4, vtr2d, 80, 3) - -# add objects in the study -id_prism = geompy.addToStudy(prism,"Prism") -id_tr1d = geompy.addToStudy(tr1d,"Translation 1D") -id_tr2d = geompy.addToStudy(tr2d,"Translation 2D") - -# display the prism and the results of fillet operation -gg.createAndDisplayGO(id_prism) -gg.setDisplayMode(id_prism,1) -gg.createAndDisplayGO(id_tr1d) -gg.setDisplayMode(id_tr1d,1) -gg.createAndDisplayGO(id_tr2d) -gg.setDisplayMode(id_tr2d,1) -\endcode +\include transformation_operations_ex08.py +Download this script \anchor tui_multi_rotation

    Multi Rotation

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create vertices and vectors -p0 = geompy.MakeVertex( 0., 0., 0.) -px = geompy.MakeVertex(20., 0., 0.) -py = geompy.MakeVertex( 0., 20., 0.) -pz = geompy.MakeVertex( 0., 0., 20.) -pxyz = geompy.MakeVertex( 50., 50., 10.) -vz = geompy.MakeVector(p0, pz) -vxy = geompy.MakeVector(px, py) -vrot1d = geompy.MakeVector(p0, pxyz) - -# create an arc -arc = geompy.MakeArc(py, pz, px) - -# create a wire -wire = geompy.MakeWire([vxy, arc]) - -# create a planar face -face = geompy.MakeFace(wire, 1) - -# create a prism -prism = geompy.MakePrismVecH(face, vz, 20.0) - -# rotate the given object around the given axis by the given angle a given number of times -rot1d = geompy.MultiRotate1D(prism, vrot1d, 4) - -# rotate the given object around the given axis by the given angle a given number of times -# and multi-translate the result of each rotation -rot2d = geompy.MultiRotate2D(prism, vrot1d, 60, 4, 50, 5) - -# add objects in the study -id_prism = geompy.addToStudy(prism,"Prism") -id_rot1d = geompy.addToStudy(rot1d,"Rotation 1D") -id_rot2d = geompy.addToStudy(rot2d,"Rotation 2D") - -# display the prism and the results of fillet operation -gg.createAndDisplayGO(id_prism) -gg.setDisplayMode(id_prism,1) -gg.createAndDisplayGO(id_rot1d) -gg.setDisplayMode(id_rot1d,1) -gg.createAndDisplayGO(id_rot2d) -gg.setDisplayMode(id_rot2d,1) -\endcode +\include transformation_operations_ex09.py +Download this script \anchor tui_fillet2d

    Fillet 2D

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create a face in OXY plane -face = geompy.MakeFaceHW(100, 100, 1) -fillet2d = geompy.MakeFillet2D(face, 30, [7, 9]) - -# add objects in the study -id_face = geompy.addToStudy(face,"Face_1") -id_fillet2d = geompy.addToStudy(fillet2d,"Fillet 2D_1") - -# display disks -gg.createAndDisplayGO(id_face) -gg.createAndDisplayGO(id_fillet2d) -\endcode +\include transformation_operations_ex10.py +Download this script \anchor tui_fillet1d

    Fillet 1D

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create box -Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) -# take box edges to create custom complex wire -[Edge_1,Edge_2,Edge_3,Edge_4,Edge_5,Edge_6,Edge_7,Edge_8,Edge_9,Edge_10,Edge_11,Edge_12] = geompy.SubShapeAllSortedCentres(Box_1, geompy.ShapeType["EDGE"]) -# create wire -Wire_1 = geompy.MakeWire([Edge_12, Edge_7, Edge_11, Edge_6, Edge_1,Edge_4]) -# make fillet at given wire vertices with giver radius -Fillet_1D_1 = geompy.MakeFillet1D(Wire_1, 55, [3, 4, 6, 8, 10]) - - -# display disks -gg.createAndDisplayGO(Wire_1) -gg.createAndDisplayGO(Fillet_1D_1) -\endcode +\include transformation_operations_ex11.py +Download this script \anchor tui_fillet

    Fillet

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") -radius = 10. -ShapeTypeEdge = geompy.ShapeType["EDGE"] - -# create vertices and vectors -p0 = geompy.MakeVertex( 0., 0., 0.) -px = geompy.MakeVertex(100., 0., 0.) -py = geompy.MakeVertex( 0., 100., 0.) -pz = geompy.MakeVertex( 0., 0., 100.) -vz = geompy.MakeVector(p0, pz) -vxy = geompy.MakeVector(px, py) - -# create an arc -arc = geompy.MakeArc(py, pz, px) - -# create a wire -wire = geompy.MakeWire([vxy, arc]) - -# create a planar face -face = geompy.MakeFace(wire, 1) - -# create a prism -prism = geompy.MakePrismVecH(face, vz, 100.0) - -# get the list of IDs (IDList) for the fillet -prism_edges = geompy.SubShapeAllSortedCentres(prism, ShapeTypeEdge) -IDlist_e = [] -IDlist_e.append(geompy.GetSubShapeID(prism, prism_edges[0])) -IDlist_e.append(geompy.GetSubShapeID(prism, prism_edges[1])) -IDlist_e.append(geompy.GetSubShapeID(prism, prism_edges[2])) - -# make a fillet on the specified edges of the given shape -fillet = geompy.MakeFillet(prism, radius, ShapeTypeEdge, IDlist_e) - -# make a fillet on all edges of the given shape -filletall = geompy.MakeFilletAll(prism, radius) - -# add objects in the study -id_prism = geompy.addToStudy(prism,"Prism") -id_fillet = geompy.addToStudy(fillet,"Fillet") -id_filletall = geompy.addToStudy(filletall,"Fillet all") - -# display the prism and the results of fillet operation -gg.createAndDisplayGO(id_prism) -gg.setDisplayMode(id_prism,1) -gg.createAndDisplayGO(id_fillet) -gg.setDisplayMode(id_fillet,1) -gg.createAndDisplayGO(id_filletall) -gg.setDisplayMode(id_filletall,1) -\endcode +\include transformation_operations_ex12.py +Download this script \anchor tui_chamfer

    Chamfer

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") -d1 = 10. -d2 = 10. -ShapeTypeFace = geompy.ShapeType["FACE"] - -# create vertices and vectors -p0 = geompy.MakeVertex( 0., 0., 0.) -px = geompy.MakeVertex(100., 0., 0.) -py = geompy.MakeVertex( 0., 100., 0.) -pz = geompy.MakeVertex( 0., 0., 100.) -vz = geompy.MakeVector(p0, pz) -vxy = geompy.MakeVector(px, py) - -# create an arc -arc = geompy.MakeArc(py, pz, px) - -# create a wire -wire = geompy.MakeWire([vxy, arc]) - -# create a planar face -face = geompy.MakeFace(wire, 1) - -# create a prism -prism = geompy.MakePrismVecH(face, vz, 100.0) - -# get the list of IDs (IDList) for the chamfer -prism_faces = geompy.SubShapeAllSortedCentres(prism, ShapeTypeFace) -f_ind_1 = geompy.GetSubShapeID(prism, prism_faces[0]) -f_ind_2 = geompy.GetSubShapeID(prism, prism_faces[1]) -IDlist_f = [f_ind_1, f_ind_2] - -# perform a chamfer on the edges common to the specified faces -chamfer_e = geompy.MakeChamferEdge(prism, d1, d2, f_ind_1, f_ind_2) - -# perform a chamfer on all edges of the specified faces -chamfer_f = geompy.MakeChamferFaces(prism, d1, d2, IDlist_f) -chamfer_f1 = geompy.MakeChamfer(prism, d1, d2, ShapeTypeFace, IDlist_f) - -# perform a symmetric chamfer on all edges of the given shape -chamfer_all = geompy.MakeChamferAll(prism, d1) - -# add objects in the study -id_prism = geompy.addToStudy(prism,"Prism") -id_chamfer_e = geompy.addToStudy(chamfer_e,"Chamfer edge") -id_chamfer_f = geompy.addToStudy(chamfer_f,"Chamfer faces") -id_chamfer_f1 = geompy.addToStudy(chamfer_f1,"Chamfer faces 1") -id_chamfer_all = geompy.addToStudy(chamfer_all,"Chamfer all") - -# display the prism and the results of chamfer operation -gg.createAndDisplayGO(id_prism) -gg.setDisplayMode(id_prism,1) -gg.createAndDisplayGO(id_chamfer_e) -gg.setDisplayMode(id_chamfer_e,1) -gg.createAndDisplayGO(id_chamfer_f) -gg.setDisplayMode(id_chamfer_f,1) -gg.createAndDisplayGO(id_chamfer_f1) -gg.setDisplayMode(id_chamfer_f1,1) -gg.createAndDisplayGO(id_chamfer_all) -gg.setDisplayMode(id_chamfer_all,1) -\endcode +\include transformation_operations_ex13.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_viewing_geom_objs.doc b/doc/salome/gui/GEOM/input/tui_viewing_geom_objs.doc index 2573c0fa5..8505548d3 100644 --- a/doc/salome/gui/GEOM/input/tui_viewing_geom_objs.doc +++ b/doc/salome/gui/GEOM/input/tui_viewing_geom_objs.doc @@ -4,78 +4,22 @@ \anchor tui_change_disp_mode

    Changing Display Mode

    - -\code -import salome -import geompy -box = geompy.MakeBox(0,0,0, 50,50,50) -box2 = geompy.MakeBox(-50,-50,-50, 0,0,0) - -sphere = geompy.MakeSphere(50,50,50, 30) -fuse = geompy.MakeBoolean(box,sphere,3) -fuse_id = geompy.addToStudy(fuse,"Fuse") -box_id = geompy.addToStudy(box2, "Box") - -gg = salome.ImportComponentGUI("GEOM") -gg.createAndDisplayGO(fuse_id) -gg.setDisplayMode(fuse_id,1) -gg.createAndDisplayGO(box_id) -gg.setVectorsMode(box_id, 1) -\endcode +\include viewing_geom_objs_ex01.py +Download this script \anchor tui_change_color

    Changing Color

    - -\code -import salome -import geompy -box = geompy.MakeBox(0,0,0, 50,50,50) - -sphere = geompy.MakeSphere(50,50,50, 30) -fuse = geompy.MakeBoolean(box,sphere,3) -fuse_id = geompy.addToStudy(fuse,"Fuse") - -gg = salome.ImportComponentGUI("GEOM") -gg.createAndDisplayGO(fuse_id) -gg.setDisplayMode(fuse_id,1) -gg.setColor(fuse_id,218,165,31) -\endcode +\include viewing_geom_objs_ex02.py +Download this script \anchor tui_change_transparency

    Changing Transparency

    - -\code -import salome -import geompy - -box = geompy.MakeBox(0,0,0, 50,50,50) -sphere = geompy.MakeSphere(50,50,50, 30) - -fuse = geompy.MakeBoolean(box,sphere,3) -fuse_id = geompy.addToStudy(fuse,"Fuse") - -gg = salome.ImportComponentGUI("GEOM") -gg.createAndDisplayGO(fuse_id) -gg.setDisplayMode(fuse_id,1) -gg.setColor(fuse_id,218,165,31) -gg.setTransparency(fuse_id,0.5) -\endcode +\include viewing_geom_objs_ex03.py +Download this script \anchor tui_point_marker

    Set Point Marker

    +\include viewing_geom_objs_ex04.py +Download this script -\code -import salome -import geompy - -texture = geompy.LoadTexture("/users/user/mytexture.dat") - -v1 = geompy.MakeVertex(0, 0, 0) -v2 = geompy.MakeVertex(100, 0, 0) -v3 = geompy.MakeVertex(0, 100, 0) - -v1.SetMarkerStd(GEOM.MT_O_PLUS, GEOM.MS_25) -v2.SetMarkerStd(GEOM.MT_BALL, GEOM.MS_40) -v3.SetMarkerTexture(texture) -\endcode */ diff --git a/doc/salome/gui/GEOM/input/tui_whatis.doc b/doc/salome/gui/GEOM/input/tui_whatis.doc index e89e8bf18..d1c8fc911 100644 --- a/doc/salome/gui/GEOM/input/tui_whatis.doc +++ b/doc/salome/gui/GEOM/input/tui_whatis.doc @@ -1,15 +1,7 @@ /*! \page tui_whatis_page What Is - -\code -import geompy - -# create a box -box = geompy.MakeBoxDXDYDZ(100,30,100) -Descr = geompy.WhatIs(box) -print "\nBox 100x30x100 description:" -print Descr -\endcode +\include whatis.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/tui_working_with_groups.doc b/doc/salome/gui/GEOM/input/tui_working_with_groups.doc index 37813417c..4f252c2e9 100644 --- a/doc/salome/gui/GEOM/input/tui_working_with_groups.doc +++ b/doc/salome/gui/GEOM/input/tui_working_with_groups.doc @@ -5,214 +5,35 @@
    \anchor tui_create_groups_anchor

    Creation of a group

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create two vertices -p0 = geompy.MakeVertex(0. , 0. , 0. ) -p200 = geompy.MakeVertex(200., 200., 200.) - -# create a box from two points -Box = geompy.MakeBoxTwoPnt(p0, p200) - -# create a group from the faces of the box -group = geompy.CreateGroup(Box, geompy.ShapeType["FACE"]) - -# add objects to the group -SubFaceList = geompy.SubShapeAllSortedCentres(Box, geompy.ShapeType["FACE"]) -for i in [0, 3, 5] : - FaceID = geompy.GetSubShapeID(Box, SubFaceList[i]) - geompy.AddObject(group, FaceID) - -# add all selected shapes from the list to the group -# (the program doesn't raise error, if some shapes are already included) -geompy.UnionList(group, [SubFaceList[0], SubFaceList[2], SubFaceList[5]]) - -# remove an object from the group -geompy.RemoveObject(group, FaceID) - -# remove all selected shapes from the group -# (the program doesn't raise error, if some shapes are not included) -geompy.DifferenceList(group, [SubFaceList[2], SubFaceList[3], SubFaceList[4]]) -id_group1 = geompy.addToStudy(group, "Group1") - -# display the contents of the group -gg.createAndDisplayGO(id_group1) -salome.sg.updateObjBrowser(1) -\endcode +\include working_with_groups_ex01.py +Download this script \anchor tui_edit_groups_anchor

    Adding an object to the group

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create two vertices -p0 = geompy.MakeVertex(0. , 0. , 0. ) -p200 = geompy.MakeVertex(200., 200., 200.) - -# create a box from two points -Box = geompy.MakeBoxTwoPnt(p0, p200) - -# create a group from the faces of the box -group = geompy.CreateGroup(Box, geompy.ShapeType["FACE"]) - -# add objects to the group -SubFaceList = geompy.SubShapeAllSortedCentres(Box, geompy.ShapeType["FACE"]) -for i in [0, 3, 5] : - FaceID = geompy.GetSubShapeID(Box, SubFaceList[i]) - geompy.AddObject(group, FaceID) -id_group1 = geompy.addToStudy(group, "Group1") - -# display the contents of the group -gg.createAndDisplayGO(id_group1) -salome.sg.updateObjBrowser(1) -\endcode +\include working_with_groups_ex02.py +Download this script

    Removing an object from the group

    - -\code -import geompy -import salome -gg = salome.ImportComponentGUI("GEOM") - -# create two vertices -p0 = geompy.MakeVertex(0. , 0. , 0. ) -p200 = geompy.MakeVertex(200., 200., 200.) - -# create a box from two points -Box = geompy.MakeBoxTwoPnt(p0, p200) - -# create a group from the faces of the box -group = geompy.CreateGroup(Box, geompy.ShapeType["FACE"]) - -# add objects to the group -SubFaceList = geompy.SubShapeAllSortedCentres(Box, geompy.ShapeType["FACE"]) -for i in [0, 3, 5] : - FaceID = geompy.GetSubShapeID(Box, SubFaceList[i]) - geompy.AddObject(group, FaceID) - -# add all selected shapes from the list to the group -# (the program doesn't raise errors, if some shapes are already included) -geompy.UnionList(group, [SubFaceList[0], SubFaceList[2], SubFaceList[5]]) - -# remove an object from the group -geompy.RemoveObject(group, FaceID) -id_group1 = geompy.addToStudy(group, "Group1") - -# display the contents of the group -gg.createAndDisplayGO(id_group1) -salome.sg.updateObjBrowser(1) -\endcode +\include working_with_groups_ex03.py +Download this script
    \anchor tui_union_groups_anchor

    Union Groups

    - -\code -import geompy -import salome - -# create a box and some groups of faces on it -Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) -Group_1 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) -geompy.UnionIDs(Group_1, [13, 23]) -Group_2 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) -geompy.UnionIDs(Group_2, [3, 27]) -Group_3 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) -geompy.UnionIDs(Group_3, [33, 23]) -Group_4 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) -geompy.UnionIDs(Group_4, [31, 27]) - -# union groups -Group_U_1_2 = geompy.UnionGroups(Group_1, Group_2) -Group_UL_3_4 = geompy.UnionListOfGroups([Group_3, Group_4]) - -# publish shapes -geompy.addToStudy(Box_1, 'Box_1') -geompy.addToStudyInFather(Box_1, Group_1, 'Group_1') -geompy.addToStudyInFather(Box_1, Group_2, 'Group_2') -geompy.addToStudyInFather(Box_1, Group_3, 'Group_3') -geompy.addToStudyInFather(Box_1, Group_4, 'Group_4') -geompy.addToStudyInFather(Box_1, Group_U_1_2, 'Group_U_1_2') -geompy.addToStudyInFather(Box_1, Group_UL_3_4, 'Group_UL_3_4') -salome.sg.updateObjBrowser(1) -\endcode +\include working_with_groups_ex04.py +Download this script
    \anchor tui_intersect_groups_anchor

    Intersect Groups

    - -\code -import geompy -import salome - -# create a box and some groups of faces on it -Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) -Group_1 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) -geompy.UnionIDs(Group_1, [13, 23]) -Group_2 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) -geompy.UnionIDs(Group_2, [3, 27]) -Group_3 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) -geompy.UnionIDs(Group_3, [33, 23]) -Group_4 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) -geompy.UnionIDs(Group_4, [31, 27]) - -# intersect groups -Group_I_1_3 = geompy.IntersectGroups(Group_1, Group_3) -Group_IL_1_3 = geompy.IntersectListOfGroups([Group_1, Group_3]) - -# publish shapes -geompy.addToStudy(Box_1, 'Box_1') -geompy.addToStudyInFather(Box_1, Group_1, 'Group_1') -geompy.addToStudyInFather(Box_1, Group_2, 'Group_2') -geompy.addToStudyInFather(Box_1, Group_3, 'Group_3') -geompy.addToStudyInFather(Box_1, Group_4, 'Group_4') -geompy.addToStudyInFather(Box_1, Group_I_1_3, 'Group_I_1_3') -geompy.addToStudyInFather(Box_1, Group_IL_1_3, 'Group_IL_1_3') -salome.sg.updateObjBrowser(1) - -\endcode +\include working_with_groups_ex05.py +Download this script
    \anchor tui_cut_groups_anchor

    Cut Groups

    - -\code -import geompy -import salome - -# create a box and some groups of faces on it -Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) -Group_1 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) -geompy.UnionIDs(Group_1, [13, 23]) -Group_2 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) -geompy.UnionIDs(Group_2, [3, 27]) -Group_3 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) -geompy.UnionIDs(Group_3, [33, 23]) -Group_4 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"]) -geompy.UnionIDs(Group_4, [31, 27]) - -# cut groups -Group_C_2_4 = geompy.CutGroups(Group_2, Group_4) -Group_CL_2_4 = geompy.CutListOfGroups([Group_2], [Group_4]) - -# publish shapes -geompy.addToStudy(Box_1, 'Box_1') -geompy.addToStudyInFather(Box_1, Group_1, 'Group_1') -geompy.addToStudyInFather(Box_1, Group_2, 'Group_2') -geompy.addToStudyInFather(Box_1, Group_3, 'Group_3') -geompy.addToStudyInFather(Box_1, Group_4, 'Group_4') -geompy.addToStudyInFather(Box_1, Group_C_2_4, 'Group_C_2_4') -geompy.addToStudyInFather(Box_1, Group_CL_2_4, 'Group_CL_2_4') -salome.sg.updateObjBrowser(1) - -\endcode +\include working_with_groups_ex06.py +Download this script */ diff --git a/doc/salome/gui/GEOM/input/working_with_groups.doc b/doc/salome/gui/GEOM/input/working_with_groups.doc index 99b98bac9..6b9d85c1c 100644 --- a/doc/salome/gui/GEOM/input/working_with_groups.doc +++ b/doc/salome/gui/GEOM/input/working_with_groups.doc @@ -103,10 +103,19 @@ To \b Edit an existing group in the main menu select New entity > Group > Edit. This menu is designed in the same way as the Create a group menu. -\n Dialog Box: +\n When a GEOM group is edited, the main shape appears in the 3D viewer in the same mode +as it is displayed in the viewer. If the main shape was not displayed in the viewer, then +the default mode defined in the preferences will be used. + +\n Working with Dialog Box: \image html editgroup.png +\n The subshapes already in the group are displayed in the 3D viewer with a specific color, +defined via preferences. The IDs of the subshapes already in the group also are displayed in +a specific color in the dialog box. When user adds some subshapes, the new IDs are +displayed in the other color. + \n The \b Result of the operation will be a \b GEOM_Object. \n TUI Command: diff --git a/doc/salome/gui/Makefile.am b/doc/salome/gui/Makefile.am index 03e3efc6e..fff0e9b64 100644 --- a/doc/salome/gui/Makefile.am +++ b/doc/salome/gui/Makefile.am @@ -20,8 +20,7 @@ # -* Makefile *- # Author : Patrick GOLDBRONN (CEA) # Date : 30/11/2001 -# Modified by : Alexander BORODIN (OCN) - autotools usage -# $Header: +# Modified by : Alexander BORODIN (OCN) - autotools usage # SUBDIRS = GEOM diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index f35c7935e..b7bcf45e2 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -804,7 +804,7 @@ module GEOM /*! * \brief Translate the given object along the given vector a given number times * \param theObject The object to be translated. - * \param theVector Direction of the translation. + * \param theVector Direction of the translation. DX if None. * \param theStep Distance to translate on. * \param theNbTimes Quantity of translations to be done. * \return New GEOM_Object, containing compound of all @@ -818,10 +818,10 @@ module GEOM /*! * \brief Conseqently apply two specified translations to theObject specified number of times. * \param theObject The object to be translated. - * \param theVector1 Direction of the first translation. + * \param theVector1 Direction of the first translation. DX if None. * \param theStep1 Step of the first translation. * \param theNbTimes1 Quantity of translations to be done along theVector1. - * \param theVector2 Direction of the second translation. + * \param theVector2 Direction of the second translation. DY if None. * \param theStep2 Step of the second translation. * \param theNbTimes2 Quantity of translations to be done along theVector2. * \return New GEOM_Object, containing compound of all @@ -888,20 +888,56 @@ module GEOM in GEOM_Object theAxis, in double theAngle); - /*! * \brief Rotate the given object around the given axis a given number times. * - * Rotation angle will be 2*PI/theNbTimes. + * Rotation angle will be 2*PI/theNbObjects. * \param theObject The object to be rotated. - * \param theAxis The rotation axis. - * \param theNbTimes Quantity of rotations to be done. + * \param theAxis The rotation axis. DZ if None. + * \param theNbObjects Quantity of rotations to be done. * \return New GEOM_Object, containing compound of all the * shapes, obtained after each rotation. */ GEOM_Object MultiRotate1D (in GEOM_Object theObject, in GEOM_Object theAxis, - in long theNbTimes); + in long theNbObjects); + + /*! + * \brief Rotate the given object around the given axis + * a given number times on the given angle. + * + * \param theObject The object to be rotated. + * \param theAxis The rotation axis. DZ if None. + * \param theAngleStep Rotation angle in radians. + * \param theNbSteps Quantity of rotations to be done. + * \return New GEOM_Object, containing compound of all the + * shapes, obtained after each rotation. + */ + GEOM_Object MultiRotate1DByStep (in GEOM_Object theObject, + in GEOM_Object theAxis, + in double theAngleStep, + in long theNbSteps); + + /*! + * \brief Rotate the given object around the given axis + * a given number times and multi-translate each rotation result. + * + * Rotation angle will be 2*PI/theNbObjects. + * Translation direction passes through center of gravity + * of rotated shape and its projection on the rotation axis. + * \param theObject The object to be rotated. + * \param theAxis Rotation axis. DZ if None. + * \param theNbObjects Quantity of rotations to be done. + * \param theRadialStep Translation distance. + * \param theNbSteps Quantity of translations to be done. + * \return New GEOM_Object, containing compound of all the + * shapes, obtained after each transformation. + */ + GEOM_Object MultiRotate2DNbTimes (in GEOM_Object theObject, + in GEOM_Object theAxis, + in long theNbObjects, + in double theRadialStep, + in long theNbSteps); /*! * \brief Rotate the given object around the @@ -911,20 +947,43 @@ module GEOM * Translation direction passes through center of gravity * of rotated shape and its projection on the rotation axis. * \param theObject The object to be rotated. - * \param theAxis Rotation axis. - * \param theAngle Rotation angle in graduces. - * \param theNbTimes1 Quantity of rotations to be done. - * \param theStep Translation distance. - * \param theNbTimes2 Quantity of translations to be done. + * \param theAxis Rotation axis. DZ if None. + * \param theAngleStep Rotation angle in radians. + * \param theNbSteps1 Quantity of rotations to be done. + * \param theRadialStep Translation distance. + * \param theNbSteps2 Quantity of translations to be done. + * \return New GEOM_Object, containing compound of all the + * shapes, obtained after each transformation. + */ + GEOM_Object MultiRotate2DByStep (in GEOM_Object theObject, + in GEOM_Object theAxis, + in double theAngleStep, + in long theNbSteps1, + in double theRadialStep, + in long theNbSteps2); + + /*! + * \brief Rotate the given object around the + * given axis on the given angle a given number + * times and multi-translate each rotation result. + * + * Translation direction passes through center of gravity + * of rotated shape and its projection on the rotation axis. + * \param theObject The object to be rotated. + * \param theAxis Rotation axis. DZ if None. + * \param theAngleStep Rotation angle in degrees. + * \param theNbSteps1 Quantity of rotations to be done. + * \param theRadialStep Translation distance. + * \param theNbSteps2 Quantity of translations to be done. * \return New GEOM_Object, containing compound of all the * shapes, obtained after each transformation. */ GEOM_Object MultiRotate2D (in GEOM_Object theObject, in GEOM_Object theAxis, - in double theAngle, - in long theNbTimes1, - in double theStep, - in long theNbTimes2); + in double theAngleStep, + in long theNbSteps1, + in double theRadialStep, + in long theNbSteps2); /*! * \brief Replace the given object by an object, @@ -1095,17 +1154,6 @@ module GEOM in boolean theCopy, in boolean theReverse); - /*! - * \brief Transform the shape in the same way what was used for the sample shape creation. - * \param theObject The object to be transformed. - * \param theSample The object containing information about required transformation. - * \note Implementation of this method is limited by multi-transformations now. - * \note Internal method. - * \return New GEOM_Object, containing the transformed shape. - */ - GEOM_Object TransformLikeOtherCopy (in GEOM_Object theObject, - in GEOM_Object theSample); - /*! * \brief Recompute the shape from its arguments. * \param theObject The object to be recomputed. @@ -1793,6 +1841,14 @@ module GEOM */ long GetSubShapeIndex (in GEOM_Object theMainShape, in GEOM_Object theSubShape); + /*! + * Get global indices of \a theSubShapes in \a theMainShape. + * \param theMainShape Main shape. + * \param theSubShapes List of sub-shapes of the main shape. + * \return list of global indices of \a theSubShapes in \a theMainShape. + */ + ListOfLong GetSubShapesIndices (in GEOM_Object theMainShape, in ListOfGO theSubShapes); + /*! * \brief Get index of \a theSubShape in \a theMainShape, unique among sub-shapes of the same type. * @@ -2804,6 +2860,17 @@ module GEOM in boolean theIsClosed, in boolean theDoReordering); + /*! + * \brief Create B-Spline curve on the set of points. + * \param thePoints Sequence of points for the B-Spline curve. + * \param theFirstVec Vector object, defining the curve direction at its first point. + * \param theLastVec Vector object, defining the curve direction at its last point. + * \return New GEOM_Object, containing the created B-Spline curve. + */ + GEOM_Object MakeSplineInterpolWithTangents (in ListOfGO thePoints, + in GEOM_Object theFirstVec, + in GEOM_Object theLastVec); + /*! * \brief Creates a curve using the parametric definition of the basic points. * \param thexExpr parametric equation of the coordinates X. @@ -3547,6 +3614,13 @@ module GEOM out double Ymin, out double Ymax, out double Zmin, out double Zmax); + /*! + * \brief Get bounding box of the given shape + * \param theShape Shape to obtain bounding box of. + * \return New GEOM_Object, containing the created bounding box. + */ + GEOM_Object MakeBoundingBox (in GEOM_Object theShape); + /*! * \brief Get min and max tolerances of sub-shapes of theShape * \param theShape Shape, to get tolerances of. @@ -3622,6 +3696,16 @@ module GEOM out double X1, out double Y1, out double Z1, out double X2, out double Y2, out double Z2); + /*! + * \brief Get closest points of the given shapes. + * \param theShape1,theShape2 Shapes to find closest points of. + * \param theCoords Output. List of (X, Y, Z) coordinates for all couples of points. + * \return The number of found solutions (-1 in case of infinite number of solutions). + */ + long ClosestPoints (in GEOM_Object theShape1, + in GEOM_Object theShape2, + out ListOfDouble theCoords); + /*! * \brief Get angle between the given lines or linear edges. * \param theShape1,theShape2 Shapes to find angle between. Lines or linear edges. diff --git a/resources/SalomeApp.xml.in b/resources/SalomeApp.xml.in index 6fb716e5a..2925e464d 100644 --- a/resources/SalomeApp.xml.in +++ b/resources/SalomeApp.xml.in @@ -51,6 +51,7 @@ + @@ -58,10 +59,13 @@ + + + diff --git a/src/ARCHIMEDE/Archimede_VolumeSection.cxx b/src/ARCHIMEDE/Archimede_VolumeSection.cxx index 0aee99aad..2d62cdc5e 100644 --- a/src/ARCHIMEDE/Archimede_VolumeSection.cxx +++ b/src/ARCHIMEDE/Archimede_VolumeSection.cxx @@ -24,7 +24,6 @@ // File : Archimede_VolumeSection.cxx // Author : Nicolas REJNERI // Module : GEOM -// $Header$ // #include "Archimede_VolumeSection.hxx" #include "utilities.h" diff --git a/src/ARCHIMEDE/Archimede_VolumeSection.hxx b/src/ARCHIMEDE/Archimede_VolumeSection.hxx index 183443788..158a26d15 100644 --- a/src/ARCHIMEDE/Archimede_VolumeSection.hxx +++ b/src/ARCHIMEDE/Archimede_VolumeSection.hxx @@ -24,7 +24,6 @@ // File : Archimede_VolumeSection.hxx // Author : Nicolas REJNERI // Module : GEOM -// $Header$ // #ifndef ARCHIMEDE_VOLUMESECTION_HXX #define ARCHIMEDE_VOLUMESECTION_HXX diff --git a/src/ARCHIMEDE/Makefile.am b/src/ARCHIMEDE/Makefile.am index 84d1a3560..35fcf539d 100644 --- a/src/ARCHIMEDE/Makefile.am +++ b/src/ARCHIMEDE/Makefile.am @@ -22,7 +22,6 @@ # Author : Nicolas REJNERI # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : GEOM -# $Header$ # include $(top_srcdir)/adm_local/unix/make_common_starter.am diff --git a/src/BREPExport/BREPExport.cxx b/src/BREPExport/BREPExport.cxx index 6c125cac0..7bd879a3a 100644 --- a/src/BREPExport/BREPExport.cxx +++ b/src/BREPExport/BREPExport.cxx @@ -58,8 +58,9 @@ extern "C" { -BREPEXPORT_EXPORT - int Export(const TopoDS_Shape& theShape, const TCollection_AsciiString& theFileName) + BREPEXPORT_EXPORT int Export (const TopoDS_Shape& theShape, + const TCollection_AsciiString& theFileName, + const TCollection_AsciiString& /*theFormatName*/) { MESSAGE("Export BREP into file " << theFileName.ToCString()); diff --git a/src/BREPExport/Makefile.am b/src/BREPExport/Makefile.am index 94f4ed160..675fe466e 100644 --- a/src/BREPExport/Makefile.am +++ b/src/BREPExport/Makefile.am @@ -21,7 +21,6 @@ # Author : Pavel TELKOV # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : GEOM -# $Header$ # include $(top_srcdir)/adm_local/unix/make_common_starter.am diff --git a/src/BREPImport/Makefile.am b/src/BREPImport/Makefile.am index f531040e4..083bc7dc0 100644 --- a/src/BREPImport/Makefile.am +++ b/src/BREPImport/Makefile.am @@ -21,7 +21,6 @@ # Author : Pavel TELKOV # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : GEOM -# $Header$ # include $(top_srcdir)/adm_local/unix/make_common_starter.am diff --git a/src/BasicGUI/BasicGUI_CircleDlg.cxx b/src/BasicGUI/BasicGUI_CircleDlg.cxx index b69c3660c..90488fa74 100644 --- a/src/BasicGUI/BasicGUI_CircleDlg.cxx +++ b/src/BasicGUI/BasicGUI_CircleDlg.cxx @@ -280,7 +280,6 @@ void BasicGUI_CircleDlg::ConstructorsClicked( int constructorId ) qApp->processEvents(); updateGeometry(); resize( minimumSizeHint() ); - SelectionIntoArgument(); myEditCurrentArgument->setFocus(); globalSelection(); // close local contexts, if any @@ -289,7 +288,7 @@ void BasicGUI_CircleDlg::ConstructorsClicked( int constructorId ) connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); - displayPreview(true); + SelectionIntoArgument(); } //================================================================================= diff --git a/src/BasicGUI/BasicGUI_CurveDlg.cxx b/src/BasicGUI/BasicGUI_CurveDlg.cxx index c964983ae..14b23a858 100644 --- a/src/BasicGUI/BasicGUI_CurveDlg.cxx +++ b/src/BasicGUI/BasicGUI_CurveDlg.cxx @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : BasicGUI_CurveDlg.cxx @@ -59,66 +58,101 @@ BasicGUI_CurveDlg::BasicGUI_CurveDlg( GeometryGUI* theGeometryGUI, QWidget* pare bool modal, Qt::WindowFlags fl ) : GEOMBase_Skeleton( theGeometryGUI, parent, modal, fl ) { - QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_POLYLINE" ) ) ); - QPixmap image2( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_SPLINE" ) ) ); - QPixmap image3( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_BEZIER" ) ) ); - QPixmap image1( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) ); + QPixmap image0 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_POLYLINE"))); + QPixmap image2 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_SPLINE"))); + QPixmap image3 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_BEZIER"))); + QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT"))); - setWindowTitle( tr( "GEOM_CURVE_TITLE" ) ); + setWindowTitle(tr("GEOM_CURVE_TITLE")); /***************************************************************/ - mainFrame()->RadioButton1->setIcon( image0 ); - mainFrame()->RadioButton2->setIcon( image3 ); - mainFrame()->RadioButton3->setIcon( image2 ); + mainFrame()->RadioButton1->setIcon(image0); + mainFrame()->RadioButton2->setIcon(image3); + mainFrame()->RadioButton3->setIcon(image2); - QGroupBox* creationModeCroup = new QGroupBox(this); - QButtonGroup* bg = new QButtonGroup(this); + // Creation mode + QGroupBox* creationModeGroup = new QGroupBox (this); + QButtonGroup* bg = new QButtonGroup (this); - creationModeCroup->setTitle( tr( "GEOM_CURVE_CRMODE" ) ); - QHBoxLayout * creationModeLayout = new QHBoxLayout(creationModeCroup); - myBySelectionBtn = new QRadioButton( tr( "GEOM_CURVE_SELECTION" ) ,creationModeCroup ); - myAnaliticalBtn = new QRadioButton( tr( "GEOM_CURVE_ANALITICAL" ) ,creationModeCroup ); + creationModeGroup->setTitle(tr("GEOM_CURVE_CRMODE")); + QHBoxLayout * creationModeLayout = new QHBoxLayout (creationModeGroup); + myBySelectionBtn = new QRadioButton (tr("GEOM_CURVE_SELECTION") ,creationModeGroup); + myAnaliticalBtn = new QRadioButton (tr("GEOM_CURVE_ANALITICAL") ,creationModeGroup); bg->addButton(myBySelectionBtn); bg->addButton(myAnaliticalBtn); - + creationModeLayout->addWidget(myBySelectionBtn); creationModeLayout->addWidget(myAnaliticalBtn); - GroupPoints = new DlgRef_1Sel3Check( centralWidget() ); - - GroupPoints->GroupBox1->setTitle( tr( "GEOM_NODES" ) ); - GroupPoints->TextLabel1->setText( tr( "GEOM_POINTS" ) ); - GroupPoints->PushButton1->setIcon( image1 ); - GroupPoints->PushButton1->setDown( true ); - - GroupPoints->LineEdit1->setReadOnly( true ); - - GroupPoints->CheckButton1->setText( tr( "GEOM_IS_CLOSED" ) ); - GroupPoints->CheckButton1->setChecked(false); - //GroupPoints->CheckButton1->hide(); - - GroupPoints->CheckButton2->setText( tr( "GEOM_IS_REORDER" ) ); - GroupPoints->CheckButton2->setChecked(false); - GroupPoints->CheckButton2->hide(); - - GroupPoints->CheckButton3->hide(); - - myParams = new BasicGUI_ParamCurveWidget( centralWidget() ); - - QVBoxLayout* layout = new QVBoxLayout( centralWidget() ); - layout->setMargin( 0 ); layout->setSpacing( 6 ); - layout->addWidget( creationModeCroup ); - layout->addWidget( GroupPoints ); - layout->addWidget( myParams ); + // Points and flags + myGroupPoints = new DlgRef_1Sel3Check (centralWidget()); + + myGroupPoints->GroupBox1->setTitle(tr("GEOM_NODES")); + myGroupPoints->TextLabel1->setText(tr("GEOM_POINTS")); + myGroupPoints->PushButton1->setIcon(image1); + myGroupPoints->PushButton1->setDown(true); + + myGroupPoints->LineEdit1->setReadOnly( true ); + + myGroupPoints->CheckButton1->setText( tr( "GEOM_IS_CLOSED" ) ); + myGroupPoints->CheckButton1->setChecked(false); + //myGroupPoints->CheckButton1->hide(); + + myGroupPoints->CheckButton2->setText( tr( "GEOM_IS_REORDER" ) ); + myGroupPoints->CheckButton2->setChecked(false); + myGroupPoints->CheckButton2->hide(); + + myGroupPoints->CheckButton3->hide(); + + // Parametrical mode + myGroupParams = new BasicGUI_ParamCurveWidget( centralWidget() ); + + // Tangents (only for Interpolation constructor and only not closed and no reordering) + myGroupTangents = new QGroupBox (this); + myGroupTangents->setCheckable(true); + myGroupTangents->setChecked(false); + myGroupTangents->setTitle(tr("GEOM_INTERPOL_TANGENTS")); + + QGridLayout* tangentsLayout = new QGridLayout (myGroupTangents); + + myPushBtnV1 = new QPushButton (myGroupTangents); + myPushBtnV2 = new QPushButton (myGroupTangents); + myPushBtnV1->setIcon(image1); + myPushBtnV2->setIcon(image1); + + myLineEditV1 = new QLineEdit (myGroupTangents); + myLineEditV2 = new QLineEdit (myGroupTangents); + myLineEditV1->setReadOnly(true); + myLineEditV2->setReadOnly(true); + + QLabel* aTextLabelV1 = new QLabel (myGroupTangents); + QLabel* aTextLabelV2 = new QLabel (myGroupTangents); + aTextLabelV1->setText(tr("GEOM_INTERPOL_FIRST_VEC")); + aTextLabelV2->setText(tr("GEOM_INTERPOL_LAST_VEC")); + + tangentsLayout->addWidget(aTextLabelV1, 0, 0); + tangentsLayout->addWidget(myPushBtnV1 , 0, 1); + tangentsLayout->addWidget(myLineEditV1, 0, 2); + tangentsLayout->addWidget(aTextLabelV2, 1, 0); + tangentsLayout->addWidget(myPushBtnV2 , 1, 1); + tangentsLayout->addWidget(myLineEditV2, 1, 2); + + // Layout + QVBoxLayout* layout = new QVBoxLayout (centralWidget()); + layout->setMargin(0); + layout->setSpacing(6); + layout->addWidget(creationModeGroup); + layout->addWidget(myGroupPoints); + layout->addWidget(myGroupParams); + layout->addWidget(myGroupTangents); /***************************************************************/ - setHelpFileName( "create_curve_page.html" ); + setHelpFileName("create_curve_page.html"); Init(); } - //================================================================================= // function : ~BasicGUI_CurveDlg() // purpose : Destroys the object and frees any allocated resources @@ -127,7 +161,6 @@ BasicGUI_CurveDlg::~BasicGUI_CurveDlg() { } - //================================================================================= // function : Init() // purpose : @@ -135,13 +168,6 @@ BasicGUI_CurveDlg::~BasicGUI_CurveDlg() void BasicGUI_CurveDlg::Init() { /* init variables */ - myEditCurrentArgument = GroupPoints->LineEdit1; - - myPoints.clear(); - - globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); - showOnlyPreviewControl(); myBySelectionBtn->setChecked(true); @@ -152,87 +178,95 @@ void BasicGUI_CurveDlg::Init() double aMax( 100. ), aMin( 0.0 ); /* min, max, step and decimals for spin boxes & initial values */ - initSpinBox( myParams->myPMin, COORD_MIN, COORD_MAX, step, "length_precision" ); - initSpinBox( myParams->myPMax, COORD_MIN, COORD_MAX, step, "length_precision" ); - myParams->myPStep->setValue( 10 ); - myParams->myPStep->setMaximum( 999 ); - myParams->myPStep->setSingleStep( 10 ); - myParams->myPMin->setValue( aMin ); - myParams->myPMax->setValue( aMax ); - myParams->myPStep->setValue( step ); - myParams->myXExpr->setText("t"); - myParams->myYExpr->setText("t"); - myParams->myZExpr->setText("t"); - - myParams->hide(); + initSpinBox( myGroupParams->myPMin, COORD_MIN, COORD_MAX, step, "length_precision" ); + initSpinBox( myGroupParams->myPMax, COORD_MIN, COORD_MAX, step, "length_precision" ); + myGroupParams->myPStep->setValue( 10 ); + myGroupParams->myPStep->setMaximum( 999 ); + myGroupParams->myPStep->setSingleStep( 10 ); + myGroupParams->myPMin->setValue( aMin ); + myGroupParams->myPMax->setValue( aMax ); + myGroupParams->myPStep->setValue( step ); + myGroupParams->myXExpr->setText("t"); + myGroupParams->myYExpr->setText("t"); + myGroupParams->myZExpr->setText("t"); + + myGroupParams->hide(); /* signals and slots connections */ - connect( myGeomGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog( ) ) ); - connect( myGeomGUI, SIGNAL( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ); + connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); + connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); - connect( buttonOk(), SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); - connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) ); + connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); - connect( this, SIGNAL( constructorsClicked( int ) ), this, SLOT( ConstructorsClicked( int ) ) ); + connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int))); - connect( GroupPoints->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) ); + connect(myGroupPoints->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(myPushBtnV1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(myPushBtnV2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); - connect( GroupPoints->CheckButton1, SIGNAL( toggled(bool) ), this, SLOT( CheckButtonToggled() ) ); - connect( GroupPoints->CheckButton2, SIGNAL( toggled(bool) ), this, SLOT( CheckButtonToggled() ) ); + connect(myGroupPoints->CheckButton1, SIGNAL(toggled(bool)), this, SLOT(CheckButtonToggled())); + connect(myGroupPoints->CheckButton2, SIGNAL(toggled(bool)), this, SLOT(CheckButtonToggled())); + connect(myGroupTangents, SIGNAL(toggled(bool)), this, SLOT(CheckButtonToggled())); - connect( myGeomGUI->getApp()->selectionMgr(), - SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); - connect( myBySelectionBtn, SIGNAL( clicked() ), this, SLOT( CreationModeChanged() ) ); - connect( myAnaliticalBtn, SIGNAL( clicked() ), this, SLOT( CreationModeChanged() ) ); + connect(myBySelectionBtn, SIGNAL(clicked()), this, SLOT(CreationModeChanged())); + connect(myAnaliticalBtn, SIGNAL(clicked()), this, SLOT(CreationModeChanged())); - connect(myParams->myPMin, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); - connect(myParams->myPMax, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); - connect(myParams->myPStep, SIGNAL(valueChanged(int)), this, SLOT(ValueChangedInSpinBox(int))); + connect(myGroupParams->myPMin, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(myGroupParams->myPMax, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(myGroupParams->myPStep, SIGNAL(valueChanged(int)), this, SLOT(ValueChangedInSpinBox(int))); - connect(myParams->myXExpr, SIGNAL(editingFinished()), this, SLOT(OnEditingFinished())); - connect(myParams->myYExpr, SIGNAL(editingFinished()), this, SLOT(OnEditingFinished())); - connect(myParams->myZExpr, SIGNAL(editingFinished()), this, SLOT(OnEditingFinished())); + connect(myGroupParams->myXExpr, SIGNAL(editingFinished()), this, SLOT(OnEditingFinished())); + connect(myGroupParams->myYExpr, SIGNAL(editingFinished()), this, SLOT(OnEditingFinished())); + connect(myGroupParams->myZExpr, SIGNAL(editingFinished()), this, SLOT(OnEditingFinished())); - initName( tr( "GEOM_CURVE" ) ); - resize(100,100); - ConstructorsClicked( 0 ); + initName(tr("GEOM_CURVE")); + //resize(100, 100); + ConstructorsClicked(0); } //================================================================================= // function : ConstructorsClicked() // purpose : //================================================================================= -void BasicGUI_CurveDlg::ConstructorsClicked( int id ) +void BasicGUI_CurveDlg::ConstructorsClicked (int id) { - QString aTitle = tr( id == 0 ? "GEOM_POLYLINE" : id == 1 ? "GEOM_BEZIER" : "GEOM_INTERPOL" ); - mainFrame()->GroupConstructors->setTitle( aTitle ); + QString aTitle = tr(id == 0 ? "GEOM_POLYLINE" : id == 1 ? "GEOM_BEZIER" : "GEOM_INTERPOL"); + mainFrame()->GroupConstructors->setTitle(aTitle); if (id == 0) { // polyline (wire) - //GroupPoints->CheckButton1->hide(); - GroupPoints->CheckButton1->setText( tr( "GEOM_BUILD_CLOSED_WIRE" ) ); - GroupPoints->CheckButton2->hide(); + myGroupPoints->CheckButton1->setText( tr( "GEOM_BUILD_CLOSED_WIRE" ) ); + myGroupPoints->CheckButton2->hide(); + myGroupTangents->hide(); } else if (id == 1) { // bezier - //GroupPoints->CheckButton1->hide(); - GroupPoints->CheckButton1->setText( tr( "GEOM_IS_CLOSED" ) ); - GroupPoints->CheckButton2->hide(); + myGroupPoints->CheckButton1->setText( tr( "GEOM_IS_CLOSED" ) ); + myGroupPoints->CheckButton2->hide(); + myGroupTangents->hide(); } else { // b-spline - //GroupPoints->CheckButton1->show(); - GroupPoints->CheckButton1->setText( tr( "GEOM_IS_CLOSED" ) ); - GroupPoints->CheckButton2->show(); + myGroupPoints->CheckButton1->setText( tr( "GEOM_IS_CLOSED" ) ); + myGroupPoints->CheckButton2->show(); + myGroupTangents->setVisible(myBySelectionBtn->isChecked()); } myPoints.clear(); + myVec1.nullify(); + myVec2.nullify(); + + myGroupPoints->LineEdit1->setText(""); + myLineEditV1->setText(""); + myLineEditV2->setText(""); - myEditCurrentArgument->setText( "" ); qApp->processEvents(); updateGeometry(); - resize( minimumSizeHint() ); - SelectionIntoArgument(); -} + resize(minimumSizeHint()); + myGroupPoints->PushButton1->click(); +} //================================================================================= // function : SetEditCurrentArgument() @@ -240,9 +274,28 @@ void BasicGUI_CurveDlg::ConstructorsClicked( int id ) //================================================================================= void BasicGUI_CurveDlg::SetEditCurrentArgument() { - if ( sender() == GroupPoints->PushButton1 ) - myEditCurrentArgument = GroupPoints->LineEdit1; + disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); + + globalSelection(); // close local contexts, if any + + if (sender() == myGroupPoints->PushButton1) { + myEditCurrentArgument = myGroupPoints->LineEdit1; + localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + } + else if (sender() == myPushBtnV1) { + myEditCurrentArgument = myLineEditV1; + localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + } + else if (sender() == myPushBtnV2) { + myEditCurrentArgument = myLineEditV2; + localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + } + myEditCurrentArgument->setFocus(); + + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + SelectionIntoArgument(); } @@ -252,7 +305,20 @@ void BasicGUI_CurveDlg::SetEditCurrentArgument() //================================================================================= void BasicGUI_CurveDlg::CheckButtonToggled() { - processPreview(); + if (sender() == myGroupTangents) { + if (myGroupTangents->isChecked()) + myPushBtnV1->click(); + else + myGroupPoints->PushButton1->click(); + } + else { + if (getConstructorId() == 2) { // Interpolation + bool disableTangents = (myGroupPoints->CheckButton1->isChecked() || + myGroupPoints->CheckButton2->isChecked()); + myGroupTangents->setEnabled(!disableTangents); + } + processPreview(); + } } //================================================================================= @@ -261,8 +327,8 @@ void BasicGUI_CurveDlg::CheckButtonToggled() //================================================================================= void BasicGUI_CurveDlg::ClickOnOk() { - setIsApplyAndClose( true ); - if ( ClickOnApply() ) + setIsApplyAndClose(true); + if (ClickOnApply()) ClickOnCancel(); } @@ -272,20 +338,23 @@ void BasicGUI_CurveDlg::ClickOnOk() //================================================================================= bool BasicGUI_CurveDlg::ClickOnApply() { - if ( !onAccept() ) + if (!onAccept()) return false; initName(); - globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + ConstructorsClicked(getConstructorId()); return true; } -static void synchronize( QList& left, QList& right ) +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection as changed or other case +//================================================================================= +static void synchronize (QList& left, QList& right) { // 1. remove items from the "left" list that are not in the "right" list - QMutableListIterator it1( left ); - while ( it1.hasNext() ) { + QMutableListIterator it1 (left); + while (it1.hasNext()) { GEOM::GeomObjPtr o1 = it1.next(); bool found = false; QMutableListIterator it2( right ); @@ -307,22 +376,38 @@ static void synchronize( QList& left, QList& } } -//================================================================================= -// function : SelectionIntoArgument() -// purpose : Called when selection as changed or other case -//================================================================================= void BasicGUI_CurveDlg::SelectionIntoArgument() { - QList points = getSelected( TopAbs_VERTEX, -1 ); - synchronize( myPoints, points ); - if ( !myPoints.isEmpty() ) - GroupPoints->LineEdit1->setText( QString::number( myPoints.count() ) + "_" + tr( "GEOM_POINT" ) + tr( "_S_" ) ); - else - GroupPoints->LineEdit1->setText( "" ); + myEditCurrentArgument->setText(""); + + if (myEditCurrentArgument == myGroupPoints->LineEdit1) { + QList points = getSelected(TopAbs_VERTEX, -1); + synchronize(myPoints, points); + if (!myPoints.isEmpty()) + myGroupPoints->LineEdit1->setText(QString::number(myPoints.count()) + "_" + + tr("GEOM_POINT") + tr("_S_")); + } + else { + QList vecs = getSelected(TopAbs_EDGE, -1); + if (vecs.count() != 1) { + if (myEditCurrentArgument == myLineEditV1) myVec1.nullify(); + else if (myEditCurrentArgument == myLineEditV2) myVec2.nullify(); + } + else { + if (myEditCurrentArgument == myLineEditV1) { + myVec1 = vecs.first(); + } + else if (myEditCurrentArgument == myLineEditV2) { + myVec2 = vecs.first(); + } + QString aName = GEOMBase::GetName(vecs.first().get()); + myEditCurrentArgument->setText(aName); + } + } + processPreview(); } - //================================================================================= // function : ActivateThisDialog() // purpose : @@ -330,13 +415,11 @@ void BasicGUI_CurveDlg::SelectionIntoArgument() void BasicGUI_CurveDlg::ActivateThisDialog() { GEOMBase_Skeleton::ActivateThisDialog(); - connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ), - this, SLOT( SelectionIntoArgument() ) ); - globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); - ConstructorsClicked( getConstructorId() ); + ConstructorsClicked(getConstructorId()); } //================================================================================= @@ -353,9 +436,9 @@ void BasicGUI_CurveDlg::DeactivateActiveDialog() // function : enterEvent() // purpose : //================================================================================= -void BasicGUI_CurveDlg::enterEvent( QEvent* ) +void BasicGUI_CurveDlg::enterEvent (QEvent*) { - if ( !mainFrame()->GroupConstructors->isEnabled() ) + if (!mainFrame()->GroupConstructors->isEnabled()) ActivateThisDialog(); } @@ -365,24 +448,34 @@ void BasicGUI_CurveDlg::enterEvent( QEvent* ) //================================================================================= GEOM::GEOM_IOperations_ptr BasicGUI_CurveDlg::createOperation() { - return myGeomGUI->GetGeomGen()->GetICurvesOperations( getStudyId() ); + return myGeomGUI->GetGeomGen()->GetICurvesOperations(getStudyId()); } //================================================================================= // function : isValid // purpose : //================================================================================= -bool BasicGUI_CurveDlg::isValid( QString& msg ) +bool BasicGUI_CurveDlg::isValid (QString& msg) { - if( myBySelectionBtn->isChecked() ) - return myPoints.count() > 1; + if (myBySelectionBtn->isChecked()) { + bool ok = true; + if (getConstructorId() == 2) { // Interpolation + bool disableTangents = (myGroupPoints->CheckButton1->isChecked() || + myGroupPoints->CheckButton2->isChecked()); + if (!disableTangents && myGroupTangents->isChecked()) { + ok = (myVec1 && myVec2); + if (!ok) msg = tr("GEOM_BOTH_TANGENTS_REQUIRED"); + } + } + return ok && myPoints.count() > 1; + } else { - bool ok = myParams->myPMin->isValid( msg, !IsPreview() ) && - myParams->myPMax->isValid( msg, !IsPreview() ) && - myParams->myPStep->isValid( msg, !IsPreview() ); - ok &= !myParams->myXExpr->text().isEmpty(); - ok &= !myParams->myYExpr->text().isEmpty(); - ok &= !myParams->myZExpr->text().isEmpty(); + bool ok = myGroupParams->myPMin->isValid( msg, !IsPreview() ) && + myGroupParams->myPMax->isValid( msg, !IsPreview() ) && + myGroupParams->myPStep->isValid( msg, !IsPreview() ); + ok &= !myGroupParams->myXExpr->text().isEmpty(); + ok &= !myGroupParams->myYExpr->text().isEmpty(); + ok &= !myGroupParams->myZExpr->text().isEmpty(); return ok; } } @@ -391,79 +484,85 @@ bool BasicGUI_CurveDlg::isValid( QString& msg ) // function : execute // purpose : //================================================================================= -bool BasicGUI_CurveDlg::execute( ObjectList& objects ) +bool BasicGUI_CurveDlg::execute (ObjectList& objects) { bool res = false; GEOM::GEOM_Object_var anObj; - GEOM::GEOM_ICurvesOperations_var anOper = GEOM::GEOM_ICurvesOperations::_narrow( getOperation() ); + GEOM::GEOM_ICurvesOperations_var anOper = GEOM::GEOM_ICurvesOperations::_narrow(getOperation()); GEOM::ListOfGO_var points = new GEOM::ListOfGO(); - points->length( myPoints.count() ); - for ( int i = 0; i < myPoints.count(); i++ ) + points->length(myPoints.count()); + for (int i = 0; i < myPoints.count(); i++) points[i] = myPoints[i].copy(); - switch ( getConstructorId() ) { + switch (getConstructorId()) { case 0 : - if( myBySelectionBtn->isChecked() ) - anObj = anOper->MakePolyline( points.in(), GroupPoints->CheckButton1->isChecked() ); + if (myBySelectionBtn->isChecked()) + anObj = anOper->MakePolyline(points.in(), myGroupPoints->CheckButton1->isChecked()); else - anObj = anOper->MakeCurveParametricNew(qPrintable(myParams->myXExpr->text()), - qPrintable(myParams->myYExpr->text()), - qPrintable(myParams->myZExpr->text()), - myParams->myPMin->value(), - myParams->myPMax->value(), - myParams->myPStep->value(), - GEOM::Polyline); + anObj = anOper->MakeCurveParametricNew(qPrintable(myGroupParams->myXExpr->text()), + qPrintable(myGroupParams->myYExpr->text()), + qPrintable(myGroupParams->myZExpr->text()), + myGroupParams->myPMin->value(), + myGroupParams->myPMax->value(), + myGroupParams->myPStep->value(), + GEOM::Polyline); res = true; break; case 1 : - if( myBySelectionBtn->isChecked() ) - anObj = anOper->MakeSplineBezier( points.in(), GroupPoints->CheckButton1->isChecked() ); + if (myBySelectionBtn->isChecked()) + anObj = anOper->MakeSplineBezier(points.in(), myGroupPoints->CheckButton1->isChecked()); else - anObj = anOper->MakeCurveParametricNew(qPrintable(myParams->myXExpr->text()), - qPrintable(myParams->myYExpr->text()), - qPrintable(myParams->myZExpr->text()), - myParams->myPMin->value(), - myParams->myPMax->value(), - myParams->myPStep->value(), - GEOM::Bezier); - + anObj = anOper->MakeCurveParametricNew(qPrintable(myGroupParams->myXExpr->text()), + qPrintable(myGroupParams->myYExpr->text()), + qPrintable(myGroupParams->myZExpr->text()), + myGroupParams->myPMin->value(), + myGroupParams->myPMax->value(), + myGroupParams->myPStep->value(), + GEOM::Bezier); res = true; break; case 2 : - if( myBySelectionBtn->isChecked() ) - anObj = anOper->MakeSplineInterpolation( points.in(), GroupPoints->CheckButton1->isChecked(), - GroupPoints->CheckButton2->isChecked() ); + if (myBySelectionBtn->isChecked()) { + bool disableTangents = (myGroupPoints->CheckButton1->isChecked() || + myGroupPoints->CheckButton2->isChecked()); + if (!disableTangents && myGroupTangents->isChecked()) { + anObj = anOper->MakeSplineInterpolWithTangents(points.in(), myVec1.get(), myVec2.get()); + } + else + anObj = anOper->MakeSplineInterpolation(points.in(), myGroupPoints->CheckButton1->isChecked(), + myGroupPoints->CheckButton2->isChecked()); + } else - anObj = anOper->MakeCurveParametricNew(qPrintable(myParams->myXExpr->text()), - qPrintable(myParams->myYExpr->text()), - qPrintable(myParams->myZExpr->text()), - myParams->myPMin->value(), - myParams->myPMax->value(), - myParams->myPStep->value(), - GEOM::Interpolation); + anObj = anOper->MakeCurveParametricNew(qPrintable(myGroupParams->myXExpr->text()), + qPrintable(myGroupParams->myYExpr->text()), + qPrintable(myGroupParams->myZExpr->text()), + myGroupParams->myPMin->value(), + myGroupParams->myPMax->value(), + myGroupParams->myPStep->value(), + GEOM::Interpolation); res = true; break; } - if ( !anObj->_is_nil() ) { - if(myAnaliticalBtn->isChecked() && !IsPreview()) { + if (!anObj->_is_nil()) { + if (myAnaliticalBtn->isChecked() && !IsPreview()) { QStringList aParameters; - aParameters<myPMin->text(); - aParameters<myPMax->text(); - aParameters<myPStep->text(); + aParameters<myPMin->text(); + aParameters<myPMax->text(); + aParameters<myPStep->text(); anObj->SetParameters(aParameters.join(":").toLatin1().constData()); } - objects.push_back( anObj._retn() ); + objects.push_back(anObj._retn()); } - + return res; } //================================================================================= -// function : addSubshapeToStudy +// function : addSubshapesToStudy // purpose : virtual method to add new SubObjects if local selection //================================================================================= void BasicGUI_CurveDlg::addSubshapesToStudy() @@ -476,19 +575,20 @@ void BasicGUI_CurveDlg::addSubshapesToStudy() // function : CreationModeChanged // purpose : //================================================================================= -void BasicGUI_CurveDlg::CreationModeChanged() { +void BasicGUI_CurveDlg::CreationModeChanged() +{ const QObject* s = sender(); - GroupPoints->setVisible(myBySelectionBtn == s); - myParams->setVisible(myBySelectionBtn != s); - - ConstructorsClicked( getConstructorId() ); + myGroupPoints->setVisible(myBySelectionBtn == s); + myGroupParams->setVisible(myBySelectionBtn != s); + + ConstructorsClicked(getConstructorId()); } //================================================================================= // function : ValueChangedInSpinBox() // purpose : //================================================================================= -void BasicGUI_CurveDlg::ValueChangedInSpinBox(double/*theValue*/) +void BasicGUI_CurveDlg::ValueChangedInSpinBox (double/*theValue*/) { processPreview(); } @@ -497,15 +597,16 @@ void BasicGUI_CurveDlg::ValueChangedInSpinBox(double/*theValue*/) // function : ValueChangedInSpinBox() // purpose : //================================================================================= -void BasicGUI_CurveDlg::ValueChangedInSpinBox(int/*theValue*/) +void BasicGUI_CurveDlg::ValueChangedInSpinBox (int/*theValue*/) { processPreview(); } //================================================================================= -// function : ValueChangedInSpinBox() +// function : OnEditingFinished() // purpose : //================================================================================= -void BasicGUI_CurveDlg::OnEditingFinished() { +void BasicGUI_CurveDlg::OnEditingFinished() +{ processPreview(); } diff --git a/src/BasicGUI/BasicGUI_CurveDlg.h b/src/BasicGUI/BasicGUI_CurveDlg.h index ce9a6a9e7..8d6751b5e 100644 --- a/src/BasicGUI/BasicGUI_CurveDlg.h +++ b/src/BasicGUI/BasicGUI_CurveDlg.h @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : BasicGUI_CurveDlg.h @@ -34,6 +33,9 @@ class DlgRef_1Sel3Check; class QRadioButton; +class QPushButton; +class QLineEdit; +class QGroupBox; class BasicGUI_ParamCurveWidget; //================================================================================= @@ -45,26 +47,34 @@ class BasicGUI_CurveDlg : public GEOMBase_Skeleton Q_OBJECT public: - BasicGUI_CurveDlg( GeometryGUI*, QWidget* = 0, bool = false, Qt::WindowFlags = 0 ); + BasicGUI_CurveDlg (GeometryGUI*, QWidget* = 0, bool = false, Qt::WindowFlags = 0); ~BasicGUI_CurveDlg(); protected: // redefined from GEOMBase_Helper virtual GEOM::GEOM_IOperations_ptr createOperation(); - virtual bool isValid( QString& ); - virtual bool execute( ObjectList& ); + virtual bool isValid (QString&); + virtual bool execute (ObjectList&); virtual void addSubshapesToStudy(); private: void Init(); - void enterEvent( QEvent* ); + void enterEvent (QEvent*); private: - DlgRef_1Sel3Check* GroupPoints; - QList myPoints; QRadioButton* myAnaliticalBtn; QRadioButton* myBySelectionBtn; - BasicGUI_ParamCurveWidget* myParams; + DlgRef_1Sel3Check* myGroupPoints; + BasicGUI_ParamCurveWidget* myGroupParams; + QGroupBox* myGroupTangents; + + QPushButton* myPushBtnV1; + QPushButton* myPushBtnV2; + QLineEdit* myLineEditV1; + QLineEdit* myLineEditV2; + + QList myPoints; + GEOM::GeomObjPtr myVec1, myVec2; private slots: void ClickOnOk(); @@ -73,13 +83,13 @@ private slots: void ActivateThisDialog(); void DeactivateActiveDialog(); - void ConstructorsClicked( int ); + void ConstructorsClicked (int); void CheckButtonToggled(); void SelectionIntoArgument(); void SetEditCurrentArgument(); void CreationModeChanged(); - void ValueChangedInSpinBox(double/*theValue*/); - void ValueChangedInSpinBox(int /*theValue*/); + void ValueChangedInSpinBox (double/*theValue*/); + void ValueChangedInSpinBox (int /*theValue*/); void OnEditingFinished(); }; diff --git a/src/GEOMAlgo/BlockFix.cxx b/src/BlockFix/BlockFix.cxx similarity index 100% rename from src/GEOMAlgo/BlockFix.cxx rename to src/BlockFix/BlockFix.cxx diff --git a/src/GEOMAlgo/BlockFix.hxx b/src/BlockFix/BlockFix.hxx similarity index 78% rename from src/GEOMAlgo/BlockFix.hxx rename to src/BlockFix/BlockFix.hxx index 34007be5c..70d37df65 100644 --- a/src/GEOMAlgo/BlockFix.hxx +++ b/src/BlockFix/BlockFix.hxx @@ -18,14 +18,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #ifndef _BlockFix_HeaderFile #define _BlockFix_HeaderFile -#ifndef _Standard_Real_HeaderFile #include -#endif class TopoDS_Shape; class BlockFix_SphereSpaceModifier; @@ -35,36 +32,16 @@ class BlockFix_BlockFixAPI; class BlockFix_PeriodicSurfaceModifier; class BlockFix_CheckTool; -#ifndef _Standard_HeaderFile #include -#endif -#ifndef _Standard_Macro_HeaderFile #include -#endif -class BlockFix { +class BlockFix { public: - - void* operator new(size_t,void* anAddress) - { - return anAddress; - } - void* operator new(size_t size) - { - return Standard::Allocate(size); - } - void operator delete(void *anAddress) - { - if (anAddress) Standard::Free((Standard_Address&)anAddress); - } - Standard_EXPORT static TopoDS_Shape RotateSphereSpace(const TopoDS_Shape& S,const Standard_Real Tol); Standard_EXPORT static TopoDS_Shape RefillProblemFaces(const TopoDS_Shape& S); Standard_EXPORT static TopoDS_Shape FixRanges(const TopoDS_Shape& S,const Standard_Real Tol); -protected: - private: friend class BlockFix_SphereSpaceModifier; @@ -76,6 +53,4 @@ friend class BlockFix_CheckTool; }; -// other Inline functions and methods (like "C++: function call" methods) - #endif diff --git a/src/GEOMAlgo/BlockFix_BlockFixAPI.cxx b/src/BlockFix/BlockFix_BlockFixAPI.cxx similarity index 85% rename from src/GEOMAlgo/BlockFix_BlockFixAPI.cxx rename to src/BlockFix/BlockFix_BlockFixAPI.cxx index 3c82e4a84..376632b4f 100644 --- a/src/GEOMAlgo/BlockFix_BlockFixAPI.cxx +++ b/src/BlockFix/BlockFix_BlockFixAPI.cxx @@ -23,7 +23,7 @@ // Created: Tue Dec 7 11:59:05 2004 // Author: Pavel DURANDIN -#include +#include #include #include @@ -35,11 +35,13 @@ #include +IMPLEMENT_STANDARD_HANDLE(BlockFix_BlockFixAPI, MMgt_TShared); +IMPLEMENT_STANDARD_RTTIEXT(BlockFix_BlockFixAPI, MMgt_TShared); + //======================================================================= -//function : ShapeConvert_CanonicAPI +//function : BlockFix_BlockFixAPI //purpose : //======================================================================= - BlockFix_BlockFixAPI::BlockFix_BlockFixAPI() { myTolerance = Precision::Confusion(); @@ -47,10 +49,15 @@ BlockFix_BlockFixAPI::BlockFix_BlockFixAPI() } //======================================================================= -//function : Perform +//function : ~BlockFix_BlockFixAPI //purpose : //======================================================================= +BlockFix_BlockFixAPI::~BlockFix_BlockFixAPI() {} +//======================================================================= +//function : Perform +//purpose : +//======================================================================= void BlockFix_BlockFixAPI::Perform() { // processing spheres with degenerativities diff --git a/src/GEOMAlgo/BlockFix_BlockFixAPI.lxx b/src/BlockFix/BlockFix_BlockFixAPI.hxx similarity index 72% rename from src/GEOMAlgo/BlockFix_BlockFixAPI.lxx rename to src/BlockFix/BlockFix_BlockFixAPI.hxx index 5992e1794..84140aff5 100644 --- a/src/GEOMAlgo/BlockFix_BlockFixAPI.lxx +++ b/src/BlockFix/BlockFix_BlockFixAPI.hxx @@ -18,15 +18,46 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#include +#ifndef _BlockFix_BlockFixAPI_HeaderFile +#define _BlockFix_BlockFixAPI_HeaderFile + +#include +#include + +#include +#include +#include +#include + +DEFINE_STANDARD_HANDLE(BlockFix_BlockFixAPI, MMgt_TShared); + +class BlockFix_BlockFixAPI : public MMgt_TShared +{ +public: + Standard_EXPORT BlockFix_BlockFixAPI(); + Standard_EXPORT ~BlockFix_BlockFixAPI(); + + void SetShape(const TopoDS_Shape& Shape); + TopoDS_Shape Shape() const; + Handle_ShapeBuild_ReShape& Context(); + Standard_Real& Tolerance(); + Standard_Integer& OptimumNbFaces(); + Standard_EXPORT void Perform(); + + DEFINE_STANDARD_RTTI(BlockFix_BlockFixAPI); + +private: + Handle_ShapeBuild_ReShape myContext; + TopoDS_Shape myShape; + Standard_Real myTolerance; + Standard_Integer myOptimumNbFaces; +}; //======================================================================= //function : SetShape //purpose : //======================================================================= - inline void BlockFix_BlockFixAPI::SetShape(const TopoDS_Shape& Shape) { myShape = Shape; @@ -36,7 +67,6 @@ inline void BlockFix_BlockFixAPI::SetShape(const TopoDS_Shape& Shape) //function : Shape //purpose : //======================================================================= - inline TopoDS_Shape BlockFix_BlockFixAPI::Shape() const { return myShape; @@ -46,7 +76,6 @@ inline TopoDS_Shape BlockFix_BlockFixAPI::Shape() const //function : Context //purpose : //======================================================================= - inline Handle(ShapeBuild_ReShape)& BlockFix_BlockFixAPI::Context() { return myContext; @@ -56,7 +85,6 @@ inline Handle(ShapeBuild_ReShape)& BlockFix_BlockFixAPI::Context() //function : Tolerance //purpose : //======================================================================= - inline Standard_Real& BlockFix_BlockFixAPI::Tolerance() { return myTolerance; @@ -66,8 +94,9 @@ inline Standard_Real& BlockFix_BlockFixAPI::Tolerance() //function : OptimumNbFaces //purpose : //======================================================================= - inline Standard_Integer& BlockFix_BlockFixAPI::OptimumNbFaces() { return myOptimumNbFaces; } + +#endif diff --git a/src/GEOMAlgo/BlockFix_CheckTool.cxx b/src/BlockFix/BlockFix_CheckTool.cxx similarity index 98% rename from src/GEOMAlgo/BlockFix_CheckTool.cxx rename to src/BlockFix/BlockFix_CheckTool.cxx index 674ef69dd..ba1c5c6af 100644 --- a/src/GEOMAlgo/BlockFix_CheckTool.cxx +++ b/src/BlockFix/BlockFix_CheckTool.cxx @@ -18,48 +18,43 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File: BlockFix_CheckTool.cxx // Created: 17.12.04 11:15:25 // Author: Sergey KUUL -// -#include -//#include -//#include +#include #include #include #include + #include #include #include #include +#include + #include #include #include #include - //======================================================================= //function : BlockFix_CheckTool() //purpose : Constructor //======================================================================= - BlockFix_CheckTool::BlockFix_CheckTool( ) { myHasCheck = Standard_False; myPossibleBlocks.Clear(); } - //======================================================================= //function : SetShape //purpose : //======================================================================= - void BlockFix_CheckTool::SetShape(const TopoDS_Shape& aShape) { myHasCheck = Standard_False; @@ -67,12 +62,10 @@ void BlockFix_CheckTool::SetShape(const TopoDS_Shape& aShape) myPossibleBlocks.Clear(); } - //======================================================================= //function : Perform //purpose : //======================================================================= - void BlockFix_CheckTool::Perform() { myNbSolids=0; @@ -229,23 +222,19 @@ void BlockFix_CheckTool::Perform() myHasCheck = Standard_True; } - //======================================================================= //function : NbPossibleBlocks //purpose : //======================================================================= - Standard_Integer BlockFix_CheckTool::NbPossibleBlocks() const { return myPossibleBlocks.Length(); } - //======================================================================= //function : PossibleBlock //purpose : //======================================================================= - TopoDS_Shape BlockFix_CheckTool::PossibleBlock(const Standard_Integer num) const { TopoDS_Shape res; @@ -254,12 +243,10 @@ TopoDS_Shape BlockFix_CheckTool::PossibleBlock(const Standard_Integer num) const return res; } - //======================================================================= //function : DumpCheckResult //purpose : //======================================================================= - void BlockFix_CheckTool::DumpCheckResult(Standard_OStream& S) const { if(!myHasCheck) diff --git a/src/GEOMAlgo/BlockFix_CheckTool.jxx b/src/BlockFix/BlockFix_CheckTool.hxx similarity index 52% rename from src/GEOMAlgo/BlockFix_CheckTool.jxx rename to src/BlockFix/BlockFix_CheckTool.hxx index 7574af057..9378b25d1 100644 --- a/src/GEOMAlgo/BlockFix_CheckTool.jxx +++ b/src/BlockFix/BlockFix_CheckTool.hxx @@ -18,11 +18,42 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#ifndef _TopoDS_Shape_HeaderFile -#include -#endif #ifndef _BlockFix_CheckTool_HeaderFile -#include +#define _BlockFix_CheckTool_HeaderFile + +#include +#include +#include +#include +#include + +class TopoDS_Shape; + +#include +#include + +class BlockFix_CheckTool { + +public: + Standard_EXPORT BlockFix_CheckTool(); + Standard_EXPORT void SetShape(const TopoDS_Shape& aShape) ; + Standard_EXPORT void Perform() ; + Standard_EXPORT Standard_Integer NbPossibleBlocks() const; + Standard_EXPORT TopoDS_Shape PossibleBlock(const Standard_Integer num) const; + Standard_EXPORT void DumpCheckResult(Standard_OStream& S) const; + +private: + TopoDS_Shape myShape; + Standard_Boolean myHasCheck; + Standard_Integer myNbSolids; + Standard_Integer myNbBlocks; + TopTools_SequenceOfShape myPossibleBlocks; + Standard_Integer myNbDegen; + Standard_Integer myNbUF; + Standard_Integer myNbUE; + Standard_Integer myNbUFUE; + Standard_Integer myBadRanges; +}; + #endif diff --git a/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.cxx b/src/BlockFix/BlockFix_PeriodicSurfaceModifier.cxx similarity index 92% rename from src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.cxx rename to src/BlockFix/BlockFix_PeriodicSurfaceModifier.cxx index 1e9f33ca0..3894c353f 100644 --- a/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.cxx +++ b/src/BlockFix/BlockFix_PeriodicSurfaceModifier.cxx @@ -18,51 +18,71 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File: BlockFix_PeriodicSurfaceModifier.cxx // Created: 15.12.04 10:08:50 // Author: Sergey KUUL -#include +#include + +#include + +#include + +#include +#include +#include + +#include #include #include + #include + #include #include -#include -#include +#include +#include + +#include + +#include +IMPLEMENT_STANDARD_HANDLE(BlockFix_PeriodicSurfaceModifier, BRepTools_Modification); +IMPLEMENT_STANDARD_RTTIEXT(BlockFix_PeriodicSurfaceModifier, BRepTools_Modification); //======================================================================= //function : BlockFix_PeriodicSurfaceModifier() //purpose : Constructor //======================================================================= - -BlockFix_PeriodicSurfaceModifier::BlockFix_PeriodicSurfaceModifier ( ) +BlockFix_PeriodicSurfaceModifier::BlockFix_PeriodicSurfaceModifier() { myMapOfFaces.Clear(); myMapOfSurfaces.Clear(); } +//======================================================================= +//function : ~BlockFix_PeriodicSurfaceModifier() +//purpose : Destructor +//======================================================================= +BlockFix_PeriodicSurfaceModifier::~BlockFix_PeriodicSurfaceModifier() +{ +} //======================================================================= //function : SetTolerance //purpose : //======================================================================= - void BlockFix_PeriodicSurfaceModifier::SetTolerance(const Standard_Real Tol) { myTolerance = Tol; } - //======================================================================= //function : ModifySurface //purpose : auxilary //======================================================================= - static Standard_Boolean ModifySurface(const TopoDS_Face& aFace, const Handle(Geom_Surface)& aSurface, Handle(Geom_Surface)& aNewSurface) @@ -102,12 +122,10 @@ static Standard_Boolean ModifySurface(const TopoDS_Face& aFace, return Standard_False; } - //======================================================================= //function : NewSurface //purpose : //======================================================================= - Standard_Boolean BlockFix_PeriodicSurfaceModifier::NewSurface(const TopoDS_Face& F, Handle(Geom_Surface)& S, TopLoc_Location& L,Standard_Real& Tol, @@ -133,12 +151,10 @@ Standard_Boolean BlockFix_PeriodicSurfaceModifier::NewSurface(const TopoDS_Face& return Standard_False; } - //======================================================================= //function : NewCurve //purpose : //======================================================================= - Standard_Boolean BlockFix_PeriodicSurfaceModifier::NewCurve(const TopoDS_Edge& /*E*/, Handle(Geom_Curve)& /*C*/, TopLoc_Location& /*L*/, @@ -147,12 +163,10 @@ Standard_Boolean BlockFix_PeriodicSurfaceModifier::NewCurve(const TopoDS_Edge& / return Standard_False; } - //======================================================================= //function : NewPoint //purpose : //======================================================================= - Standard_Boolean BlockFix_PeriodicSurfaceModifier::NewPoint(const TopoDS_Vertex& /*V*/, gp_Pnt& /*P*/, Standard_Real& /*Tol*/) @@ -160,12 +174,10 @@ Standard_Boolean BlockFix_PeriodicSurfaceModifier::NewPoint(const TopoDS_Vertex& return Standard_False; } - //======================================================================= //function : NewCurve2d //purpose : //======================================================================= - Standard_Boolean BlockFix_PeriodicSurfaceModifier::NewCurve2d(const TopoDS_Edge& E, const TopoDS_Face& F, const TopoDS_Edge& /*NewE*/, @@ -219,12 +231,10 @@ Standard_Boolean BlockFix_PeriodicSurfaceModifier::NewCurve2d(const TopoDS_Edge& return Standard_False; } - //======================================================================= //function : NewParameter //purpose : //======================================================================= - Standard_Boolean BlockFix_PeriodicSurfaceModifier::NewParameter(const TopoDS_Vertex& /*V*/, const TopoDS_Edge& /*E*/, Standard_Real& /*P*/, @@ -233,12 +243,10 @@ Standard_Boolean BlockFix_PeriodicSurfaceModifier::NewParameter(const TopoDS_Ver return Standard_False; } - //======================================================================= //function : Continuity //purpose : //======================================================================= - GeomAbs_Shape BlockFix_PeriodicSurfaceModifier::Continuity(const TopoDS_Edge& E, const TopoDS_Face& F1, const TopoDS_Face& F2, @@ -248,4 +256,3 @@ GeomAbs_Shape BlockFix_PeriodicSurfaceModifier::Continuity(const TopoDS_Edge& E, { return BRep_Tool::Continuity(E,F1,F2); } - diff --git a/src/BlockFix/BlockFix_PeriodicSurfaceModifier.hxx b/src/BlockFix/BlockFix_PeriodicSurfaceModifier.hxx new file mode 100644 index 000000000..0223b25e2 --- /dev/null +++ b/src/BlockFix/BlockFix_PeriodicSurfaceModifier.hxx @@ -0,0 +1,95 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com + +#ifndef _BlockFix_PeriodicSurfaceModifier_HeaderFile +#define _BlockFix_PeriodicSurfaceModifier_HeaderFile + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class TopoDS_Face; +class Geom_Surface; +class TopLoc_Location; +class TopoDS_Edge; +class Geom_Curve; +class TopoDS_Vertex; +class gp_Pnt; +class Geom2d_Curve; + +DEFINE_STANDARD_HANDLE(BlockFix_PeriodicSurfaceModifier, BRepTools_Modification); + +class BlockFix_PeriodicSurfaceModifier : public BRepTools_Modification { + +public: + Standard_EXPORT BlockFix_PeriodicSurfaceModifier(); + Standard_EXPORT ~BlockFix_PeriodicSurfaceModifier(); + + Standard_EXPORT void SetTolerance (const Standard_Real Toler) ; + Standard_EXPORT Standard_Boolean NewSurface (const TopoDS_Face& F, + Handle(Geom_Surface)& S, + TopLoc_Location& L, + Standard_Real& Tol, + Standard_Boolean& RevWires, + Standard_Boolean& RevFace); + Standard_EXPORT Standard_Boolean NewCurve (const TopoDS_Edge& E, + Handle(Geom_Curve)& C, + TopLoc_Location& L, + Standard_Real& Tol) ; + Standard_EXPORT Standard_Boolean NewPoint (const TopoDS_Vertex& V, gp_Pnt& P, Standard_Real& Tol); + Standard_EXPORT Standard_Boolean NewCurve2d (const TopoDS_Edge& E, + const TopoDS_Face& F, + const TopoDS_Edge& NewE, + const TopoDS_Face& NewF, + Handle(Geom2d_Curve)& C, + Standard_Real& Tol); + Standard_EXPORT Standard_Boolean NewParameter (const TopoDS_Vertex& V, + const TopoDS_Edge& E, + Standard_Real& P, + Standard_Real& Tol); + Standard_EXPORT GeomAbs_Shape Continuity (const TopoDS_Edge& E, + const TopoDS_Face& F1, + const TopoDS_Face& F2, + const TopoDS_Edge& NewE, + const TopoDS_Face& NewF1, + const TopoDS_Face& NewF2); + + DEFINE_STANDARD_RTTI(BlockFix_PeriodicSurfaceModifier); + +private: + Standard_Real myTolerance; + TopTools_DataMapOfShapeInteger myMapOfFaces; + TColStd_IndexedMapOfTransient myMapOfSurfaces; + +}; + +#endif diff --git a/src/GEOMAlgo/BlockFix_SphereSpaceModifier.cxx b/src/BlockFix/BlockFix_SphereSpaceModifier.cxx similarity index 94% rename from src/GEOMAlgo/BlockFix_SphereSpaceModifier.cxx rename to src/BlockFix/BlockFix_SphereSpaceModifier.cxx index 2abc08316..4a984cd45 100644 --- a/src/GEOMAlgo/BlockFix_SphereSpaceModifier.cxx +++ b/src/BlockFix/BlockFix_SphereSpaceModifier.cxx @@ -18,37 +18,50 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File: BlockFix.cxx // Created: Tue Dec 7 11:59:05 2004 // Author: Pavel DURANDIN -#include +#include + +#include + +#include + +#include #include + +#include +#include +#include +#include + #include +#include + +#include +#include + #include #include -#include -#include -#include -#include -#include -#include -#include -#include + #include +#include + #include -#include -#include +#include +#include + +IMPLEMENT_STANDARD_HANDLE(BlockFix_SphereSpaceModifier, BRepTools_Modification); +IMPLEMENT_STANDARD_RTTIEXT(BlockFix_SphereSpaceModifier, BRepTools_Modification); //======================================================================= //function : BlockFix_SphereSpaceModifier //purpose : //======================================================================= - BlockFix_SphereSpaceModifier::BlockFix_SphereSpaceModifier() { myMapOfFaces.Clear(); @@ -56,22 +69,24 @@ BlockFix_SphereSpaceModifier::BlockFix_SphereSpaceModifier() } //======================================================================= -//function : SetTolerance +//function : ~BlockFix_SphereSpaceModifier //purpose : //======================================================================= +BlockFix_SphereSpaceModifier::~BlockFix_SphereSpaceModifier() {} +//======================================================================= +//function : SetTolerance +//purpose : +//======================================================================= void BlockFix_SphereSpaceModifier::SetTolerance(const Standard_Real Tol) { myTolerance = Tol; } - //======================================================================= //function : NewSurface //purpose : //======================================================================= - - static Standard_Boolean ModifySurface(const TopoDS_Face& aFace, const Handle(Geom_Surface)& aSurface, Handle(Geom_Surface)& aNewSurface) @@ -132,7 +147,6 @@ static Standard_Boolean ModifySurface(const TopoDS_Face& aFace, return Standard_False; } - Standard_Boolean BlockFix_SphereSpaceModifier::NewSurface(const TopoDS_Face& F, Handle(Geom_Surface)& S, TopLoc_Location& L,Standard_Real& Tol, @@ -163,7 +177,6 @@ Standard_Boolean BlockFix_SphereSpaceModifier::NewSurface(const TopoDS_Face& F, //function : NewCurve //purpose : //======================================================================= - Standard_Boolean BlockFix_SphereSpaceModifier::NewCurve(const TopoDS_Edge& /*E*/,Handle(Geom_Curve)& /*C*/, TopLoc_Location& /*L*/,Standard_Real& /*Tol*/) { @@ -174,7 +187,6 @@ Standard_Boolean BlockFix_SphereSpaceModifier::NewCurve(const TopoDS_Edge& /*E*/ //function : NewPoint //purpose : //======================================================================= - Standard_Boolean BlockFix_SphereSpaceModifier::NewPoint(const TopoDS_Vertex& /*V*/, gp_Pnt& /*P*/, Standard_Real& /*Tol*/) @@ -186,7 +198,6 @@ Standard_Boolean BlockFix_SphereSpaceModifier::NewPoint(const TopoDS_Vertex& /*V //function : NewCurve2d //purpose : //======================================================================= - Standard_Boolean BlockFix_SphereSpaceModifier::NewCurve2d(const TopoDS_Edge& E,const TopoDS_Face& F, const TopoDS_Edge& /*NewE*/,const TopoDS_Face& /*NewF*/, Handle(Geom2d_Curve)& C,Standard_Real& Tol) @@ -249,24 +260,20 @@ Standard_Boolean BlockFix_SphereSpaceModifier::NewCurve2d(const TopoDS_Edge& E,c return Standard_False; } - //======================================================================= //function : NewParameter //purpose : //======================================================================= - Standard_Boolean BlockFix_SphereSpaceModifier::NewParameter(const TopoDS_Vertex& /*V*/,const TopoDS_Edge& /*E*/, Standard_Real& /*P*/,Standard_Real& /*Tol*/) { return Standard_False; } - //======================================================================= //function : Continuity //purpose : //======================================================================= - GeomAbs_Shape BlockFix_SphereSpaceModifier::Continuity(const TopoDS_Edge& E,const TopoDS_Face& F1, const TopoDS_Face& F2,const TopoDS_Edge& /*NewE*/, const TopoDS_Face& /*NewF1*/,const TopoDS_Face& /*NewF2*/) diff --git a/src/BlockFix/BlockFix_SphereSpaceModifier.hxx b/src/BlockFix/BlockFix_SphereSpaceModifier.hxx new file mode 100644 index 000000000..fa620b4e3 --- /dev/null +++ b/src/BlockFix/BlockFix_SphereSpaceModifier.hxx @@ -0,0 +1,82 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com + +#ifndef _BlockFix_SphereSpaceModifier_HeaderFile +#define _BlockFix_SphereSpaceModifier_HeaderFile + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class TopoDS_Face; +class Geom_Surface; +class TopLoc_Location; +class TopoDS_Edge; +class Geom_Curve; +class TopoDS_Vertex; +class gp_Pnt; +class Geom2d_Curve; + +DEFINE_STANDARD_HANDLE(BlockFix_SphereSpaceModifier, BRepTools_Modification); + +class BlockFix_SphereSpaceModifier : public BRepTools_Modification { + +public: + Standard_EXPORT BlockFix_SphereSpaceModifier(); + Standard_EXPORT ~BlockFix_SphereSpaceModifier(); + + Standard_EXPORT void SetTolerance (const Standard_Real Toler); + Standard_EXPORT Standard_Boolean NewSurface (const TopoDS_Face& F, Handle(Geom_Surface)& S, + TopLoc_Location& L, Standard_Real& Tol, + Standard_Boolean& RevWires, Standard_Boolean& RevFace); + Standard_EXPORT Standard_Boolean NewCurve (const TopoDS_Edge& E, Handle(Geom_Curve)& C, + TopLoc_Location& L, Standard_Real& Tol); + Standard_EXPORT Standard_Boolean NewPoint (const TopoDS_Vertex& V, gp_Pnt& P, Standard_Real& Tol); + Standard_EXPORT Standard_Boolean NewCurve2d (const TopoDS_Edge& E, const TopoDS_Face& F, + const TopoDS_Edge& NewE, const TopoDS_Face& NewF, + Handle(Geom2d_Curve)& C, Standard_Real& Tol); + Standard_EXPORT Standard_Boolean NewParameter (const TopoDS_Vertex& V, const TopoDS_Edge& E, + Standard_Real& P, Standard_Real& Tol); + Standard_EXPORT GeomAbs_Shape Continuity (const TopoDS_Edge& E, + const TopoDS_Face& F1,const TopoDS_Face& F2, + const TopoDS_Edge& NewE, + const TopoDS_Face& NewF1, const TopoDS_Face& NewF2); + Standard_EXPORT Standard_Boolean ForRotation (const TopoDS_Face& F); + + DEFINE_STANDARD_RTTI(BlockFix_SphereSpaceModifier); + +private: + Standard_Real myTolerance; + TopTools_DataMapOfShapeInteger myMapOfFaces; + TColStd_IndexedMapOfTransient myMapOfSpheres; + +}; + +#endif diff --git a/src/GEOMAlgo/BlockFix_UnionEdges.cxx b/src/BlockFix/BlockFix_UnionEdges.cxx similarity index 99% rename from src/GEOMAlgo/BlockFix_UnionEdges.cxx rename to src/BlockFix/BlockFix_UnionEdges.cxx index 95a1a713e..531d30a5a 100644 --- a/src/GEOMAlgo/BlockFix_UnionEdges.cxx +++ b/src/BlockFix/BlockFix_UnionEdges.cxx @@ -23,10 +23,12 @@ // Created: 07.12.04 15:27:30 // Author: Sergey KUUL -#include +#include #include +#include + #include #include #include @@ -57,6 +59,7 @@ #include #include #include +#include #include diff --git a/src/GEOMAlgo/BlockFix_UnionEdges.jxx b/src/BlockFix/BlockFix_UnionEdges.hxx similarity index 72% rename from src/GEOMAlgo/BlockFix_UnionEdges.jxx rename to src/BlockFix/BlockFix_UnionEdges.hxx index 558e8d82b..b63f5c7e2 100644 --- a/src/GEOMAlgo/BlockFix_UnionEdges.jxx +++ b/src/BlockFix/BlockFix_UnionEdges.hxx @@ -18,14 +18,30 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#ifndef _ShapeBuild_ReShape_HeaderFile -#include -#endif -#ifndef _TopoDS_Shape_HeaderFile -#include -#endif #ifndef _BlockFix_UnionEdges_HeaderFile -#include +#define _BlockFix_UnionEdges_HeaderFile + +#include + +#include + +#include +#include + +class TopoDS_Shape; + +class BlockFix_UnionEdges { + +public: + Standard_EXPORT BlockFix_UnionEdges(); + + Standard_EXPORT TopoDS_Shape Perform (const TopoDS_Shape& Shape,const Standard_Real Tol); + +private: + Standard_Real myTolerance; + Handle_ShapeBuild_ReShape myContext; + +}; + #endif diff --git a/src/GEOMAlgo/BlockFix_UnionFaces.cxx b/src/BlockFix/BlockFix_UnionFaces.cxx similarity index 99% rename from src/GEOMAlgo/BlockFix_UnionFaces.cxx rename to src/BlockFix/BlockFix_UnionFaces.cxx index c800fd421..aae28cab6 100644 --- a/src/GEOMAlgo/BlockFix_UnionFaces.cxx +++ b/src/BlockFix/BlockFix_UnionFaces.cxx @@ -18,13 +18,12 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File: BlockFix_UnionFaces.cxx // Created: Tue Dec 7 17:15:42 2004 // Author: Pavel DURANDIN -#include +#include #include @@ -73,6 +72,7 @@ #include #include #include +#include #include @@ -104,43 +104,37 @@ //function : BlockFix_UnionFaces //purpose : //======================================================================= - BlockFix_UnionFaces::BlockFix_UnionFaces() : myTolerance(Precision::Confusion()), myOptimumNbFaces(6) { } - //======================================================================= //function : GetTolerance //purpose : //======================================================================= - Standard_Real& BlockFix_UnionFaces::GetTolerance() { return myTolerance; } - //======================================================================= //function : GetOptimumNbFaces //purpose : //======================================================================= - Standard_Integer& BlockFix_UnionFaces::GetOptimumNbFaces() { return myOptimumNbFaces; } - //======================================================================= //function : AddOrdinaryEdges //purpose : auxilary +// adds edges from the shape to the sequence +// seams and equal edges are dropped +// Returns true if one of original edges dropped //======================================================================= -// adds edges from the shape to the sequence -// seams and equal edges are dropped -// Returns true if one of original edges dropped static Standard_Boolean AddOrdinaryEdges(TopTools_SequenceOfShape& edges, const TopoDS_Shape aShape, Standard_Integer& anIndex) @@ -180,7 +174,6 @@ static Standard_Boolean AddOrdinaryEdges(TopTools_SequenceOfShape& edges, return isDropped; } - //======================================================================= //function : ClearRts //purpose : auxilary @@ -195,12 +188,10 @@ static Handle(Geom_Surface) ClearRts(const Handle(Geom_Surface)& aSurface) return aSurface; } - //======================================================================= //function : Perform //purpose : //======================================================================= - TopoDS_Shape BlockFix_UnionFaces::Perform(const TopoDS_Shape& Shape) { Handle(ShapeBuild_ReShape) myContext = new ShapeBuild_ReShape; @@ -519,12 +510,10 @@ TopoDS_Shape BlockFix_UnionFaces::Perform(const TopoDS_Shape& Shape) return aResShape; } - //======================================================================= //function : IsSameDomain //purpose : //======================================================================= - bool getCylinder (Handle(Geom_Surface)& theInSurface, gp_Cylinder& theOutCylinder) { bool isCylinder = false; @@ -683,12 +672,10 @@ Standard_Boolean BlockFix_UnionFaces::IsSameDomain(const TopoDS_Face& aFace, return false; } - //======================================================================= //function : MovePCurves //purpose : //======================================================================= - void BlockFix_UnionFaces::MovePCurves(TopoDS_Face& aTarget, const TopoDS_Face& aSource) const { diff --git a/src/GEOMAlgo/BlockFix_UnionFaces.hxx b/src/BlockFix/BlockFix_UnionFaces.hxx similarity index 64% rename from src/GEOMAlgo/BlockFix_UnionFaces.hxx rename to src/BlockFix/BlockFix_UnionFaces.hxx index f676d5bcf..83140b08b 100644 --- a/src/GEOMAlgo/BlockFix_UnionFaces.hxx +++ b/src/BlockFix/BlockFix_UnionFaces.hxx @@ -18,23 +18,14 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #ifndef _BlockFix_UnionFaces_HeaderFile #define _BlockFix_UnionFaces_HeaderFile -#ifndef _Standard_Real_HeaderFile #include -#endif -#ifndef _Standard_Boolean_HeaderFile #include -#endif -#ifndef _Standard_HeaderFile #include -#endif -#ifndef _Standard_Macro_HeaderFile #include -#endif class TopoDS_Shape; class TopoDS_Face; @@ -42,24 +33,9 @@ class TopoDS_Face; class BlockFix_UnionFaces { public: - void* operator new(size_t,void* anAddress) - { - return anAddress; - } - void* operator new(size_t size) - { - return Standard::Allocate(size); - } - void operator delete(void *anAddress) - { - if (anAddress) Standard::Free((Standard_Address&)anAddress); - } - - // Methods PUBLIC - // Standard_EXPORT BlockFix_UnionFaces(); - Standard_EXPORT Standard_Real& GetTolerance(); + Standard_EXPORT Standard_Real& GetTolerance(); /* \brief To get/set the OptimumNbFaces parameter * @@ -71,18 +47,17 @@ public: * negative - do not perform any unions, regardless the faces quantity. * */ - Standard_EXPORT Standard_Integer& GetOptimumNbFaces(); + Standard_EXPORT Standard_Integer& GetOptimumNbFaces(); + + Standard_EXPORT TopoDS_Shape Perform(const TopoDS_Shape& Shape); - Standard_EXPORT TopoDS_Shape Perform(const TopoDS_Shape& Shape); + Standard_EXPORT virtual Standard_Boolean IsSameDomain(const TopoDS_Face& aFace, + const TopoDS_Face& aChekedFace) const; - Standard_EXPORT virtual Standard_Boolean IsSameDomain(const TopoDS_Face& aFace, - const TopoDS_Face& aChekedFace) const; - Standard_EXPORT virtual void MovePCurves(TopoDS_Face& aTarget, - const TopoDS_Face& aSource) const; + Standard_EXPORT virtual void MovePCurves(TopoDS_Face& aTarget, + const TopoDS_Face& aSource) const; private: - // Fields PRIVATE - // Standard_Real myTolerance; Standard_Integer myOptimumNbFaces; }; diff --git a/src/BlockFix/Makefile.am b/src/BlockFix/Makefile.am new file mode 100644 index 000000000..a3b37223d --- /dev/null +++ b/src/BlockFix/Makefile.am @@ -0,0 +1,55 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# 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. +# +# 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com + +# GEOM BlockFix : tools for Blocks algorithms +# File : Makefile.am +# Author : Julia DOROVSKIKH +# Module : GEOM + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +# Libraries targets +lib_LTLIBRARIES = libBlockFix.la + +dist_libBlockFix_la_SOURCES = \ + BlockFix_BlockFixAPI.cxx \ + BlockFix_CheckTool.cxx \ + BlockFix.cxx \ + BlockFix_PeriodicSurfaceModifier.cxx \ + BlockFix_SphereSpaceModifier.cxx \ + BlockFix_UnionEdges.cxx \ + BlockFix_UnionFaces.cxx + +# header files +salomeinclude_HEADERS = \ + BlockFix.hxx \ + BlockFix_BlockFixAPI.hxx \ + BlockFix_CheckTool.hxx \ + BlockFix_PeriodicSurfaceModifier.hxx \ + BlockFix_SphereSpaceModifier.hxx \ + BlockFix_UnionEdges.hxx \ + BlockFix_UnionFaces.hxx + +libBlockFix_la_CPPFLAGS = \ + $(CAS_CPPFLAGS) \ + $(KERNEL_CXXFLAGS) + +libBlockFix_la_LDFLAGS = \ + $(STDLIB) \ + $(CAS_LDPATH) -lTKBO -lTKShHealing -lTKBool -lTKMesh -lTKOffset \ + $(KERNEL_LDFLAGS) -lSALOMELocalTrace diff --git a/src/BlocksGUI/BlocksGUI_ExplodeDlg.cxx b/src/BlocksGUI/BlocksGUI_ExplodeDlg.cxx index a03687eab..c50811b82 100644 --- a/src/BlocksGUI/BlocksGUI_ExplodeDlg.cxx +++ b/src/BlocksGUI/BlocksGUI_ExplodeDlg.cxx @@ -509,7 +509,7 @@ GEOM::GEOM_Object_ptr BlocksGUI_ExplodeDlg::getFather( GEOM::GEOM_Object_ptr ) // Function : getNewObjectName // Purpose : Redefine this method to return proper name for a new object //================================================================ -QString BlocksGUI_ExplodeDlg::getNewObjectName() const +QString BlocksGUI_ExplodeDlg::getNewObjectName (int) const { return QString::null; } diff --git a/src/BlocksGUI/BlocksGUI_ExplodeDlg.h b/src/BlocksGUI/BlocksGUI_ExplodeDlg.h index 6be87bef4..1f396ccc5 100644 --- a/src/BlocksGUI/BlocksGUI_ExplodeDlg.h +++ b/src/BlocksGUI/BlocksGUI_ExplodeDlg.h @@ -50,7 +50,7 @@ protected: virtual bool execute( ObjectList& ); virtual GEOM::GEOM_Object_ptr getFather( GEOM::GEOM_Object_ptr ); - virtual QString getNewObjectName() const; + virtual QString getNewObjectName (int CurrObj = -1) const; private: void Init(); diff --git a/src/DisplayGUI/DisplayGUI.cxx b/src/DisplayGUI/DisplayGUI.cxx index 67665f66e..0dc9455d4 100644 --- a/src/DisplayGUI/DisplayGUI.cxx +++ b/src/DisplayGUI/DisplayGUI.cxx @@ -577,10 +577,10 @@ void DisplayGUI::ChangeDisplayMode( const int mode, SUIT_ViewWindow* viewWindow } } if(mode == 0 || mode == 1 || mode == 2) { - aStudy->setObjectProperty(mgrId,It.Value()->getEntry(),DISPLAY_MODE_PROP, mode); + aStudy->setObjectProperty(mgrId,It.Value()->getEntry(),GEOM::propertyName( GEOM::DisplayMode ), mode); } else if (mode == 4) { - aStudy->setObjectProperty(mgrId, It.Value()->getEntry(),VECTOR_MODE_PROP, vectorMode); + aStudy->setObjectProperty(mgrId, It.Value()->getEntry(),GEOM::propertyName( GEOM::EdgesDirection ), vectorMode); } } } @@ -625,10 +625,10 @@ void DisplayGUI::ChangeDisplayMode( const int mode, SUIT_ViewWindow* viewWindow } } if(mode == 0 || mode == 1 || mode == 2 || mode == 3) { - aStudy->setObjectProperty(mgrId, It.Value()->getEntry(),DISPLAY_MODE_PROP, mode); + aStudy->setObjectProperty(mgrId, It.Value()->getEntry(),GEOM::propertyName( GEOM::DisplayMode ), mode); } else if (mode == 4) { - aStudy->setObjectProperty(mgrId, It.Value()->getEntry(),VECTOR_MODE_PROP, vectorMode); + aStudy->setObjectProperty(mgrId, It.Value()->getEntry(),GEOM::propertyName( GEOM::EdgesDirection ), vectorMode); } } } diff --git a/src/DlgRef/DlgRef.cxx b/src/DlgRef/DlgRef.cxx index 164f483b4..a7a551f60 100644 --- a/src/DlgRef/DlgRef.cxx +++ b/src/DlgRef/DlgRef.cxx @@ -15,7 +15,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File : DlgRef.cxx // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) @@ -218,34 +217,6 @@ DlgRef_1Sel3Spin1Check::~DlgRef_1Sel3Spin1Check() { } -////////////////////////////////////////// -// DlgRef_1Sel4Spin2Check -////////////////////////////////////////// - -DlgRef_1Sel4Spin2Check::DlgRef_1Sel4Spin2Check( QWidget* parent, Qt::WindowFlags f ) -: QWidget( parent, f ) -{ - setupUi( this ); -} - -DlgRef_1Sel4Spin2Check::~DlgRef_1Sel4Spin2Check() -{ -} - -////////////////////////////////////////// -// DlgRef_1Sel4Spin -////////////////////////////////////////// - -DlgRef_1Sel4Spin::DlgRef_1Sel4Spin( QWidget* parent, Qt::WindowFlags f ) -: QWidget( parent, f ) -{ - setupUi( this ); -} - -DlgRef_1Sel4Spin::~DlgRef_1Sel4Spin() -{ -} - ////////////////////////////////////////// // DlgRef_1Sel5Spin1Check ////////////////////////////////////////// @@ -260,20 +231,6 @@ DlgRef_1Sel5Spin1Check::~DlgRef_1Sel5Spin1Check() { } -////////////////////////////////////////// -// DlgRef_1Sel5Spin -////////////////////////////////////////// - -DlgRef_1Sel5Spin::DlgRef_1Sel5Spin( QWidget* parent, Qt::WindowFlags f ) -: QWidget( parent, f ) -{ - setupUi( this ); -} - -DlgRef_1Sel5Spin::~DlgRef_1Sel5Spin() -{ -} - ////////////////////////////////////////// // DlgRef_1Spin ////////////////////////////////////////// @@ -526,20 +483,6 @@ DlgRef_2Sel3Spin::~DlgRef_2Sel3Spin() { } -////////////////////////////////////////// -// DlgRef_2Sel4Spin1Check -////////////////////////////////////////// - -DlgRef_2Sel4Spin1Check::DlgRef_2Sel4Spin1Check( QWidget* parent, Qt::WindowFlags f ) -: QWidget( parent, f ) -{ - setupUi( this ); -} - -DlgRef_2Sel4Spin1Check::~DlgRef_2Sel4Spin1Check() -{ -} - ////////////////////////////////////////// // DlgRef_2Sel ////////////////////////////////////////// diff --git a/src/DlgRef/DlgRef.h b/src/DlgRef/DlgRef.h index bda6da5b5..b727e96ec 100644 --- a/src/DlgRef/DlgRef.h +++ b/src/DlgRef/DlgRef.h @@ -15,7 +15,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File : DlgRef.h // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) @@ -259,38 +258,6 @@ public: ~DlgRef_1Sel3Spin1Check(); }; -////////////////////////////////////////// -// DlgRef_1Sel4Spin2Check -////////////////////////////////////////// - -#include "ui_DlgRef_1Sel4Spin2Check_QTD.h" - -class DLGREF_EXPORT DlgRef_1Sel4Spin2Check : public QWidget, - public Ui::DlgRef_1Sel4Spin2Check_QTD -{ - Q_OBJECT - -public: - DlgRef_1Sel4Spin2Check( QWidget* = 0, Qt::WindowFlags = 0 ); - ~DlgRef_1Sel4Spin2Check(); -}; - -////////////////////////////////////////// -// DlgRef_1Sel4Spin -////////////////////////////////////////// - -#include "ui_DlgRef_1Sel4Spin_QTD.h" - -class DLGREF_EXPORT DlgRef_1Sel4Spin : public QWidget, - public Ui::DlgRef_1Sel4Spin_QTD -{ - Q_OBJECT - -public: - DlgRef_1Sel4Spin( QWidget* = 0, Qt::WindowFlags = 0 ); - ~DlgRef_1Sel4Spin(); -}; - ////////////////////////////////////////// // DlgRef_1Sel5Spin1Check ////////////////////////////////////////// @@ -307,22 +274,6 @@ public: ~DlgRef_1Sel5Spin1Check(); }; -////////////////////////////////////////// -// DlgRef_1Sel5Spin -////////////////////////////////////////// - -#include "ui_DlgRef_1Sel5Spin_QTD.h" - -class DLGREF_EXPORT DlgRef_1Sel5Spin : public QWidget, - public Ui::DlgRef_1Sel5Spin_QTD -{ - Q_OBJECT - -public: - DlgRef_1Sel5Spin( QWidget* = 0, Qt::WindowFlags = 0 ); - ~DlgRef_1Sel5Spin(); -}; - ////////////////////////////////////////// // DlgRef_1Spin ////////////////////////////////////////// @@ -611,22 +562,6 @@ public: ~DlgRef_2Sel3Spin(); }; -////////////////////////////////////////// -// DlgRef_2Sel4Spin1Check -////////////////////////////////////////// - -#include "ui_DlgRef_2Sel4Spin1Check_QTD.h" - -class DLGREF_EXPORT DlgRef_2Sel4Spin1Check : public QWidget, - public Ui::DlgRef_2Sel4Spin1Check_QTD -{ - Q_OBJECT - -public: - DlgRef_2Sel4Spin1Check( QWidget* = 0, Qt::WindowFlags = 0 ); - ~DlgRef_2Sel4Spin1Check(); -}; - ////////////////////////////////////////// // DlgRef_2Sel ////////////////////////////////////////// diff --git a/src/DlgRef/DlgRef_1Sel4Spin2Check_QTD.ui b/src/DlgRef/DlgRef_1Sel4Spin2Check_QTD.ui deleted file mode 100644 index a6c6a6391..000000000 --- a/src/DlgRef/DlgRef_1Sel4Spin2Check_QTD.ui +++ /dev/null @@ -1,211 +0,0 @@ - - DlgRef_1Sel4Spin2Check_QTD - - - - 0 - 0 - 156 - 120 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - 6 - - - - - - - - - 9 - - - 9 - - - 9 - - - 9 - - - 6 - - - 6 - - - - - - 0 - 0 - - - - TL1 - - - false - - - - - - - - 0 - 0 - - - - - - - - - - - - - - - - 0 - 0 - - - - TL2 - - - false - - - - - - - - - - - - 0 - 0 - - - - TL3 - - - false - - - - - - - - - - - - 0 - 0 - - - - TL4 - - - false - - - - - - - - - - - - 0 - 0 - - - - TL5 - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - qPixmapFromMimeSource - - - SalomeApp_DoubleSpinBox - QDoubleSpinBox -
    SalomeApp_DoubleSpinBox.h
    -
    -
    - - PushButton1 - LineEdit1 - SpinBox_DX - SpinBox_DY - SpinBox_DZ - SpinBox_SC - CheckBox1 - CheckBox2 - - - -
    diff --git a/src/DlgRef/DlgRef_1Sel4Spin_QTD.ui b/src/DlgRef/DlgRef_1Sel4Spin_QTD.ui deleted file mode 100644 index 43cbcba2b..000000000 --- a/src/DlgRef/DlgRef_1Sel4Spin_QTD.ui +++ /dev/null @@ -1,214 +0,0 @@ - - DlgRef_1Sel4Spin_QTD - - - - 0 - 0 - 271 - 117 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - 6 - - - - - - - - - 9 - - - 9 - - - 9 - - - 9 - - - 6 - - - 6 - - - - - - 0 - 0 - - - - TL6 - - - false - - - - - - - - - - - - - - 6 - - - 9 - - - 9 - - - 9 - - - 9 - - - - - - 0 - 0 - - - - TL3 - - - false - - - - - - - - - - - 0 - 0 - - - - TL4 - - - false - - - - - - - - - - - 0 - 0 - - - - TL5 - - - false - - - - - - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - TL1 - - - false - - - - - - - - - - qPixmapFromMimeSource - - - SalomeApp_DoubleSpinBox - QDoubleSpinBox -
    SalomeApp_DoubleSpinBox.h
    -
    -
    - - PushButton1 - LineEdit1 - SpinBox_DX - SpinBox_DY - SpinBox_DZ - SpinBox_S - - - -
    diff --git a/src/DlgRef/DlgRef_1Sel5Spin_QTD.ui b/src/DlgRef/DlgRef_1Sel5Spin_QTD.ui deleted file mode 100644 index 1b945b5a8..000000000 --- a/src/DlgRef/DlgRef_1Sel5Spin_QTD.ui +++ /dev/null @@ -1,232 +0,0 @@ - - DlgRef_1Sel5Spin_QTD - - - - 0 - 0 - 174 - 123 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 9 - - - 9 - - - 9 - - - 9 - - - 6 - - - 6 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - 6 - - - - - - 0 - 0 - - - - TL4 - - - false - - - - - - - - 0 - 0 - - - - TL3 - - - false - - - - - - - - - - - 0 - 0 - - - - TL2 - - - false - - - - - - - - - - - 0 - 0 - - - - TL6 - - - false - - - - - - - - - - - - - - - - - 0 - 0 - - - - TL5 - - - false - - - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - TL1 - - - false - - - - - - - - - - - - - qPixmapFromMimeSource - - - SalomeApp_DoubleSpinBox - QDoubleSpinBox -
    SalomeApp_DoubleSpinBox.h
    -
    -
    - - PushButton1 - LineEdit1 - SpinBox1 - SpinBox2 - SpinBox4 - SpinBox5 - SpinBox3 - - - -
    diff --git a/src/DlgRef/DlgRef_2Sel4Spin1Check_QTD.ui b/src/DlgRef/DlgRef_2Sel4Spin1Check_QTD.ui deleted file mode 100644 index 5d0afce71..000000000 --- a/src/DlgRef/DlgRef_2Sel4Spin1Check_QTD.ui +++ /dev/null @@ -1,237 +0,0 @@ - - DlgRef_2Sel4Spin1Check_QTD - - - - 0 - 0 - 156 - 197 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 9 - - - 9 - - - 9 - - - 9 - - - 6 - - - 6 - - - - - - - - - - - - - - - - - - - - - - - - - 0 - 0 - - - - TL6 - - - false - - - - - - - - 0 - 0 - - - - TL5 - - - false - - - - - - - - 0 - 0 - - - - TL4 - - - false - - - - - - - - 0 - 0 - - - - TL3 - - - false - - - - - - - - 0 - 0 - - - - TL2 - - - false - - - - - - - - 0 - 0 - - - - - - - - - - - - - - - 0 - 0 - - - - TL1 - - - false - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - - - qPixmapFromMimeSource - - - SalomeApp_DoubleSpinBox - QDoubleSpinBox -
    SalomeApp_DoubleSpinBox.h
    -
    - - SalomeApp_IntSpinBox - QSpinBox -
    SalomeApp_IntSpinBox.h
    -
    -
    - - PushButton1 - LineEdit1 - PushButton2 - LineEdit2 - SpinBox_DX1 - SpinBox_DY1 - CheckButton1 - SpinBox_DX2 - SpinBox_DY2 - - - -
    diff --git a/src/DlgRef/Makefile.am b/src/DlgRef/Makefile.am index deaa27026..681636166 100644 --- a/src/DlgRef/Makefile.am +++ b/src/DlgRef/Makefile.am @@ -15,9 +15,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# GEOM DLGREF : # File : Makefile.am # Author : Alexander BORODIN, Open CASCADE S.A.S. (alexander.borodin@opencascade.com) # Package : DlgRef @@ -50,10 +48,7 @@ UIC_FILES = \ ui_DlgRef_1Sel3Spin_QTD.h \ ui_DlgRef_1Sel3Spin1Check_QTD.h \ ui_DlgRef_1Sel3Spin2Check1Spin_QTD.h \ - ui_DlgRef_1Sel4Spin2Check_QTD.h \ - ui_DlgRef_1Sel4Spin_QTD.h \ ui_DlgRef_1Sel5Spin1Check_QTD.h \ - ui_DlgRef_1Sel5Spin_QTD.h \ ui_DlgRef_1Sel_QTD.h \ ui_DlgRef_1SelExt_QTD.h \ ui_DlgRef_1Spin_QTD.h \ @@ -72,7 +67,6 @@ UIC_FILES = \ ui_DlgRef_2Sel2Spin2Push_QTD.h \ ui_DlgRef_2Sel3Spin2Rb_QTD.h \ ui_DlgRef_2Sel3Spin_QTD.h \ - ui_DlgRef_2Sel4Spin1Check_QTD.h \ ui_DlgRef_2Sel_QTD.h \ ui_DlgRef_2SelExt_QTD.h \ ui_DlgRef_2Spin_QTD.h \ diff --git a/src/EntityGUI/EntityGUI_SubShapeDlg.cxx b/src/EntityGUI/EntityGUI_SubShapeDlg.cxx index 5facd0411..3de5f8e89 100644 --- a/src/EntityGUI/EntityGUI_SubShapeDlg.cxx +++ b/src/EntityGUI/EntityGUI_SubShapeDlg.cxx @@ -831,7 +831,7 @@ GEOM::GEOM_Object_ptr EntityGUI_SubShapeDlg::getFather(GEOM::GEOM_Object_ptr) // Function : getNewObjectName // Purpose : //================================================================ -QString EntityGUI_SubShapeDlg::getNewObjectName() const +QString EntityGUI_SubShapeDlg::getNewObjectName (int) const { return QString::null; } diff --git a/src/EntityGUI/EntityGUI_SubShapeDlg.h b/src/EntityGUI/EntityGUI_SubShapeDlg.h index d9bf30a3f..816059e86 100644 --- a/src/EntityGUI/EntityGUI_SubShapeDlg.h +++ b/src/EntityGUI/EntityGUI_SubShapeDlg.h @@ -51,7 +51,7 @@ protected: virtual bool isValid (QString&); virtual bool execute (ObjectList&); virtual GEOM::GEOM_Object_ptr getFather (GEOM::GEOM_Object_ptr); - virtual QString getNewObjectName() const; + virtual QString getNewObjectName (int CurrObj = -1) const; void closeEvent (QCloseEvent*); diff --git a/src/GEOM/Makefile.am b/src/GEOM/Makefile.am index 68f248fb6..98fcfe532 100644 --- a/src/GEOM/Makefile.am +++ b/src/GEOM/Makefile.am @@ -21,7 +21,6 @@ # Author : Damien COQUERET (OCC) # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : GEOM -# $Header: include $(top_srcdir)/adm_local/unix/make_common_starter.am diff --git a/src/GEOMAlgo/BlockFix.cdl b/src/GEOMAlgo/BlockFix.cdl deleted file mode 100644 index 961af6625..000000000 --- a/src/GEOMAlgo/BlockFix.cdl +++ /dev/null @@ -1,67 +0,0 @@ --- Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE --- --- Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, --- CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS --- --- 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. --- --- 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com --- - --- File: BlockFix.cdl --- Created: Tue Dec 7 11:59:05 2004 --- Author: Pavel Durandin --- -package BlockFix - -uses - - TColStd, - gp, - Geom, - Geom2d, - GeomAbs, - TopLoc, - TopoDS, - BRepTools, - TopTools, - ShapeBuild - -is - - class SphereSpaceModifier; - - class UnionFaces; - - class UnionEdges; - - class BlockFixAPI; - ---Purpose: API class to perform the fixing of the - -- block - - class PeriodicSurfaceModifier; - - class CheckTool; - - RotateSphereSpace (S: Shape from TopoDS; Tol: Real) - returns Shape from TopoDS; - - FixRanges (S: Shape from TopoDS; Tol: Real) - returns Shape from TopoDS; - ---Purpose: checking and fixing cases where parametric - -- boundaries of face based on periodic surface are not - -- contained in the range of this surface. - -end BlockFix; diff --git a/src/GEOMAlgo/BlockFix.ixx b/src/GEOMAlgo/BlockFix.ixx deleted file mode 100644 index 2ea228ff7..000000000 --- a/src/GEOMAlgo/BlockFix.ixx +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include - - - - diff --git a/src/GEOMAlgo/BlockFix.jxx b/src/GEOMAlgo/BlockFix.jxx deleted file mode 100644 index 8649f8895..000000000 --- a/src/GEOMAlgo/BlockFix.jxx +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _TopoDS_Shape_HeaderFile -#include -#endif -#ifndef _BlockFix_HeaderFile -#include -#endif diff --git a/src/GEOMAlgo/BlockFix_BlockFixAPI.cdl b/src/GEOMAlgo/BlockFix_BlockFixAPI.cdl deleted file mode 100644 index 8cb4c49ce..000000000 --- a/src/GEOMAlgo/BlockFix_BlockFixAPI.cdl +++ /dev/null @@ -1,68 +0,0 @@ --- Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE --- --- Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, --- CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS --- --- 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. --- --- 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com --- - --- File: BlockFix_BlockFixAPI.cdl --- Created: Tue Dec 7 17:56:09 2004 --- Author: Pavel Durandin --- -class BlockFixAPI from BlockFix inherits TShared from MMgt - - ---Purpose: - -uses - - Shape from TopoDS, - ReShape from ShapeBuild - -is - Create returns BlockFixAPI from BlockFix; - ---Purpose: Empty constructor - - SetShape(me: mutable; Shape: Shape from TopoDS); - ---Purpose: Sets the shape to be operated on - ---C++: inline - - Perform(me: mutable); - ---Purpose: - - Shape(me) returns Shape from TopoDS; - ---Purpose: Returns resulting shape. - ---C++: inline - - Context(me:mutable) returns ReShape from ShapeBuild; - ---Purpose: Returns modifiable context for storing the - -- mofifications - ---C++: inline - ---C++: return & - - Tolerance (me:mutable) returns Real; - ---Purpose: Returns modifiable tolerance of recognition - ---C++: inline - ---C++: return & - -fields - - myContext : ReShape from ShapeBuild; - myShape : Shape from TopoDS; - myTolerance : Real from Standard; - -end BlockFixAPI from BlockFix; diff --git a/src/GEOMAlgo/BlockFix_BlockFixAPI.hxx b/src/GEOMAlgo/BlockFix_BlockFixAPI.hxx deleted file mode 100644 index 7be25cc57..000000000 --- a/src/GEOMAlgo/BlockFix_BlockFixAPI.hxx +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _BlockFix_BlockFixAPI_HeaderFile -#define _BlockFix_BlockFixAPI_HeaderFile - -#ifndef _Standard_HeaderFile -#include -#endif -#ifndef _Handle_BlockFix_BlockFixAPI_HeaderFile -#include -#endif - -#ifndef _Handle_ShapeBuild_ReShape_HeaderFile -#include -#endif -#ifndef _TopoDS_Shape_HeaderFile -#include -#endif -#ifndef _Standard_Real_HeaderFile -#include -#endif -#ifndef _MMgt_TShared_HeaderFile -#include -#endif - -class ShapeBuild_ReShape; -class TopoDS_Shape; - - -class BlockFix_BlockFixAPI : public MMgt_TShared -{ -public: - void* operator new(size_t,void* anAddress) - { - return anAddress; - } - void* operator new(size_t size) - { - return Standard::Allocate(size); - } - void operator delete(void *anAddress) - { - if (anAddress) Standard::Free((Standard_Address&)anAddress); - } - - // Methods PUBLIC - // - Standard_EXPORT BlockFix_BlockFixAPI(); - void SetShape(const TopoDS_Shape& Shape); - Standard_EXPORT void Perform(); - TopoDS_Shape Shape() const; - Handle_ShapeBuild_ReShape& Context(); - Standard_Real& Tolerance(); - Standard_Integer& OptimumNbFaces(); - Standard_EXPORT ~BlockFix_BlockFixAPI(); - - // Type management - // - Standard_EXPORT friend Handle_Standard_Type& BlockFix_BlockFixAPI_Type_(); - Standard_EXPORT const Handle(Standard_Type)& DynamicType() const; - Standard_EXPORT Standard_Boolean IsKind(const Handle(Standard_Type)&) const; - -private: - // Fields PRIVATE - // - Handle_ShapeBuild_ReShape myContext; - TopoDS_Shape myShape; - Standard_Real myTolerance; - Standard_Integer myOptimumNbFaces; -}; - -#include - -#endif diff --git a/src/GEOMAlgo/BlockFix_BlockFixAPI.ixx b/src/GEOMAlgo/BlockFix_BlockFixAPI.ixx deleted file mode 100644 index 4d06a875e..000000000 --- a/src/GEOMAlgo/BlockFix_BlockFixAPI.ixx +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include - -#ifndef _Standard_TypeMismatch_HeaderFile -#include -#endif - -BlockFix_BlockFixAPI::~BlockFix_BlockFixAPI() {} - - - -Standard_EXPORT Handle_Standard_Type& BlockFix_BlockFixAPI_Type_() -{ - - static Handle_Standard_Type aType1 = STANDARD_TYPE(MMgt_TShared); - if ( aType1.IsNull()) aType1 = STANDARD_TYPE(MMgt_TShared); - static Handle_Standard_Type aType2 = STANDARD_TYPE(Standard_Transient); - if ( aType2.IsNull()) aType2 = STANDARD_TYPE(Standard_Transient); - - - static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,NULL}; - static Handle_Standard_Type _aType = new Standard_Type("BlockFix_BlockFixAPI", - sizeof(BlockFix_BlockFixAPI), - 1, - (Standard_Address)_Ancestors, - (Standard_Address)NULL); - - return _aType; -} - - -// DownCast method -// allow safe downcasting -// -const Handle(BlockFix_BlockFixAPI) Handle(BlockFix_BlockFixAPI)::DownCast(const Handle(Standard_Transient)& AnObject) -{ - Handle(BlockFix_BlockFixAPI) _anOtherObject; - - if (!AnObject.IsNull()) { - if (AnObject->IsKind(STANDARD_TYPE(BlockFix_BlockFixAPI))) { - _anOtherObject = Handle(BlockFix_BlockFixAPI)((Handle(BlockFix_BlockFixAPI)&)AnObject); - } - } - - return _anOtherObject ; -} -const Handle(Standard_Type)& BlockFix_BlockFixAPI::DynamicType() const -{ - return STANDARD_TYPE(BlockFix_BlockFixAPI) ; -} -Standard_Boolean BlockFix_BlockFixAPI::IsKind(const Handle(Standard_Type)& AType) const -{ - return (STANDARD_TYPE(BlockFix_BlockFixAPI) == AType || MMgt_TShared::IsKind(AType)); -} -Handle_BlockFix_BlockFixAPI::~Handle_BlockFix_BlockFixAPI() {} - diff --git a/src/GEOMAlgo/BlockFix_BlockFixAPI.jxx b/src/GEOMAlgo/BlockFix_BlockFixAPI.jxx deleted file mode 100644 index 945a6ed88..000000000 --- a/src/GEOMAlgo/BlockFix_BlockFixAPI.jxx +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _ShapeBuild_ReShape_HeaderFile -#include -#endif -#ifndef _TopoDS_Shape_HeaderFile -#include -#endif -#ifndef _BlockFix_BlockFixAPI_HeaderFile -#include -#endif diff --git a/src/GEOMAlgo/BlockFix_CheckTool.cdl b/src/GEOMAlgo/BlockFix_CheckTool.cdl deleted file mode 100644 index c5423377f..000000000 --- a/src/GEOMAlgo/BlockFix_CheckTool.cdl +++ /dev/null @@ -1,67 +0,0 @@ --- Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE --- --- Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, --- CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS --- --- 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. --- --- 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com --- - --- File: BlockFix_CheckTool.cdl --- Created: Fri Dec 17 10:36:58 2004 --- Author: Sergey KUUL --- -class CheckTool from BlockFix - - ---Purpose: - -uses - - Shape from TopoDS, - SequenceOfShape from TopTools - -is - - Create returns CheckTool from BlockFix; - ---Purpose: Empty constructor - - SetShape(me: in out; aShape: Shape from TopoDS); - - Perform(me: in out); - ---Purpose: - - NbPossibleBlocks(me) returns Integer; - - PossibleBlock(me; num: Integer) returns Shape from TopoDS; - - DumpCheckResult(me; S : in out OStream); - ---Purpose: Dumps results of checking - - -fields - - myShape : Shape from TopoDS; - myHasCheck : Boolean; - myNbSolids : Integer; - myNbBlocks : Integer; - myPossibleBlocks : SequenceOfShape from TopTools; - myNbDegen : Integer; - myNbUF : Integer; - myNbUE : Integer; - myNbUFUE : Integer; - myBadRanges : Integer; - -end CheckTool; diff --git a/src/GEOMAlgo/BlockFix_CheckTool.hxx b/src/GEOMAlgo/BlockFix_CheckTool.hxx deleted file mode 100644 index 652319e42..000000000 --- a/src/GEOMAlgo/BlockFix_CheckTool.hxx +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _BlockFix_CheckTool_HeaderFile -#define _BlockFix_CheckTool_HeaderFile - -#ifndef _TopoDS_Shape_HeaderFile -#include -#endif -#ifndef _Standard_Boolean_HeaderFile -#include -#endif -#ifndef _Standard_Integer_HeaderFile -#include -#endif -#ifndef _TopTools_SequenceOfShape_HeaderFile -#include -#endif -#ifndef _Standard_OStream_HeaderFile -#include -#endif -class TopoDS_Shape; - - -#ifndef _Standard_HeaderFile -#include -#endif -#ifndef _Standard_Macro_HeaderFile -#include -#endif - -class BlockFix_CheckTool { - -public: - - void* operator new(size_t,void* anAddress) - { - return anAddress; - } - void* operator new(size_t size) - { - return Standard::Allocate(size); - } - void operator delete(void *anAddress) - { - if (anAddress) Standard::Free((Standard_Address&)anAddress); - } - // Methods PUBLIC - // -Standard_EXPORT BlockFix_CheckTool(); -Standard_EXPORT void SetShape(const TopoDS_Shape& aShape) ; -Standard_EXPORT void Perform() ; -Standard_EXPORT Standard_Integer NbPossibleBlocks() const; -Standard_EXPORT TopoDS_Shape PossibleBlock(const Standard_Integer num) const; -Standard_EXPORT void DumpCheckResult(Standard_OStream& S) const; - - - - - -protected: - - // Methods PROTECTED - // - - - // Fields PROTECTED - // - - -private: - - // Methods PRIVATE - // - - - // Fields PRIVATE - // -TopoDS_Shape myShape; -Standard_Boolean myHasCheck; -Standard_Integer myNbSolids; -Standard_Integer myNbBlocks; -TopTools_SequenceOfShape myPossibleBlocks; -Standard_Integer myNbDegen; -Standard_Integer myNbUF; -Standard_Integer myNbUE; -Standard_Integer myNbUFUE; -Standard_Integer myBadRanges; - - -}; - - - - - -// other Inline functions and methods (like "C++: function call" methods) -// - - -#endif diff --git a/src/GEOMAlgo/BlockFix_CheckTool.ixx b/src/GEOMAlgo/BlockFix_CheckTool.ixx deleted file mode 100644 index d44f98056..000000000 --- a/src/GEOMAlgo/BlockFix_CheckTool.ixx +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include - - - - diff --git a/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.cdl b/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.cdl deleted file mode 100644 index 374af919c..000000000 --- a/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.cdl +++ /dev/null @@ -1,135 +0,0 @@ --- Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE --- --- Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, --- CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS --- --- 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. --- --- 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com --- - --- File: BlockFix_PeriodicSurfaceModifier.cdl --- Created: Wed Dec 15 10:03:50 2004 --- Author: Sergey KUUL --- -class PeriodicSurfaceModifier from BlockFix inherits Modification from BRepTools - - ---Purpose: - -uses - Vertex from TopoDS, - Edge from TopoDS, - Face from TopoDS, - Location from TopLoc, - Shape from GeomAbs, - Pnt from gp, - Curve from Geom, - Curve from Geom2d, - Surface from Geom, - IndexedMapOfTransient from TColStd, - DataMapOfShapeInteger from TopTools - -is - - Create returns mutable PeriodicSurfaceModifier from BlockFix; - - SetTolerance(me: mutable; Toler: Real); - ---Purpose: Sets the tolerance for recognition of geometry - - NewSurface(me: mutable; F : Face from TopoDS; - S : out Surface from Geom; - L : out Location from TopLoc; - Tol: out Real from Standard; - RevWires : out Boolean from Standard; - RevFace : out Boolean from Standard) - returns Boolean from Standard; - ---Purpose: Returns Standard_True if the face has been - -- modified. In this case, is the new geometric - -- support of the face, the new location, - -- the new tolerance. Otherwise, returns - -- Standard_False, and , , are not - -- significant. - - NewCurve(me: mutable; E : Edge from TopoDS; - C : out Curve from Geom; - L : out Location from TopLoc; - Tol: out Real from Standard) - returns Boolean from Standard; - ---Purpose: Returns Standard_True if the edge has been - -- modified. In this case, is the new geometric - -- support of the edge, the new location, - -- the new tolerance. Otherwise, returns - -- Standard_False, and , , are not - -- significant. - - NewPoint(me: mutable; V : Vertex from TopoDS; - P : out Pnt from gp; - Tol: out Real from Standard) - returns Boolean from Standard; - ---Purpose: Returns Standard_True if the vertex has been - -- modified. In this case,

    is the new geometric - -- support of the vertex, the new tolerance. - -- Otherwise, returns Standard_False, and

    , - -- are not significant. - - NewCurve2d(me: mutable; E : Edge from TopoDS; - F : Face from TopoDS; - NewE : Edge from TopoDS; - NewF : Face from TopoDS; - C : out Curve from Geom2d; - Tol : out Real from Standard) - returns Boolean from Standard; - ---Purpose: Returns Standard_True if the edge has a new - -- curve on surface on the face .In this case, - -- is the new geometric support of the edge, the - -- new location, the new tolerance. - -- - -- Otherwise, returns Standard_False, and , , - -- are not significant. - -- - -- is the new edge created from . - -- is the new face created from . They may be usefull. - - NewParameter(me: mutable; V : Vertex from TopoDS; - E : Edge from TopoDS; - P : out Real from Standard; - Tol: out Real from Standard) - returns Boolean from Standard; - ---Purpose: Returns Standard_True if the Vertex has a new - -- parameter on the edge . In this case,

    is - -- the parameter, the new tolerance. - -- Otherwise, returns Standard_False, and

    , - -- are not significant. - - Continuity(me: mutable; E : Edge from TopoDS; - F1,F2 : Face from TopoDS; - NewE : Edge from TopoDS; - NewF1,NewF2: Face from TopoDS) - returns Shape from GeomAbs; - ---Purpose: Returns the continuity of between - -- and . - -- - -- is the new edge created from . - -- (resp. ) is the new face created from - -- (resp. ). - - -fields - - myTolerance : Real; - myMapOfFaces : DataMapOfShapeInteger from TopTools; - myMapOfSurfaces: IndexedMapOfTransient from TColStd; - -end PeriodicSurfaceModifier; diff --git a/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.hxx b/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.hxx deleted file mode 100644 index 39d2062ea..000000000 --- a/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.hxx +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _BlockFix_PeriodicSurfaceModifier_HeaderFile -#define _BlockFix_PeriodicSurfaceModifier_HeaderFile - -#ifndef _Standard_HeaderFile -#include -#endif -#ifndef _Handle_BlockFix_PeriodicSurfaceModifier_HeaderFile -#include -#endif - -#ifndef _Standard_Real_HeaderFile -#include -#endif -#ifndef _TopTools_DataMapOfShapeInteger_HeaderFile -#include -#endif -#ifndef _TColStd_IndexedMapOfTransient_HeaderFile -#include -#endif -#ifndef _BRepTools_Modification_HeaderFile -#include -#endif -#ifndef _Standard_Boolean_HeaderFile -#include -#endif -#ifndef _Handle_Geom_Surface_HeaderFile -#include -#endif -#ifndef _Handle_Geom_Curve_HeaderFile -#include -#endif -#ifndef _Handle_Geom2d_Curve_HeaderFile -#include -#endif -#ifndef _GeomAbs_Shape_HeaderFile -#include -#endif -class TopoDS_Face; -class Geom_Surface; -class TopLoc_Location; -class TopoDS_Edge; -class Geom_Curve; -class TopoDS_Vertex; -class gp_Pnt; -class Geom2d_Curve; - - -class BlockFix_PeriodicSurfaceModifier : public BRepTools_Modification { - -public: - - void* operator new(size_t,void* anAddress) - { - return anAddress; - } - void* operator new(size_t size) - { - return Standard::Allocate(size); - } - void operator delete(void *anAddress) - { - if (anAddress) Standard::Free((Standard_Address&)anAddress); - } - // Methods PUBLIC - // -Standard_EXPORT BlockFix_PeriodicSurfaceModifier(); -Standard_EXPORT void SetTolerance(const Standard_Real Toler) ; -Standard_EXPORT Standard_Boolean NewSurface(const TopoDS_Face& F,Handle(Geom_Surface)& S,TopLoc_Location& L,Standard_Real& Tol,Standard_Boolean& RevWires,Standard_Boolean& RevFace) ; -Standard_EXPORT Standard_Boolean NewCurve(const TopoDS_Edge& E,Handle(Geom_Curve)& C,TopLoc_Location& L,Standard_Real& Tol) ; -Standard_EXPORT Standard_Boolean NewPoint(const TopoDS_Vertex& V,gp_Pnt& P,Standard_Real& Tol) ; -Standard_EXPORT Standard_Boolean NewCurve2d(const TopoDS_Edge& E,const TopoDS_Face& F,const TopoDS_Edge& NewE,const TopoDS_Face& NewF,Handle(Geom2d_Curve)& C,Standard_Real& Tol) ; -Standard_EXPORT Standard_Boolean NewParameter(const TopoDS_Vertex& V,const TopoDS_Edge& E,Standard_Real& P,Standard_Real& Tol) ; -Standard_EXPORT GeomAbs_Shape Continuity(const TopoDS_Edge& E,const TopoDS_Face& F1,const TopoDS_Face& F2,const TopoDS_Edge& NewE,const TopoDS_Face& NewF1,const TopoDS_Face& NewF2) ; -Standard_EXPORT ~BlockFix_PeriodicSurfaceModifier(); - - - - - // Type management - // - Standard_EXPORT friend Handle_Standard_Type& BlockFix_PeriodicSurfaceModifier_Type_(); - Standard_EXPORT const Handle(Standard_Type)& DynamicType() const; - Standard_EXPORT Standard_Boolean IsKind(const Handle(Standard_Type)&) const; - -protected: - - // Methods PROTECTED - // - - - // Fields PROTECTED - // - - -private: - - // Methods PRIVATE - // - - - // Fields PRIVATE - // -Standard_Real myTolerance; -TopTools_DataMapOfShapeInteger myMapOfFaces; -TColStd_IndexedMapOfTransient myMapOfSurfaces; - - -}; - - - - - -// other Inline functions and methods (like "C++: function call" methods) -// - - -#endif diff --git a/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.ixx b/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.ixx deleted file mode 100644 index da3bdc95e..000000000 --- a/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.ixx +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include - -#ifndef _Standard_TypeMismatch_HeaderFile -#include -#endif - -BlockFix_PeriodicSurfaceModifier::~BlockFix_PeriodicSurfaceModifier() {} - - - -Standard_EXPORT Handle_Standard_Type& BlockFix_PeriodicSurfaceModifier_Type_() -{ - - static Handle_Standard_Type aType1 = STANDARD_TYPE(BRepTools_Modification); - if ( aType1.IsNull()) aType1 = STANDARD_TYPE(BRepTools_Modification); - static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared); - if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared); - static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient); - if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient); - - - static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL}; - static Handle_Standard_Type _aType = new Standard_Type("BlockFix_PeriodicSurfaceModifier", - sizeof(BlockFix_PeriodicSurfaceModifier), - 1, - (Standard_Address)_Ancestors, - (Standard_Address)NULL); - - return _aType; -} - - -// DownCast method -// allow safe downcasting -// -const Handle(BlockFix_PeriodicSurfaceModifier) Handle(BlockFix_PeriodicSurfaceModifier)::DownCast(const Handle(Standard_Transient)& AnObject) -{ - Handle(BlockFix_PeriodicSurfaceModifier) _anOtherObject; - - if (!AnObject.IsNull()) { - if (AnObject->IsKind(STANDARD_TYPE(BlockFix_PeriodicSurfaceModifier))) { - _anOtherObject = Handle(BlockFix_PeriodicSurfaceModifier)((Handle(BlockFix_PeriodicSurfaceModifier)&)AnObject); - } - } - - return _anOtherObject ; -} -const Handle(Standard_Type)& BlockFix_PeriodicSurfaceModifier::DynamicType() const -{ - return STANDARD_TYPE(BlockFix_PeriodicSurfaceModifier) ; -} -Standard_Boolean BlockFix_PeriodicSurfaceModifier::IsKind(const Handle(Standard_Type)& AType) const -{ - return (STANDARD_TYPE(BlockFix_PeriodicSurfaceModifier) == AType || BRepTools_Modification::IsKind(AType)); -} -Handle_BlockFix_PeriodicSurfaceModifier::~Handle_BlockFix_PeriodicSurfaceModifier() {} - diff --git a/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.jxx b/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.jxx deleted file mode 100644 index 29c1c1e34..000000000 --- a/src/GEOMAlgo/BlockFix_PeriodicSurfaceModifier.jxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _TopoDS_Face_HeaderFile -#include -#endif -#ifndef _Geom_Surface_HeaderFile -#include -#endif -#ifndef _TopLoc_Location_HeaderFile -#include -#endif -#ifndef _TopoDS_Edge_HeaderFile -#include -#endif -#ifndef _Geom_Curve_HeaderFile -#include -#endif -#ifndef _TopoDS_Vertex_HeaderFile -#include -#endif -#ifndef _gp_Pnt_HeaderFile -#include -#endif -#ifndef _Geom2d_Curve_HeaderFile -#include -#endif -#ifndef _BlockFix_PeriodicSurfaceModifier_HeaderFile -#include -#endif diff --git a/src/GEOMAlgo/BlockFix_SphereSpaceModifier.cdl b/src/GEOMAlgo/BlockFix_SphereSpaceModifier.cdl deleted file mode 100644 index da614611b..000000000 --- a/src/GEOMAlgo/BlockFix_SphereSpaceModifier.cdl +++ /dev/null @@ -1,139 +0,0 @@ --- Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE --- --- Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, --- CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS --- --- 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. --- --- 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com --- - --- File: BlockFix_SphereSpaceModifier.cdl --- Created: Tue Dec 7 12:01:49 2004 --- Author: Pavel Durandin --- -class SphereSpaceModifier from BlockFix inherits Modification from BRepTools - - ---Purpose: Rotation of the parametric space of the sphere in order - -- to avoid the seam and degenerared edge within it - -uses - Vertex from TopoDS, - Edge from TopoDS, - Face from TopoDS, - Location from TopLoc, - Shape from GeomAbs, - Pnt from gp, - Curve from Geom, - Curve from Geom2d, - Surface from Geom, - IndexedMapOfTransient from TColStd, - DataMapOfShapeInteger from TopTools - -is - - Create returns mutable SphereSpaceModifier from BlockFix; - - SetTolerance(me: mutable; Toler: Real); - ---Purpose: Sets the tolerance for recognition of geometry - - NewSurface(me: mutable; F : Face from TopoDS; - S : out Surface from Geom; - L : out Location from TopLoc; - Tol: out Real from Standard; - RevWires : out Boolean from Standard; - RevFace : out Boolean from Standard) - returns Boolean from Standard; - ---Purpose: Returns Standard_True if the face has been - -- modified. In this case, is the new geometric - -- support of the face, the new location, - -- the new tolerance. Otherwise, returns - -- Standard_False, and , , are not - -- significant. - - NewCurve(me: mutable; E : Edge from TopoDS; - C : out Curve from Geom; - L : out Location from TopLoc; - Tol: out Real from Standard) - returns Boolean from Standard; - ---Purpose: Returns Standard_True if the edge has been - -- modified. In this case, is the new geometric - -- support of the edge, the new location, - -- the new tolerance. Otherwise, returns - -- Standard_False, and , , are not - -- significant. - - NewPoint(me: mutable; V : Vertex from TopoDS; - P : out Pnt from gp; - Tol: out Real from Standard) - returns Boolean from Standard; - ---Purpose: Returns Standard_True if the vertex has been - -- modified. In this case,

    is the new geometric - -- support of the vertex, the new tolerance. - -- Otherwise, returns Standard_False, and

    , - -- are not significant. - - NewCurve2d(me: mutable; E : Edge from TopoDS; - F : Face from TopoDS; - NewE : Edge from TopoDS; - NewF : Face from TopoDS; - C : out Curve from Geom2d; - Tol : out Real from Standard) - returns Boolean from Standard; - ---Purpose: Returns Standard_True if the edge has a new - -- curve on surface on the face .In this case, - -- is the new geometric support of the edge, the - -- new location, the new tolerance. - -- - -- Otherwise, returns Standard_False, and , , - -- are not significant. - -- - -- is the new edge created from . - -- is the new face created from . They may be usefull. - - NewParameter(me: mutable; V : Vertex from TopoDS; - E : Edge from TopoDS; - P : out Real from Standard; - Tol: out Real from Standard) - returns Boolean from Standard; - ---Purpose: Returns Standard_True if the Vertex has a new - -- parameter on the edge . In this case,

    is - -- the parameter, the new tolerance. - -- Otherwise, returns Standard_False, and

    , - -- are not significant. - - Continuity(me: mutable; E : Edge from TopoDS; - F1,F2 : Face from TopoDS; - NewE : Edge from TopoDS; - NewF1,NewF2: Face from TopoDS) - returns Shape from GeomAbs; - ---Purpose: Returns the continuity of between - -- and . - -- - -- is the new edge created from . - -- (resp. ) is the new face created from - -- (resp. ). - - ForRotation(me: mutable; F: Face from TopoDS) returns Boolean; - -fields - - myTolerance : Real; - myMapOfFaces : DataMapOfShapeInteger from TopTools; - myMapOfSpheres: IndexedMapOfTransient from TColStd; - --myMapOfGeom: MapOfShapeTransient from TColStd; - -end SphereSpaceModifier; - diff --git a/src/GEOMAlgo/BlockFix_SphereSpaceModifier.hxx b/src/GEOMAlgo/BlockFix_SphereSpaceModifier.hxx deleted file mode 100644 index fb11fdbae..000000000 --- a/src/GEOMAlgo/BlockFix_SphereSpaceModifier.hxx +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _BlockFix_SphereSpaceModifier_HeaderFile -#define _BlockFix_SphereSpaceModifier_HeaderFile - -#ifndef _Standard_HeaderFile -#include -#endif -#ifndef _Handle_BlockFix_SphereSpaceModifier_HeaderFile -#include -#endif - -#ifndef _Standard_Real_HeaderFile -#include -#endif -#ifndef _TopTools_DataMapOfShapeInteger_HeaderFile -#include -#endif -#ifndef _TColStd_IndexedMapOfTransient_HeaderFile -#include -#endif -#ifndef _BRepTools_Modification_HeaderFile -#include -#endif -#ifndef _Standard_Boolean_HeaderFile -#include -#endif -#ifndef _Handle_Geom_Surface_HeaderFile -#include -#endif -#ifndef _Handle_Geom_Curve_HeaderFile -#include -#endif -#ifndef _Handle_Geom2d_Curve_HeaderFile -#include -#endif -#ifndef _GeomAbs_Shape_HeaderFile -#include -#endif -class TopoDS_Face; -class Geom_Surface; -class TopLoc_Location; -class TopoDS_Edge; -class Geom_Curve; -class TopoDS_Vertex; -class gp_Pnt; -class Geom2d_Curve; - - -class BlockFix_SphereSpaceModifier : public BRepTools_Modification { - -public: - - void* operator new(size_t,void* anAddress) - { - return anAddress; - } - void* operator new(size_t size) - { - return Standard::Allocate(size); - } - void operator delete(void *anAddress) - { - if (anAddress) Standard::Free((Standard_Address&)anAddress); - } - // Methods PUBLIC - // -Standard_EXPORT BlockFix_SphereSpaceModifier(); -Standard_EXPORT void SetTolerance(const Standard_Real Toler) ; -Standard_EXPORT Standard_Boolean NewSurface(const TopoDS_Face& F,Handle(Geom_Surface)& S,TopLoc_Location& L,Standard_Real& Tol,Standard_Boolean& RevWires,Standard_Boolean& RevFace) ; -Standard_EXPORT Standard_Boolean NewCurve(const TopoDS_Edge& E,Handle(Geom_Curve)& C,TopLoc_Location& L,Standard_Real& Tol) ; -Standard_EXPORT Standard_Boolean NewPoint(const TopoDS_Vertex& V,gp_Pnt& P,Standard_Real& Tol) ; -Standard_EXPORT Standard_Boolean NewCurve2d(const TopoDS_Edge& E,const TopoDS_Face& F,const TopoDS_Edge& NewE,const TopoDS_Face& NewF,Handle(Geom2d_Curve)& C,Standard_Real& Tol) ; -Standard_EXPORT Standard_Boolean NewParameter(const TopoDS_Vertex& V,const TopoDS_Edge& E,Standard_Real& P,Standard_Real& Tol) ; -Standard_EXPORT GeomAbs_Shape Continuity(const TopoDS_Edge& E,const TopoDS_Face& F1,const TopoDS_Face& F2,const TopoDS_Edge& NewE,const TopoDS_Face& NewF1,const TopoDS_Face& NewF2) ; -Standard_EXPORT Standard_Boolean ForRotation(const TopoDS_Face& F) ; -Standard_EXPORT ~BlockFix_SphereSpaceModifier(); - - - - - // Type management - // - Standard_EXPORT friend Handle_Standard_Type& BlockFix_SphereSpaceModifier_Type_(); - Standard_EXPORT const Handle(Standard_Type)& DynamicType() const; - Standard_EXPORT Standard_Boolean IsKind(const Handle(Standard_Type)&) const; - -protected: - - // Methods PROTECTED - // - - - // Fields PROTECTED - // - - -private: - - // Methods PRIVATE - // - - - // Fields PRIVATE - // -Standard_Real myTolerance; -TopTools_DataMapOfShapeInteger myMapOfFaces; -TColStd_IndexedMapOfTransient myMapOfSpheres; - - -}; - - - - - -// other Inline functions and methods (like "C++: function call" methods) -// - - -#endif diff --git a/src/GEOMAlgo/BlockFix_SphereSpaceModifier.ixx b/src/GEOMAlgo/BlockFix_SphereSpaceModifier.ixx deleted file mode 100644 index 482241f6d..000000000 --- a/src/GEOMAlgo/BlockFix_SphereSpaceModifier.ixx +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include - -#ifndef _Standard_TypeMismatch_HeaderFile -#include -#endif - -BlockFix_SphereSpaceModifier::~BlockFix_SphereSpaceModifier() {} - - - -Standard_EXPORT Handle_Standard_Type& BlockFix_SphereSpaceModifier_Type_() -{ - - static Handle_Standard_Type aType1 = STANDARD_TYPE(BRepTools_Modification); - if ( aType1.IsNull()) aType1 = STANDARD_TYPE(BRepTools_Modification); - static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared); - if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared); - static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient); - if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient); - - - static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL}; - static Handle_Standard_Type _aType = new Standard_Type("BlockFix_SphereSpaceModifier", - sizeof(BlockFix_SphereSpaceModifier), - 1, - (Standard_Address)_Ancestors, - (Standard_Address)NULL); - - return _aType; -} - - -// DownCast method -// allow safe downcasting -// -const Handle(BlockFix_SphereSpaceModifier) Handle(BlockFix_SphereSpaceModifier)::DownCast(const Handle(Standard_Transient)& AnObject) -{ - Handle(BlockFix_SphereSpaceModifier) _anOtherObject; - - if (!AnObject.IsNull()) { - if (AnObject->IsKind(STANDARD_TYPE(BlockFix_SphereSpaceModifier))) { - _anOtherObject = Handle(BlockFix_SphereSpaceModifier)((Handle(BlockFix_SphereSpaceModifier)&)AnObject); - } - } - - return _anOtherObject ; -} -const Handle(Standard_Type)& BlockFix_SphereSpaceModifier::DynamicType() const -{ - return STANDARD_TYPE(BlockFix_SphereSpaceModifier) ; -} -Standard_Boolean BlockFix_SphereSpaceModifier::IsKind(const Handle(Standard_Type)& AType) const -{ - return (STANDARD_TYPE(BlockFix_SphereSpaceModifier) == AType || BRepTools_Modification::IsKind(AType)); -} -Handle_BlockFix_SphereSpaceModifier::~Handle_BlockFix_SphereSpaceModifier() {} - diff --git a/src/GEOMAlgo/BlockFix_SphereSpaceModifier.jxx b/src/GEOMAlgo/BlockFix_SphereSpaceModifier.jxx deleted file mode 100644 index 050734179..000000000 --- a/src/GEOMAlgo/BlockFix_SphereSpaceModifier.jxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _TopoDS_Face_HeaderFile -#include -#endif -#ifndef _Geom_Surface_HeaderFile -#include -#endif -#ifndef _TopLoc_Location_HeaderFile -#include -#endif -#ifndef _TopoDS_Edge_HeaderFile -#include -#endif -#ifndef _Geom_Curve_HeaderFile -#include -#endif -#ifndef _TopoDS_Vertex_HeaderFile -#include -#endif -#ifndef _gp_Pnt_HeaderFile -#include -#endif -#ifndef _Geom2d_Curve_HeaderFile -#include -#endif -#ifndef _BlockFix_SphereSpaceModifier_HeaderFile -#include -#endif diff --git a/src/GEOMAlgo/BlockFix_UnionEdges.cdl b/src/GEOMAlgo/BlockFix_UnionEdges.cdl deleted file mode 100644 index 05a9f3870..000000000 --- a/src/GEOMAlgo/BlockFix_UnionEdges.cdl +++ /dev/null @@ -1,49 +0,0 @@ --- Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE --- --- Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, --- CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS --- --- 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. --- --- 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com --- - --- File: BlockFix_UnionEdges.cdl --- Created: Tue Dec 7 15:24:51 2004 --- Author: Sergey KUUL --- -class UnionEdges from BlockFix - - ---Purpose: - -uses - - Shape from TopoDS, - ReShape from ShapeBuild - -is - - Create returns UnionEdges from BlockFix; - - Perform(me: in out; Shape: Shape from TopoDS; - Tol : Real) - returns Shape from TopoDS; - -fields - - myTolerance : Real; - myContext : ReShape from ShapeBuild; - -end UnionEdges; diff --git a/src/GEOMAlgo/BlockFix_UnionEdges.hxx b/src/GEOMAlgo/BlockFix_UnionEdges.hxx deleted file mode 100644 index b38e941fb..000000000 --- a/src/GEOMAlgo/BlockFix_UnionEdges.hxx +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _BlockFix_UnionEdges_HeaderFile -#define _BlockFix_UnionEdges_HeaderFile - -#ifndef _Standard_Real_HeaderFile -#include -#endif -#ifndef _Handle_ShapeBuild_ReShape_HeaderFile -#include -#endif -class ShapeBuild_ReShape; -class TopoDS_Shape; - - -#ifndef _Standard_HeaderFile -#include -#endif -#ifndef _Standard_Macro_HeaderFile -#include -#endif - -class BlockFix_UnionEdges { - -public: - - void* operator new(size_t,void* anAddress) - { - return anAddress; - } - void* operator new(size_t size) - { - return Standard::Allocate(size); - } - void operator delete(void *anAddress) - { - if (anAddress) Standard::Free((Standard_Address&)anAddress); - } - // Methods PUBLIC - // -Standard_EXPORT BlockFix_UnionEdges(); -Standard_EXPORT TopoDS_Shape Perform(const TopoDS_Shape& Shape,const Standard_Real Tol) ; - - - - - -protected: - - // Methods PROTECTED - // - - - // Fields PROTECTED - // - - -private: - - // Methods PRIVATE - // - - - // Fields PRIVATE - // -Standard_Real myTolerance; -Handle_ShapeBuild_ReShape myContext; - - -}; - - - - - -// other Inline functions and methods (like "C++: function call" methods) -// - - -#endif diff --git a/src/GEOMAlgo/BlockFix_UnionEdges.ixx b/src/GEOMAlgo/BlockFix_UnionEdges.ixx deleted file mode 100644 index 27e87ac6c..000000000 --- a/src/GEOMAlgo/BlockFix_UnionEdges.ixx +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include - - - - diff --git a/src/GEOMAlgo/BlockFix_UnionFaces.cdl b/src/GEOMAlgo/BlockFix_UnionFaces.cdl deleted file mode 100644 index 371cb25ea..000000000 --- a/src/GEOMAlgo/BlockFix_UnionFaces.cdl +++ /dev/null @@ -1,65 +0,0 @@ --- Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE --- --- Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, --- CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS --- --- 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. --- --- 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com --- - --- File: BlockFix_UnionFaces.cdl --- Created: Tue Dec 7 17:15:42 2004 --- Author: Pavel Durandin --- -class UnionFaces from BlockFix - -uses - - Face from TopoDS, - Shape from TopoDS - -is - - Create returns UnionFaces from BlockFix; - ---Purpose: Empty constructor - - GetTolerance(me: in out) returns Real; - ---Purpose: Returns modifiable tolerance - ---C++: return& - - Perform (me: in out; Shape: Shape from TopoDS) returns Shape from TopoDS; - ---Purpose: Performs the unification of the fsces - -- whith the same geometry - - IsSameDomain(me; aFace : Face from TopoDS; - aChekedFace: Face from TopoDS) - returns Boolean is virtual; - ---Purpose: Returns true is surfaces have same geometrically domain - -- with given tolerance - - MovePCurves(me; aTarget: in out Face from TopoDS; - aSource: Face from TopoDS) - is virtual; - ---Purpose: Creates pcurves on aTarget face for each edge from - -- aSource one. - -fields - - myTolerance: Real; - -end; - - diff --git a/src/GEOMAlgo/BlockFix_UnionFaces.ixx b/src/GEOMAlgo/BlockFix_UnionFaces.ixx deleted file mode 100644 index c5299ca40..000000000 --- a/src/GEOMAlgo/BlockFix_UnionFaces.ixx +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include - - - - diff --git a/src/GEOMAlgo/BlockFix_UnionFaces.jxx b/src/GEOMAlgo/BlockFix_UnionFaces.jxx deleted file mode 100644 index c89fc31fb..000000000 --- a/src/GEOMAlgo/BlockFix_UnionFaces.jxx +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _TopoDS_Shape_HeaderFile -#include -#endif -#ifndef _TopoDS_Face_HeaderFile -#include -#endif -#ifndef _BlockFix_UnionFaces_HeaderFile -#include -#endif diff --git a/src/GEOMAlgo/FILES b/src/GEOMAlgo/FILES index 44aeb0c17..102101794 100644 --- a/src/GEOMAlgo/FILES +++ b/src/GEOMAlgo/FILES @@ -140,30 +140,3 @@ GEOMAlgo_IndexedDataMapOfShapeShapeInfo.hxx GEOMAlgo_IndexedDataMapOfShapeState.hxx GEOMAlgo_IndexedDataMapOfIntegerShape.hxx GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/GEOMAlgo/Handle_BlockFix_BlockFixAPI.hxx b/src/GEOMAlgo/Handle_BlockFix_BlockFixAPI.hxx deleted file mode 100644 index 3fce5be46..000000000 --- a/src/GEOMAlgo/Handle_BlockFix_BlockFixAPI.hxx +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _Handle_BlockFix_BlockFixAPI_HeaderFile -#define _Handle_BlockFix_BlockFixAPI_HeaderFile - -#ifndef _Standard_Macro_HeaderFile -#include -#endif -#ifndef _Standard_HeaderFile -#include -#endif - -#ifndef _Handle_MMgt_TShared_HeaderFile -#include -#endif - -class Standard_Transient; -class Handle_Standard_Type; -class Handle(MMgt_TShared); -class BlockFix_BlockFixAPI; -Standard_EXPORT Handle_Standard_Type& STANDARD_TYPE(BlockFix_BlockFixAPI); - -class Handle(BlockFix_BlockFixAPI) : public Handle(MMgt_TShared) { - public: - void* operator new(size_t,void* anAddress) - { - return anAddress; - } - void* operator new(size_t size) - { - return Standard::Allocate(size); - } - void operator delete(void *anAddress) - { - if (anAddress) Standard::Free((Standard_Address&)anAddress); - } - Handle(BlockFix_BlockFixAPI)():Handle(MMgt_TShared)() {} - Handle(BlockFix_BlockFixAPI)(const Handle(BlockFix_BlockFixAPI)& aHandle) : Handle(MMgt_TShared)(aHandle) - { - } - - Handle(BlockFix_BlockFixAPI)(const BlockFix_BlockFixAPI* anItem) : Handle(MMgt_TShared)((MMgt_TShared *)anItem) - { - } - - Handle(BlockFix_BlockFixAPI)& operator=(const Handle(BlockFix_BlockFixAPI)& aHandle) - { - Assign(aHandle.Access()); - return *this; - } - - Handle(BlockFix_BlockFixAPI)& operator=(const BlockFix_BlockFixAPI* anItem) - { - Assign((Standard_Transient *)anItem); - return *this; - } - - BlockFix_BlockFixAPI* operator->() - { - return (BlockFix_BlockFixAPI *)ControlAccess(); - } - - BlockFix_BlockFixAPI* operator->() const - { - return (BlockFix_BlockFixAPI *)ControlAccess(); - } - - Standard_EXPORT ~Handle(BlockFix_BlockFixAPI)(); - - Standard_EXPORT static const Handle(BlockFix_BlockFixAPI) DownCast(const Handle(Standard_Transient)& AnObject); -}; -#endif diff --git a/src/GEOMAlgo/Handle_BlockFix_PeriodicSurfaceModifier.hxx b/src/GEOMAlgo/Handle_BlockFix_PeriodicSurfaceModifier.hxx deleted file mode 100644 index 1cb29e022..000000000 --- a/src/GEOMAlgo/Handle_BlockFix_PeriodicSurfaceModifier.hxx +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _Handle_BlockFix_PeriodicSurfaceModifier_HeaderFile -#define _Handle_BlockFix_PeriodicSurfaceModifier_HeaderFile - -#ifndef _Standard_Macro_HeaderFile -#include -#endif -#ifndef _Standard_HeaderFile -#include -#endif - -#ifndef _Handle_BRepTools_Modification_HeaderFile -#include -#endif - -class Standard_Transient; -class Handle_Standard_Type; -class Handle(BRepTools_Modification); -class BlockFix_PeriodicSurfaceModifier; -Standard_EXPORT Handle_Standard_Type& STANDARD_TYPE(BlockFix_PeriodicSurfaceModifier); - -class Handle(BlockFix_PeriodicSurfaceModifier) : public Handle(BRepTools_Modification) { - public: - void* operator new(size_t,void* anAddress) - { - return anAddress; - } - void* operator new(size_t size) - { - return Standard::Allocate(size); - } - void operator delete(void *anAddress) - { - if (anAddress) Standard::Free((Standard_Address&)anAddress); - } - Handle(BlockFix_PeriodicSurfaceModifier)():Handle(BRepTools_Modification)() {} - Handle(BlockFix_PeriodicSurfaceModifier)(const Handle(BlockFix_PeriodicSurfaceModifier)& aHandle) : Handle(BRepTools_Modification)(aHandle) - { - } - - Handle(BlockFix_PeriodicSurfaceModifier)(const BlockFix_PeriodicSurfaceModifier* anItem) : Handle(BRepTools_Modification)((BRepTools_Modification *)anItem) - { - } - - Handle(BlockFix_PeriodicSurfaceModifier)& operator=(const Handle(BlockFix_PeriodicSurfaceModifier)& aHandle) - { - Assign(aHandle.Access()); - return *this; - } - - Handle(BlockFix_PeriodicSurfaceModifier)& operator=(const BlockFix_PeriodicSurfaceModifier* anItem) - { - Assign((Standard_Transient *)anItem); - return *this; - } - - BlockFix_PeriodicSurfaceModifier* operator->() - { - return (BlockFix_PeriodicSurfaceModifier *)ControlAccess(); - } - - BlockFix_PeriodicSurfaceModifier* operator->() const - { - return (BlockFix_PeriodicSurfaceModifier *)ControlAccess(); - } - - Standard_EXPORT ~Handle(BlockFix_PeriodicSurfaceModifier)(); - - Standard_EXPORT static const Handle(BlockFix_PeriodicSurfaceModifier) DownCast(const Handle(Standard_Transient)& AnObject); -}; -#endif diff --git a/src/GEOMAlgo/Handle_BlockFix_SphereSpaceModifier.hxx b/src/GEOMAlgo/Handle_BlockFix_SphereSpaceModifier.hxx deleted file mode 100644 index 33dc8a198..000000000 --- a/src/GEOMAlgo/Handle_BlockFix_SphereSpaceModifier.hxx +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef _Handle_BlockFix_SphereSpaceModifier_HeaderFile -#define _Handle_BlockFix_SphereSpaceModifier_HeaderFile - -#ifndef _Standard_Macro_HeaderFile -#include -#endif -#ifndef _Standard_HeaderFile -#include -#endif - -#ifndef _Handle_BRepTools_Modification_HeaderFile -#include -#endif - -class Standard_Transient; -class Handle_Standard_Type; -class Handle(BRepTools_Modification); -class BlockFix_SphereSpaceModifier; -Standard_EXPORT Handle_Standard_Type& STANDARD_TYPE(BlockFix_SphereSpaceModifier); - -class Handle(BlockFix_SphereSpaceModifier) : public Handle(BRepTools_Modification) { - public: - void* operator new(size_t,void* anAddress) - { - return anAddress; - } - void* operator new(size_t size) - { - return Standard::Allocate(size); - } - void operator delete(void *anAddress) - { - if (anAddress) Standard::Free((Standard_Address&)anAddress); - } - Handle(BlockFix_SphereSpaceModifier)():Handle(BRepTools_Modification)() {} - Handle(BlockFix_SphereSpaceModifier)(const Handle(BlockFix_SphereSpaceModifier)& aHandle) : Handle(BRepTools_Modification)(aHandle) - { - } - - Handle(BlockFix_SphereSpaceModifier)(const BlockFix_SphereSpaceModifier* anItem) : Handle(BRepTools_Modification)((BRepTools_Modification *)anItem) - { - } - - Handle(BlockFix_SphereSpaceModifier)& operator=(const Handle(BlockFix_SphereSpaceModifier)& aHandle) - { - Assign(aHandle.Access()); - return *this; - } - - Handle(BlockFix_SphereSpaceModifier)& operator=(const BlockFix_SphereSpaceModifier* anItem) - { - Assign((Standard_Transient *)anItem); - return *this; - } - - BlockFix_SphereSpaceModifier* operator->() - { - return (BlockFix_SphereSpaceModifier *)ControlAccess(); - } - - BlockFix_SphereSpaceModifier* operator->() const - { - return (BlockFix_SphereSpaceModifier *)ControlAccess(); - } - - Standard_EXPORT ~Handle(BlockFix_SphereSpaceModifier)(); - - Standard_EXPORT static const Handle(BlockFix_SphereSpaceModifier) DownCast(const Handle(Standard_Transient)& AnObject); -}; -#endif diff --git a/src/GEOMAlgo/Makefile.am b/src/GEOMAlgo/Makefile.am index dacba0542..f54398d11 100644 --- a/src/GEOMAlgo/Makefile.am +++ b/src/GEOMAlgo/Makefile.am @@ -15,7 +15,6 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# # GEOM GEOMAlgo : tools for Glue Faces algorithm # File : Makefile.am @@ -28,13 +27,6 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am lib_LTLIBRARIES = libGEOMAlgo.la dist_libGEOMAlgo_la_SOURCES = \ - BlockFix_BlockFixAPI.cxx \ - BlockFix_CheckTool.cxx \ - BlockFix.cxx \ - BlockFix_PeriodicSurfaceModifier.cxx \ - BlockFix_SphereSpaceModifier.cxx \ - BlockFix_UnionEdges.cxx \ - BlockFix_UnionFaces.cxx \ GEOMAlgo_Algo.cxx \ GEOMAlgo_Builder_0.cxx \ GEOMAlgo_Builder_1.cxx \ @@ -96,31 +88,6 @@ dist_libGEOMAlgo_la_SOURCES = \ # header files salomeinclude_HEADERS = \ - BlockFix.hxx \ - BlockFix.ixx \ - BlockFix.jxx \ - BlockFix_BlockFixAPI.hxx \ - BlockFix_BlockFixAPI.ixx \ - BlockFix_BlockFixAPI.jxx \ - BlockFix_BlockFixAPI.lxx \ - BlockFix_CheckTool.hxx \ - BlockFix_CheckTool.ixx \ - BlockFix_CheckTool.jxx \ - BlockFix_PeriodicSurfaceModifier.hxx \ - BlockFix_PeriodicSurfaceModifier.ixx \ - BlockFix_PeriodicSurfaceModifier.jxx \ - BlockFix_SphereSpaceModifier.hxx \ - BlockFix_SphereSpaceModifier.ixx \ - BlockFix_SphereSpaceModifier.jxx \ - BlockFix_UnionEdges.hxx \ - BlockFix_UnionEdges.ixx \ - BlockFix_UnionEdges.jxx \ - BlockFix_UnionFaces.hxx \ - BlockFix_UnionFaces.ixx \ - BlockFix_UnionFaces.jxx \ - Handle_BlockFix_BlockFixAPI.hxx \ - Handle_BlockFix_SphereSpaceModifier.hxx \ - Handle_BlockFix_PeriodicSurfaceModifier.hxx \ GEOMAlgo_Algo.hxx \ GEOMAlgo_BuilderArea.hxx \ GEOMAlgo_BuilderFace.hxx \ @@ -211,15 +178,7 @@ libGEOMAlgo_la_LDFLAGS = \ $(KERNEL_LDFLAGS) -lSALOMELocalTrace # extra distributed files -CDL_FILES = \ - BlockFix.cdl \ - BlockFix_BlockFixAPI.cdl \ - BlockFix_CheckTool.cdl \ - BlockFix_PeriodicSurfaceModifier.cdl \ - BlockFix_SphereSpaceModifier.cdl \ - BlockFix_UnionEdges.cdl \ - BlockFix_UnionFaces.cdl \ - GEOMAlgo.cdl +CDL_FILES = GEOMAlgo.cdl EXTRA_DIST += \ $(CDL_FILES) \ diff --git a/src/GEOMBase/GEOMBase.cxx b/src/GEOMBase/GEOMBase.cxx index 1df7a528c..0e13b280e 100644 --- a/src/GEOMBase/GEOMBase.cxx +++ b/src/GEOMBase/GEOMBase.cxx @@ -512,7 +512,7 @@ TopoDS_Shape GEOMBase::CreateArrowForLinearEdge( const TopoDS_Shape& shape ) try { Standard_Real first, last; Handle(Geom_Curve) curv = BRep_Tool::Curve( TopoDS::Edge( shape ), first, last ); - if ( curv->IsCN(1) ) { + if ( !curv.IsNull() && curv->IsCN(1) ) { const Standard_Real param = ( first+last ) / 2.0; gp_Pnt middleParamPoint; gp_Vec V1; diff --git a/src/GEOMBase/GEOMBase_Helper.cxx b/src/GEOMBase/GEOMBase_Helper.cxx index 8fea8899a..4a051722c 100755 --- a/src/GEOMBase/GEOMBase_Helper.cxx +++ b/src/GEOMBase/GEOMBase_Helper.cxx @@ -18,12 +18,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : GEOMBase_Helper.cxx // Author : Sergey ANIKIN, Open CASCADE S.A.S. (sergey.anikin@opencascade.com) -// + #include "GEOMBase_Helper.h" #include "GEOMBase.h" #include "GEOM_Operation.h" @@ -90,7 +89,7 @@ GEOM::GEOM_Gen_ptr GEOMBase_Helper::getGeomEngine() GEOMBase_Helper::GEOMBase_Helper( SUIT_Desktop* desktop ) : myDesktop( desktop ), myViewWindow( 0 ), myDisplayer( 0 ), myCommand( 0 ), isPreview( false ), myIsApplyAndClose( false ), myIsOptimizedBrowsing( false ), myIsWaitCursorEnabled( true ), - myIsDisableBrowsing(false) + myIsDisableBrowsing(false), myIsDisplayResult(true) { } @@ -319,19 +318,16 @@ void GEOMBase_Helper::displayPreview( GEOM::GEOM_Object_ptr object, const int displayMode, const int color ) { + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + // Set color for preview shape getDisplayer()->SetColor( color == -1 ? Quantity_NOC_VIOLET : color ); // set width of displayed shape - int lw = lineWidth; - if(lw == -1) { - SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); - lw = resMgr->integerValue("Geometry", "preview_edge_width", -1); - } - getDisplayer()->SetWidth( lw ); + getDisplayer()->SetWidth( lineWidth == -1 ? resMgr->integerValue("Geometry", "preview_edge_width", -1) : lineWidth ); // set display mode of displayed shape - int aPrevDispMode = getDisplayer()->SetDisplayMode( displayMode ); + int aPrevDispMode = getDisplayer()->SetDisplayMode( displayMode == -1 ? resMgr->integerValue( "Geometry", "display_mode", 0 ) : displayMode ); // Disable activation of selection getDisplayer()->SetToActivate( activate ); @@ -554,9 +550,10 @@ QString GEOMBase_Helper::addInStudy( GEOM::GEOM_Object_ptr theObj, const char* t getGeomEngine()->AddInStudy(aStudyDS, theObj, theName, aFatherObj); QString anEntry; - if ( !aSO->_is_nil() ) - anEntry = aSO->GetID(); - + if ( !aSO->_is_nil() ) { + CORBA::String_var entry = aSO->GetID(); + anEntry = entry.in(); + } // Each dialog is responsible for this method implementation, // default implementation does nothing restoreSubShapes(aStudyDS, aSO); @@ -770,7 +767,6 @@ bool GEOMBase_Helper::commitCommand( const char* ) //================================================================ bool GEOMBase_Helper::hasCommand() const { - bool res = (bool) myCommand; return (bool)myCommand; } @@ -858,11 +854,11 @@ bool GEOMBase_Helper::onAccept( const bool publish, const bool useTransaction, b addSubshapesToStudy(); // add Sub-shapes if local selection const int nbObjs = objects.size(); QStringList anEntryList; - int aNumber = 1; - for ( ObjectList::iterator it = objects.begin(); it != objects.end(); ++it ) { + int currObj = 1, aNumber = 1; + for ( ObjectList::iterator it = objects.begin(); it != objects.end(); ++it, currObj++ ) { GEOM::GEOM_Object_var obj=*it; if ( publish ) { - QString aName = getNewObjectName(); + QString aName = getNewObjectName(currObj); if ( nbObjs > 1 ) { if (aName.isEmpty()) aName = getPrefix(obj); @@ -880,7 +876,8 @@ bool GEOMBase_Helper::onAccept( const bool publish, const bool useTransaction, b } anEntryList << addInStudy( obj, aName.toLatin1().constData() ); // updateView=false - display( obj, false ); + if( isDisplayResult() ) + display( obj, false ); #ifdef WITHGENERICOBJ // obj has been published in study. Its refcount has been incremented. // It is safe to decrement its refcount @@ -893,7 +890,8 @@ bool GEOMBase_Helper::onAccept( const bool publish, const bool useTransaction, b // was modified, and need to be re-cached in GEOM_Client before redisplay clearShapeBuffer( obj ); // withChildren=true, updateView=false - redisplay( obj, true, false ); + if( isDisplayResult() ) + redisplay( obj, true, false ); } } @@ -1006,7 +1004,7 @@ GEOM::GEOM_Object_ptr GEOMBase_Helper::getFather( GEOM::GEOM_Object_ptr theObj ) // Function : getNewObjectName // Purpose : Redefine this method to return proper name for a new object //================================================================ -QString GEOMBase_Helper::getNewObjectName() const +QString GEOMBase_Helper::getNewObjectName (int) const { return QString::null; } @@ -1137,17 +1135,17 @@ GEOM::GEOM_Object_ptr GEOMBase_Helper::findObjectInFather( GEOM::GEOM_Object_ptr if ( sobject ) { _PTR(ChildIterator) it( studyDS->NewChildIterator( sobject ) ); for ( ; it->More() && !found; it->Next() ) { - GEOM::GEOM_Object_var cobject = GEOM::GEOM_Object::_narrow( GeometryGUI::ClientSObjectToObject( it->Value() ) ); - if ( !CORBA::is_nil( cobject ) ) { - GEOM::ListOfLong_var indices = cobject->GetSubShapeIndices(); - int length = indices->length(); - for ( int i = 0; i < length && !found; i++ ) { - if ( indices[i] == theIndex ) { - object = cobject; - found = true; - } - } - } + GEOM::GEOM_Object_var cobject = GEOM::GEOM_Object::_narrow( GeometryGUI::ClientSObjectToObject( it->Value() ) ); + if ( !CORBA::is_nil( cobject ) ) { + GEOM::ListOfLong_var indices = cobject->GetSubShapeIndices(); + int length = indices->length(); + for ( int i = 0; i < length && !found; i++ ) { + if ( indices[i] == theIndex ) { + object = cobject; + found = true; + } + } + } } } } @@ -1277,58 +1275,58 @@ QList GEOMBase_Helper::getSelected( const QListGetIndexes( IO, subShapes ); - int nbSubShapes = subShapes.Extent(); - if ( nbSubShapes == 0 ) { - // global selection - if ( typeInList( (TopAbs_ShapeEnum)(object->GetShapeType()), types ) ) { - result << object; - if ( count > 0 ) { - if ( strict && result.count() > count ) { - result.clear(); - stopped = true; - } - else if ( !strict && result.count() == count ) - stopped = true; - } - } - else if ( strict ) { - result.clear(); - stopped = true; - } - } - else { - // local selection - for ( int i = 1; i <= nbSubShapes && !stopped; i++ ) { - int idx = subShapes( i ); - GEOM::GeomObjPtr subShape = findObjectInFather( object.get(), idx ); - if ( !subShape ) { - // sub-shape is not yet published in the study - GEOM::ShapesOpPtr shapesOp = getGeomEngine()->GetIShapesOperations( getStudyId() ); - subShape.take( shapesOp->GetSubShape( object.get(), idx ) ); // take ownership! - } - if ( typeInList( (TopAbs_ShapeEnum)(subShape->GetShapeType()), types ) ) { - result << subShape; - if ( count > 0 ) { - if ( strict && result.count() > count ) { - result.clear(); - stopped = true; - } - else if ( !strict && result.count() == count ) - stopped = true; - } - } - else if ( strict ) { - result.clear(); - stopped = true; - } - } - } - } + Handle(SALOME_InteractiveObject) IO = it.Value(); + GEOM::GeomObjPtr object = GEOMBase::ConvertIOinGEOMObject( IO ); + if ( object ) { + TColStd_IndexedMapOfInteger subShapes; + selMgr->GetIndexes( IO, subShapes ); + int nbSubShapes = subShapes.Extent(); + if ( nbSubShapes == 0 ) { + // global selection + if ( typeInList( (TopAbs_ShapeEnum)(object->GetShapeType()), types ) ) { + result << object; + if ( count > 0 ) { + if ( strict && result.count() > count ) { + result.clear(); + stopped = true; + } + else if ( !strict && result.count() == count ) + stopped = true; + } + } + else if ( strict ) { + result.clear(); + stopped = true; + } + } + else { + // local selection + for ( int i = 1; i <= nbSubShapes && !stopped; i++ ) { + int idx = subShapes( i ); + GEOM::GeomObjPtr subShape = findObjectInFather( object.get(), idx ); + if ( !subShape ) { + // sub-shape is not yet published in the study + GEOM::ShapesOpPtr shapesOp = getGeomEngine()->GetIShapesOperations( getStudyId() ); + subShape.take( shapesOp->GetSubShape( object.get(), idx ) ); // take ownership! + } + if ( typeInList( (TopAbs_ShapeEnum)(subShape->GetShapeType()), types ) ) { + result << subShape; + if ( count > 0 ) { + if ( strict && result.count() > count ) { + result.clear(); + stopped = true; + } + else if ( !strict && result.count() == count ) + stopped = true; + } + } + else if ( strict ) { + result.clear(); + stopped = true; + } + } + } + } } } } diff --git a/src/GEOMBase/GEOMBase_Helper.h b/src/GEOMBase/GEOMBase_Helper.h index 5d32fd268..0a1ae7b6d 100755 --- a/src/GEOMBase/GEOMBase_Helper.h +++ b/src/GEOMBase/GEOMBase_Helper.h @@ -18,12 +18,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : GEOMBase_Helper.h // Author : Sergey ANIKIN, Open CASCADE S.A.S. (sergey.anikin@opencascade.com) -// + #ifndef GEOMBASE_HELPER_H #define GEOMBASE_HELPER_H @@ -51,7 +50,7 @@ class TColStd_MapOfInteger; //================================================================ // Class : GEOMBase_Helper -// Description : Helper class for dialog box development, can be used as +// Description : Helper class for dialog box development, can be used as // the second base class for dialog boxes. Contains convenient methods // performing common operations (display/erase, selection activation, // publication in a study, transaction management) @@ -73,24 +72,24 @@ protected: void redisplay ( GEOM::GEOM_Object_ptr, const bool = true, const bool = true ); virtual void displayPreview ( const bool display, - const bool activate = false, + const bool activate = false, const bool update = true, const bool toRemoveFromEngine = true, - const double lineWidth = -1, + const double lineWidth = -1, const int displayMode = -1, const int color = -1 ); // This is the easiest way to show preview. It is based on execute() method. // It removes temporary GEOM::GEOM_Objects automatically. - virtual void displayPreview ( GEOM::GEOM_Object_ptr obj, - const bool append = false, - const bool activate = false, + virtual void displayPreview ( GEOM::GEOM_Object_ptr obj, + const bool append = false, + const bool activate = false, const bool update = true, - const double lineWidth = -1, + const double lineWidth = -1, const int displayMode = -1, const int color = -1 ); - void displayPreview ( const SALOME_Prs* prs, - const bool append = false, + void displayPreview ( const SALOME_Prs* prs, + const bool append = false, const bool = true ); void erasePreview ( const bool = true ); @@ -105,7 +104,7 @@ protected: void prepareSelection( const ObjectList&, const int ); void prepareSelection( GEOM::GEOM_Object_ptr, const int ); - QString addInStudy ( GEOM::GEOM_Object_ptr, const char* theName ); + QString addInStudy ( GEOM::GEOM_Object_ptr, const char* theName ); bool openCommand (); bool abortCommand (); @@ -119,7 +118,7 @@ protected: bool onAccept( const bool publish = true, const bool useTransaction = true, bool erasePreviewFlag = true); // This method should be called from "OK" button handler. - // == true means that objects returned by execute() + // == true means that objects returned by execute() // should be published in a study. void showError(); @@ -134,16 +133,16 @@ protected: inline void setPrefix( const QString& prefix ) { myPrefix = prefix; } QString getPrefix( GEOM::GEOM_Object_ptr = GEOM::GEOM_Object::_nil() ) const; - + bool selectObjects( ObjectList& objects ); - // Selects list of objects + // Selects list of objects //////////////////////////////////////////////////////////////////////////// // Virtual methods, to be redefined in dialog classes //////////////////////////////////////////////////////////////////////////// virtual GEOM::GEOM_IOperations_ptr createOperation(); - // This method should be redefined in dialog boxes so as to return + // This method should be redefined in dialog boxes so as to return // proper GEOM_IOperation interface. // Returns nil reference by default @@ -151,9 +150,9 @@ protected: // Called by onAccept(). Redefine this method to check validity of user input in dialog boxes. virtual bool execute( ObjectList& objects ); - // This method is called by onAccept(). - // It should perform the required operation and put all new or modified objects into - // argument.Should return if some error occurs during its execution. + // This method is called by onAccept(). + // It should perform the required operation and put all new or modified objects into + // argument.Should return if some error occurs during its execution. virtual void restoreSubShapes( SALOMEDS::Study_ptr theStudy, SALOMEDS::SObject_ptr theSObject ); // This method is called by addInStudy(). @@ -163,7 +162,7 @@ protected: // for or a nil reference if should be published // as a top-level object. - virtual QString getNewObjectName() const; + virtual QString getNewObjectName (int CurrObj = -1) const; virtual bool extractPrefix() const; virtual void addSubshapesToStudy(); @@ -187,12 +186,13 @@ protected: virtual void setIsOptimizedBrowsing( const bool theFlag ); virtual bool isOptimizedBrowsing() const; - + virtual void setIsWaitCursorEnabled( const bool theFlag ) {myIsWaitCursorEnabled = theFlag;} virtual bool isWaitCursorEnabled() const {return myIsWaitCursorEnabled ;} virtual void setIsDisableBrowsing( const bool theFlag ) { myIsDisableBrowsing = theFlag; } virtual bool isDisableBrowsing() const { return myIsDisableBrowsing; } - + virtual void setIsDisplayResult( const bool theFlag ) {myIsDisplayResult = theFlag; } + virtual bool isDisplayResult() const { return myIsDisplayResult; } private: QString getEntry( GEOM::GEOM_Object_ptr ) const; @@ -213,9 +213,9 @@ private: bool myIsApplyAndClose; bool myIsOptimizedBrowsing; bool myIsWaitCursorEnabled; - bool myIsDisableBrowsing; //This flag enable/disable selection + bool myIsDisableBrowsing; //This flag enable/disable selection //in the Object Browser newly created objects. - + bool myIsDisplayResult; //This flag display/hide newly created objects. }; #endif // GEOMBASE_HELPER_H diff --git a/src/GEOMBase/GEOMBase_Skeleton.cxx b/src/GEOMBase/GEOMBase_Skeleton.cxx index 57be34955..d6f286425 100644 --- a/src/GEOMBase/GEOMBase_Skeleton.cxx +++ b/src/GEOMBase/GEOMBase_Skeleton.cxx @@ -18,12 +18,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : GEOMBase_Skeleton.cxx // Author : Damien COQUERET, Open CASCADE S.A.S. -// + #include "GEOMBase_Skeleton.h" #include "GEOMBase.h" @@ -293,7 +292,7 @@ void GEOMBase_Skeleton::initName( const QString& thePrefix ) // function : getNewObjectName() // purpose : returns contents of Name field //================================================================================= -QString GEOMBase_Skeleton::getNewObjectName() const +QString GEOMBase_Skeleton::getNewObjectName (int) const { return myMainFrame->ResultName->text(); } diff --git a/src/GEOMBase/GEOMBase_Skeleton.h b/src/GEOMBase/GEOMBase_Skeleton.h index bb6d75434..73bf0d2a2 100644 --- a/src/GEOMBase/GEOMBase_Skeleton.h +++ b/src/GEOMBase/GEOMBase_Skeleton.h @@ -18,12 +18,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : GEOMBase_Skeleton.h // Author : Damine COQUERET, Open CASCADE S.A.S. -// + #ifndef GEOMBASE_SKELETON_H #define GEOMBASE_SKELETON_H @@ -74,7 +73,7 @@ protected: /*! returns contents of "Name" field */ - virtual QString getNewObjectName() const; + virtual QString getNewObjectName (int CurrObj = -1) const; /*! returns id of a selected "constructor" radio button or '-1' in case of error */ diff --git a/src/GEOMBase/GEOM_GenericObjPtr.h b/src/GEOMBase/GEOM_GenericObjPtr.h index b4ece1236..aec0ee23e 100644 --- a/src/GEOMBase/GEOM_GenericObjPtr.h +++ b/src/GEOMBase/GEOM_GenericObjPtr.h @@ -87,15 +87,15 @@ namespace GEOM void Register() { if ( !CORBA::is_nil( this->myObject ) ) - this->myObject->Register(); + this->myObject->Register(); } //! Decrement counter for the object. void UnRegister() { if ( !CORBA::is_nil( this->myObject ) ) { - this->myObject->UnRegister(); - this->myObject = TInterface::_nil(); + this->myObject->UnRegister(); + this->myObject = TInterface::_nil(); } } diff --git a/src/GEOMClient/Makefile.am b/src/GEOMClient/Makefile.am index b3addc3b2..d2775005a 100644 --- a/src/GEOMClient/Makefile.am +++ b/src/GEOMClient/Makefile.am @@ -22,7 +22,6 @@ # Author : Patrick GOLDBRONN (CEA) # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : GEOM -# $Header$ # include $(top_srcdir)/adm_local/unix/make_common_starter.am diff --git a/src/GEOMGUI/GEOMGUI.cxx b/src/GEOMGUI/GEOMGUI.cxx index b87f89833..2e1021de3 100644 --- a/src/GEOMGUI/GEOMGUI.cxx +++ b/src/GEOMGUI/GEOMGUI.cxx @@ -48,6 +48,15 @@ GEOMGUI::~GEOMGUI() { } +//================================================================================= +// class : GEOMGUI::OnGUIEvent +// purpose : Main/popup menu events processing +//================================================================================= +bool GEOMGUI::OnGUIEvent( int /*theCommandID*/, SUIT_Desktop* /*parent*/, const QVariant& /*theParam*/ ) +{ + return TRUE; +} + //================================================================================= // class : GEOMGUI::OnGUIEvent // purpose : Main/popup menu events processing diff --git a/src/GEOMGUI/GEOMGUI.h b/src/GEOMGUI/GEOMGUI.h index 87b76ed24..eac15283a 100644 --- a/src/GEOMGUI/GEOMGUI.h +++ b/src/GEOMGUI/GEOMGUI.h @@ -51,6 +51,7 @@ public : // Each of this methods can be redifined by descendants virtual bool OnGUIEvent( int theCommandID, SUIT_Desktop* parent ); + virtual bool OnGUIEvent( int theCommandID, SUIT_Desktop* parent, const QVariant& theParam ); virtual bool OnMousePress( QMouseEvent* pe, SUIT_Desktop* parent, SUIT_ViewWindow* ); virtual bool OnMouseMove( QMouseEvent* pe, SUIT_Desktop* parent, SUIT_ViewWindow* ); diff --git a/src/GEOMGUI/GEOMGUI_Selection.cxx b/src/GEOMGUI/GEOMGUI_Selection.cxx index 0aa1da20a..4d7a490b0 100644 --- a/src/GEOMGUI/GEOMGUI_Selection.cxx +++ b/src/GEOMGUI/GEOMGUI_Selection.cxx @@ -213,27 +213,20 @@ int GEOMGUI_Selection::typeId( const int index ) const bool GEOMGUI_Selection::isVisible( const int index ) const { - bool res = false; - #ifdef USE_VISUAL_PROP_MAP - bool found = false; - QVariant v = visibleProperty( entry( index ), VISIBILITY_PROP ); - if ( v.canConvert( QVariant::Bool ) ) { - res = v.toBool(); - found = true; - } - - if ( !found ) { + QVariant v = visibleProperty( entry( index ), GEOM::propertyName( GEOM::Visibility ) ); + if ( v.canConvert( QVariant::Bool ) ) + return v.toBool(); #endif - GEOM::GEOM_Object_var obj = getObject( index ); - SALOME_View* view = GEOM_Displayer::GetActiveView(); - if ( !CORBA::is_nil( obj ) && view ) { - Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( entry( index ).toLatin1().constData(), "GEOM", "TEMP_IO" ); - res = view->isVisible( io ); - } -#ifdef USE_VISUAL_PROP_MAP + + bool res = false; + + GEOM::GEOM_Object_var obj = getObject( index ); + SALOME_View* view = GEOM_Displayer::GetActiveView(); + if ( !CORBA::is_nil( obj ) && view ) { + Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( entry( index ).toLatin1().constData(), "GEOM", "TEMP_IO" ); + res = view->isVisible( io ); } -#endif return res; } @@ -288,8 +281,9 @@ QString GEOMGUI_Selection::displayMode( const int index ) const { QString res; QString viewType = activeViewType(); + #ifdef USE_VISUAL_PROP_MAP - QVariant v = visibleProperty( entry( index ), DISPLAY_MODE_PROP ); + QVariant v = visibleProperty( entry( index ), GEOM::propertyName( GEOM::DisplayMode ) ); if ( v.canConvert( QVariant::Int ) ) { int dm = v.toInt(); if ( viewType == OCCViewer_Viewer::Type() ) { @@ -297,113 +291,103 @@ QString GEOMGUI_Selection::displayMode( const int index ) const } else if ( viewType == SVTK_Viewer::Type() ) { VTK_DISPLAY_MODE_TO_STRING( res, dm ); } + return res; } - - if ( res.isEmpty() ) { #endif - SALOME_View* view = GEOM_Displayer::GetActiveView(); - if ( view /*fix for 9320==>*/&& ( viewType == OCCViewer_Viewer::Type() || viewType == SVTK_Viewer::Type() ) ) { - SALOME_Prs* prs = view->CreatePrs( entry( index ).toLatin1().constData() ); - if ( prs ) { - if ( viewType == OCCViewer_Viewer::Type() ) { // assuming OCC - SOCC_Prs* occPrs = (SOCC_Prs*) prs; - AIS_ListOfInteractive lst; - occPrs->GetObjects( lst ); - if ( lst.Extent() ) { - Handle(AIS_InteractiveObject) io = lst.First(); - if ( !io.IsNull() ) { - int dm; - Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast(io); - if(!aSh.IsNull()) { - dm = aSh->isTopLevel() ? aSh->prevDisplayMode() : aSh->DisplayMode(); - } else { - dm = io->DisplayMode(); - } + + SALOME_View* view = GEOM_Displayer::GetActiveView(); + if ( view /*fix for 9320==>*/&& ( viewType == OCCViewer_Viewer::Type() || viewType == SVTK_Viewer::Type() ) ) { + SALOME_Prs* prs = view->CreatePrs( entry( index ).toLatin1().constData() ); + if ( prs ) { + if ( viewType == OCCViewer_Viewer::Type() ) { // assuming OCC + SOCC_Prs* occPrs = (SOCC_Prs*) prs; + AIS_ListOfInteractive lst; + occPrs->GetObjects( lst ); + if ( lst.Extent() ) { + Handle(AIS_InteractiveObject) io = lst.First(); + if ( !io.IsNull() ) { + int dm; + Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast(io); + if(!aSh.IsNull()) { + dm = aSh->isTopLevel() ? aSh->prevDisplayMode() : aSh->DisplayMode(); + } else { + dm = io->DisplayMode(); + } + OCC_DISPLAY_MODE_TO_STRING( res, dm ); + if ( res.isEmpty() ) { // return default display mode of AIS_InteractiveContext + OCCViewer_Viewer* occViewer = (OCCViewer_Viewer*)SUIT_Session::session()->activeApplication()-> + desktop()->activeWindow()->getViewManager()->getViewModel(); + Handle(AIS_InteractiveContext) ic = occViewer->getAISContext(); + dm = ic->DisplayMode(); OCC_DISPLAY_MODE_TO_STRING( res, dm ); - if ( res.isEmpty() ) { // return default display mode of AIS_InteractiveContext - OCCViewer_Viewer* occViewer = (OCCViewer_Viewer*)SUIT_Session::session()->activeApplication()-> - desktop()->activeWindow()->getViewManager()->getViewModel(); - Handle(AIS_InteractiveContext) ic = occViewer->getAISContext(); - dm = ic->DisplayMode(); - OCC_DISPLAY_MODE_TO_STRING( res, dm ); - } } } } - else if ( viewType == SVTK_Viewer::Type() ) { // assuming VTK - SVTK_Prs* vtkPrs = dynamic_cast( prs ); - vtkActorCollection* lst = vtkPrs ? vtkPrs->GetObjects() : 0; - if ( lst ) { - lst->InitTraversal(); - vtkActor* actor = lst->GetNextActor(); - if ( actor ) { - SALOME_Actor* salActor = dynamic_cast( actor ); - if ( salActor ) { - int dm = salActor->getDisplayMode(); - VTK_DISPLAY_MODE_TO_STRING( res, dm ); - } // if ( salome actor ) - } // if ( actor ) - } // if ( lst == vtkPrs->GetObjects() ) - } // if VTK } + else if ( viewType == SVTK_Viewer::Type() ) { // assuming VTK + SVTK_Prs* vtkPrs = dynamic_cast( prs ); + vtkActorCollection* lst = vtkPrs ? vtkPrs->GetObjects() : 0; + if ( lst ) { + lst->InitTraversal(); + vtkActor* actor = lst->GetNextActor(); + if ( actor ) { + SALOME_Actor* salActor = dynamic_cast( actor ); + if ( salActor ) { + int dm = salActor->getDisplayMode(); + VTK_DISPLAY_MODE_TO_STRING( res, dm ); + } // if ( salome actor ) + } // if ( actor ) + } // if ( lst == vtkPrs->GetObjects() ) + } // if VTK } - -#ifdef USE_VISUAL_PROP_MAP } -#endif return res; } bool GEOMGUI_Selection::isVectorsMode( const int index ) const { - bool res = false; - #ifdef USE_VISUAL_PROP_MAP - bool found = false; - QVariant v = visibleProperty( entry( index ), VECTOR_MODE_PROP ); - if ( v.canConvert( QVariant::Bool ) ) { - res = v.toBool(); - found = true; - } - - if ( !found ) { + QVariant v = visibleProperty( entry( index ), GEOM::propertyName( GEOM::EdgesDirection ) ); + if ( v.canConvert( QVariant::Bool ) ) + return v.toBool(); #endif - SALOME_View* view = GEOM_Displayer::GetActiveView(); - QString viewType = activeViewType(); - if ( view && ( viewType == OCCViewer_Viewer::Type() || viewType == SVTK_Viewer::Type() ) ) { - SALOME_Prs* prs = view->CreatePrs( entry( index ).toLatin1().constData() ); - if ( prs ) { - if ( viewType == OCCViewer_Viewer::Type() ) { // assuming OCC - SOCC_Prs* occPrs = (SOCC_Prs*) prs; - AIS_ListOfInteractive lst; - occPrs->GetObjects( lst ); - if ( lst.Extent() ) { - Handle(AIS_InteractiveObject) io = lst.First(); - if ( !io.IsNull() ) { - Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast(io); - if ( !aSh.IsNull() ) - res = aSh->isShowVectors(); - } + + bool res = false; + + SALOME_View* view = GEOM_Displayer::GetActiveView(); + QString viewType = activeViewType(); + if ( view && ( viewType == OCCViewer_Viewer::Type() || viewType == SVTK_Viewer::Type() ) ) { + SALOME_Prs* prs = view->CreatePrs( entry( index ).toLatin1().constData() ); + if ( prs ) { + if ( viewType == OCCViewer_Viewer::Type() ) { // assuming OCC + SOCC_Prs* occPrs = (SOCC_Prs*) prs; + AIS_ListOfInteractive lst; + occPrs->GetObjects( lst ); + if ( lst.Extent() ) { + Handle(AIS_InteractiveObject) io = lst.First(); + if ( !io.IsNull() ) { + Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast(io); + if ( !aSh.IsNull() ) + res = aSh->isShowVectors(); } - } else if ( viewType == SVTK_Viewer::Type() ) { // assuming VTK - SVTK_Prs* vtkPrs = dynamic_cast( prs ); - vtkActorCollection* lst = vtkPrs ? vtkPrs->GetObjects() : 0; - if ( lst ) { - lst->InitTraversal(); - vtkActor* actor = lst->GetNextActor(); - if ( actor ) { - GEOM_Actor* aGeomActor = GEOM_Actor::SafeDownCast(actor); - if ( aGeomActor ) - res = aGeomActor->GetVectorMode(); + } + } + else if ( viewType == SVTK_Viewer::Type() ) { // assuming VTK + SVTK_Prs* vtkPrs = dynamic_cast( prs ); + vtkActorCollection* lst = vtkPrs ? vtkPrs->GetObjects() : 0; + if ( lst ) { + lst->InitTraversal(); + vtkActor* actor = lst->GetNextActor(); + if ( actor ) { + GEOM_Actor* aGeomActor = GEOM_Actor::SafeDownCast(actor); + if ( aGeomActor ) + res = aGeomActor->GetVectorMode(); } - } } } } -#ifdef USE_VISUAL_PROP_MAP } -#endif return res; } @@ -548,35 +532,31 @@ QString GEOMGUI_Selection::selectionMode() const return ""; } -bool GEOMGUI_Selection::topLevel( const int index ) const { - bool res = false; - +bool GEOMGUI_Selection::topLevel( const int index ) const +{ #ifdef USE_VISUAL_PROP_MAP - bool found = false; - QVariant v = visibleProperty( entry( index ), TOP_LEVEL_PROP ); - if ( v.canConvert() ) { - res = v.toBool(); - found = true; - } - - if ( !found ) { + QVariant v = visibleProperty( entry( index ), GEOM::propertyName( GEOM::TopLevel ) ); + if ( v.canConvert() ) + return v.toBool(); #endif - SALOME_View* view = GEOM_Displayer::GetActiveView(); - QString viewType = activeViewType(); - if ( view && viewType == OCCViewer_Viewer::Type() ) { - SALOME_Prs* prs = view->CreatePrs( entry( index ).toLatin1().constData() ); - if ( prs ) { - if ( viewType == OCCViewer_Viewer::Type() ) { // assuming OCC - SOCC_Prs* occPrs = (SOCC_Prs*) prs; - AIS_ListOfInteractive lst; - occPrs->GetObjects( lst ); - if ( lst.Extent() ) { - Handle(AIS_InteractiveObject) io = lst.First(); - if ( !io.IsNull() ) { - Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast(io); - if ( !aSh.IsNull() ) - res = (bool)aSh->isTopLevel(); - } + + bool res = false; + + SALOME_View* view = GEOM_Displayer::GetActiveView(); + QString viewType = activeViewType(); + if ( view && viewType == OCCViewer_Viewer::Type() ) { + SALOME_Prs* prs = view->CreatePrs( entry( index ).toLatin1().constData() ); + if ( prs ) { + if ( viewType == OCCViewer_Viewer::Type() ) { // assuming OCC + SOCC_Prs* occPrs = (SOCC_Prs*) prs; + AIS_ListOfInteractive lst; + occPrs->GetObjects( lst ); + if ( lst.Extent() ) { + Handle(AIS_InteractiveObject) io = lst.First(); + if ( !io.IsNull() ) { + Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast(io); + if ( !aSh.IsNull() ) + res = (bool)aSh->isTopLevel(); } } } @@ -585,57 +565,55 @@ bool GEOMGUI_Selection::topLevel( const int index ) const { return res; } -bool GEOMGUI_Selection::isPhysicalMaterial( const int idx ) const{ - bool res = false; - +bool GEOMGUI_Selection::isPhysicalMaterial( const int idx ) const +{ #ifdef USE_VISUAL_PROP_MAP - bool found = false; - QVariant v = visibleProperty( entry( idx ), MATERIAL_PROP ); - if ( v.canConvert() ) { - Material_Model material; - material.fromProperties( v.toString() ); - res = material.isPhysical(); - found = true; - } - - if ( !found ) { + QVariant v = visibleProperty( entry( idx ), GEOM::propertyName( GEOM::Material ) ); + if ( v.canConvert() ) { + Material_Model material; + material.fromProperties( v.toString() ); + return material.isPhysical(); + } #endif - SALOME_View* view = GEOM_Displayer::GetActiveView(); - QString viewType = activeViewType(); - if ( view ) { - SALOME_Prs* prs = view->CreatePrs( entry( idx ).toLatin1().constData() ); - if ( prs ) { - if ( viewType == OCCViewer_Viewer::Type() ) { // assuming OCC - SOCC_Prs* occPrs = (SOCC_Prs*) prs; - AIS_ListOfInteractive lst; - occPrs->GetObjects( lst ); - if ( lst.Extent() ) { - Handle(AIS_InteractiveObject) io = lst.First(); - if ( !io.IsNull() ) { - Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast(io); - if ( !aSh.IsNull() ) - res = (bool) aSh->Attributes()->ShadingAspect()-> - Material(Aspect_TOFM_BOTH_SIDE).MaterialType( Graphic3d_MATERIAL_PHYSIC ); - } - } - } - else if ( viewType == SVTK_Viewer::Type() ) { // assuming VTK - SVTK_Prs* vtkPrs = dynamic_cast( prs ); - vtkActorCollection* lst = vtkPrs ? vtkPrs->GetObjects() : 0; - if ( lst ) { - lst->InitTraversal(); - vtkActor* actor = lst->GetNextActor(); - if ( actor ) { - GEOM_Actor* aGeomGActor = GEOM_Actor::SafeDownCast( actor ); - if ( aGeomGActor ) { - GEOM_VTKPropertyMaterial* mat = GEOM_VTKPropertyMaterial::SafeDownCast(aGeomGActor->GetProperty()); - res = mat->GetPhysical(); - } // if ( salome actor ) - } // if ( actor ) - } // if ( lst == vtkPrs->GetObjects() ) - } - } - } - } - return res; + + bool res = false; + + SALOME_View* view = GEOM_Displayer::GetActiveView(); + QString viewType = activeViewType(); + if ( view ) { + SALOME_Prs* prs = view->CreatePrs( entry( idx ).toLatin1().constData() ); + if ( prs ) { + if ( viewType == OCCViewer_Viewer::Type() ) { // assuming OCC + SOCC_Prs* occPrs = (SOCC_Prs*) prs; + AIS_ListOfInteractive lst; + occPrs->GetObjects( lst ); + if ( lst.Extent() ) { + Handle(AIS_InteractiveObject) io = lst.First(); + if ( !io.IsNull() ) { + Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast(io); + if ( !aSh.IsNull() ) + res = (bool) aSh->Attributes()->ShadingAspect()-> + Material(Aspect_TOFM_BOTH_SIDE).MaterialType( Graphic3d_MATERIAL_PHYSIC ); + } + } + } + else if ( viewType == SVTK_Viewer::Type() ) { // assuming VTK + SVTK_Prs* vtkPrs = dynamic_cast( prs ); + vtkActorCollection* lst = vtkPrs ? vtkPrs->GetObjects() : 0; + if ( lst ) { + lst->InitTraversal(); + vtkActor* actor = lst->GetNextActor(); + if ( actor ) { + GEOM_Actor* aGeomGActor = GEOM_Actor::SafeDownCast( actor ); + if ( aGeomGActor ) { + GEOM_VTKPropertyMaterial* mat = GEOM_VTKPropertyMaterial::SafeDownCast(aGeomGActor->GetProperty()); + res = mat->GetPhysical(); + } // if ( salome actor ) + } // if ( actor ) + } // if ( lst == vtkPrs->GetObjects() ) + } + } + } + + return res; } diff --git a/src/GEOMGUI/GEOM_Displayer.cxx b/src/GEOMGUI/GEOM_Displayer.cxx index 1718d7d0b..4b362a702 100644 --- a/src/GEOMGUI/GEOM_Displayer.cxx +++ b/src/GEOMGUI/GEOM_Displayer.cxx @@ -121,6 +121,9 @@ // of auto-color picking up #define SIMPLE_AUTOCOLOR +// Hard-coded value of shape deflection coefficient for VTK viewer +const double VTK_MIN_DEFLECTION = 0.001; + //================================================================ // Function : getActiveStudy // Purpose : Get active study, returns 0 if no open study frame @@ -323,6 +326,7 @@ GEOM_Displayer::GEOM_Displayer( SalomeApp_Study* st ) myShadingColor = SalomeApp_Tools::color( col ); myDisplayMode = resMgr->integerValue("Geometry", "display_mode", 0); + myHasDisplayMode = false; int aType = resMgr->integerValue("Geometry", "type_of_marker", (int)Aspect_TOM_PLUS); myWidth = resMgr->integerValue("Geometry", "edge_width", -1); @@ -342,10 +346,10 @@ GEOM_Displayer::GEOM_Displayer( SalomeApp_Study* st ) myToActivate = true; // This parameter is used for activisation/deactivisation of objects to be displayed - + #if OCC_VERSION_LARGE > 0x06050100 // Functionnality available only in OCCT 6.5.2 - // Activate parallel vizualisation only for testing purpose - // and if the corresponding env variable is set to 1 + // Activate parallel vizualisation only for testing purpose + // and if the corresponding env variable is set to 1 char* parallel_visu = getenv("PARALLEL_VISU"); if (parallel_visu && atoi(parallel_visu)) { @@ -393,7 +397,7 @@ void GEOM_Displayer::Display( const Handle(SALOME_InteractiveObject)& theIO, int aMgrId = getViewManagerId(vf); SalomeApp_Study* aStudy = getStudy(); - aStudy->setObjectProperty(aMgrId, theIO->getEntry(), VISIBILITY_PROP, 1 ); + aStudy->setObjectProperty(aMgrId, theIO->getEntry(), GEOM::propertyName( GEOM::Visibility ), 1 ); setVisibilityState(theIO->getEntry(), Qtx::ShownState); @@ -449,7 +453,7 @@ void GEOM_Displayer::Erase( const Handle(SALOME_InteractiveObject)& theIO, int aMgrId = getViewManagerId(vf); SalomeApp_Study* aStudy = getStudy(); - aStudy->setObjectProperty(aMgrId, theIO->getEntry(), VISIBILITY_PROP, 0 ); + aStudy->setObjectProperty(aMgrId, theIO->getEntry(), GEOM::propertyName( GEOM::Visibility ), 0 ); setVisibilityState(theIO->getEntry(), Qtx::HiddenState); } @@ -532,6 +536,371 @@ void GEOM_Displayer::Display( const SALOME_ListIO& theIOList, const bool updateV UpdateViewer(); } +Quantity_Color GEOM_Displayer::qColorFromResources( const QString& property, const QColor& defColor ) +{ + // VSR: this method can be improved in future: + // to improve performance, the default values from resource manager should be cached in the displayer + return SalomeApp_Tools::color( SUIT_Session::session()->resourceMgr()->colorValue( "Geometry", property, defColor ) ); +} + +QColor GEOM_Displayer::colorFromResources( const QString& property, const QColor& defColor ) +{ + // VSR: this method can be improved in future: + // to improve performance, the default values from resource manager should be cached in the displayer + return SUIT_Session::session()->resourceMgr()->colorValue( "Geometry", property, defColor ); +} + +void GEOM_Displayer::updateShapeProperties( const Handle(GEOM_AISShape)& AISShape, bool create ) +{ + // check that shape is not null + if ( AISShape.IsNull() ) return; + + // check that study is active + SalomeApp_Study* study = getStudy(); + if ( !study ) return; + + if ( myShape.ShapeType() != TopAbs_VERTEX && // fix pb with not displayed points + !TopoDS_Iterator(myShape).More() ) + return; // NPAL15983 (Bug when displaying empty groups) + + // set interactive object + + Handle( SALOME_InteractiveObject ) anIO; + + if ( !myIO.IsNull() ) { + AISShape->setIO( myIO ); + AISShape->SetOwner( myIO ); + anIO = myIO; + } + else if ( !myName.empty() ) { + // workaround to allow selection of temporary objects + static int tempId = 0; + anIO = new SALOME_InteractiveObject( QString( "TEMP_%1" ).arg( tempId++ ).toLatin1().data(), "GEOM", myName.c_str() ); + AISShape->setIO( anIO ); + AISShape->SetOwner( anIO ); + } + + // flag: only vertex or compound of vertices is processed (specific handling) + bool onlyVertex = myShape.ShapeType() == TopAbs_VERTEX || isCompoundOfVertices( myShape ); + // presentation study entry (empty for temporary objects like preview) + QString entry = !anIO.IsNull() ? QString( anIO->getEntry() ) : QString(); + // flag: temporary object + bool isTemporary = entry.isEmpty() || entry.startsWith( "TEMP_" ); + // currently active view window's ID (-1 if no active view) + int aMgrId = !anIO.IsNull() ? getViewManagerId( myViewFrame ) : -1; + + // get presentation properties + PropMap propMap = getObjectProperties( study, entry, myViewFrame ); + + // Temporary staff: vertex must be infinite for correct visualization + AISShape->SetInfiniteState( myShape.Infinite() ); // || myShape.ShapeType() == TopAbs_VERTEX // VSR: 05/04/2010: Fix 20668 (Fit All for points & lines) + + // set material + Material_Model material; + // if predefined color isn't set in displayer(via GEOM_Displayer::SetColor() function) + if( !HasColor() ) + material.fromProperties( propMap.value( GEOM::propertyName( GEOM::Material ) ).toString() ); + // - set front material properties + AISShape->SetCurrentFacingModel( Aspect_TOFM_FRONT_SIDE ); + AISShape->SetMaterial( material.getMaterialOCCAspect( true ) ); + // - set back material properties + AISShape->SetCurrentFacingModel( Aspect_TOFM_BACK_SIDE ); + AISShape->SetMaterial( material.getMaterialOCCAspect( false ) ); + // - switch to default (both sides) facing mode + AISShape->SetCurrentFacingModel( Aspect_TOFM_BOTH_SIDE ); + + // set colors + + // - shading color + if ( HasColor() ) { + // predefined color, manually set to displayer via GEOM_Displayer::SetColor() function; + // we set it to the shape not taking into account material properties + AISShape->SetShadingColor( (Quantity_NameOfColor)GetColor() ); + } + else if ( !material.isPhysical() ) { + // shading color from properties is used only for non-physical materials + AISShape->SetShadingColor( SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::ShadingColor ) ).value() ) ); + } + + // - wireframe color + Handle(Prs3d_LineAspect) anAspect = AISShape->Attributes()->LineAspect(); + anAspect->SetColor( HasColor() ? (Quantity_NameOfColor)GetColor() : + SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::WireframeColor ) ).value() ) ); + AISShape->Attributes()->SetLineAspect( anAspect ); + + // - unfree boundaries color + anAspect = AISShape->Attributes()->UnFreeBoundaryAspect(); + anAspect->SetColor( HasColor() ? (Quantity_NameOfColor)GetColor() : + SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::WireframeColor ) ).value() ) ); + AISShape->Attributes()->SetUnFreeBoundaryAspect( anAspect ); + + // - free boundaries color + anAspect = AISShape->Attributes()->FreeBoundaryAspect(); + anAspect->SetColor( HasColor() ? (Quantity_NameOfColor)GetColor() : + SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::FreeBndColor ) ).value() ) ); + AISShape->Attributes()->SetFreeBoundaryAspect( anAspect ); + + // - standalone edges color + anAspect = AISShape->Attributes()->WireAspect(); + anAspect->SetColor( HasColor() ? (Quantity_NameOfColor)GetColor() : + SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::LineColor ) ).value() ) ); + AISShape->Attributes()->SetWireAspect( anAspect ); + + // - color for edges in shading+edges mode + AISShape->SetEdgesInShadingColor( SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::OutlineColor ) ).value() ) ); + + // ??? + AISShape->storeBoundaryColors(); + + // set display mode + AISShape->SetDisplayMode( HasDisplayMode() ? + // predefined display mode, manually set to displayer via GEOM_Displayer::SetDisplayMode() function + GetDisplayMode() : + // display mode from properties + propMap.value( GEOM::propertyName( GEOM::DisplayMode ) ).toInt() ); + + // set display vectors flag + AISShape->SetDisplayVectors( propMap.value( GEOM::propertyName( GEOM::EdgesDirection ) ).toBool() ); + + // set transparency + // VSR: ??? next line is commented: transparency property is set in the AfterDisplay() function + //AISShape->SetTransparency( propMap.value( GEOM::propertyName( GEOM::Transparency ) ).toDouble() ); + + // set iso properties + int uIsos = propMap.value( GEOM::propertyName( GEOM::NbIsos ) ).toString().split( GEOM::subSectionSeparator() )[0].toInt(); + int vIsos = propMap.value( GEOM::propertyName( GEOM::NbIsos ) ).toString().split( GEOM::subSectionSeparator() )[1].toInt(); + Quantity_Color isosColor = SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::IsosColor ) ).value() ); + int isosWidth = propMap.value( GEOM::propertyName( GEOM::IsosWidth ) ).toInt(); + Handle(Prs3d_IsoAspect) uIsoAspect = AISShape->Attributes()->UIsoAspect(); + Handle(Prs3d_IsoAspect) vIsoAspect = AISShape->Attributes()->VIsoAspect(); + uIsoAspect->SetColor( isosColor ); + uIsoAspect->SetWidth( isosWidth ); + uIsoAspect->SetNumber( uIsos ); + vIsoAspect->SetColor( isosColor ); + vIsoAspect->SetWidth( isosWidth ); + vIsoAspect->SetNumber( vIsos ); + AISShape->Attributes()->SetUIsoAspect( uIsoAspect ); + AISShape->Attributes()->SetVIsoAspect( vIsoAspect ); + + // set deflection coefficient + // ... to avoid to small values of the coefficient, its lower value is limited + AISShape->SetOwnDeviationCoefficient( qMax( propMap.value( GEOM::propertyName( GEOM::Deflection ) ).toDouble(), GEOM::minDeflection() ) ); + + // set texture + if ( HasTexture() ) { + // predefined display texture, manually set to displayer via GEOM_Displayer::SetTexture() function + AISShape->SetTextureFileName( TCollection_AsciiString( GetTexture().c_str() ) ); + AISShape->SetTextureMapOn(); + AISShape->DisableTextureModulate(); + AISShape->SetDisplayMode( 3 ); + } + + // set line width + AISShape->SetWidth( HasWidth() ? + // predefined line width, manually set to displayer via GEOM_Displayer::SetLineWidth() function + GetWidth() : + // libe width from properties + propMap.value( GEOM::propertyName( GEOM::LineWidth ) ).toInt() ); + + // set top-level flag + AISShape->setTopLevel( propMap.value( GEOM::propertyName( GEOM::TopLevel ) ).toBool() ); + + // set point marker (for vertex / compound of vertices only) + if ( onlyVertex ) { + QStringList aList = propMap.value( GEOM::propertyName( GEOM::PointMarker ) ).toString().split( GEOM::subSectionSeparator() ); + if ( aList.size() == 2 ) { + // standard marker string contains "TypeOfMarker:ScaleOfMarker" + int aTypeOfMarker = aList[0].toInt(); + double aScaleOfMarker = (aList[1].toInt() + 1) * 0.5; + Handle(Prs3d_PointAspect) anAspect = AISShape->Attributes()->PointAspect(); + anAspect->SetScale( aScaleOfMarker ); + anAspect->SetTypeOfMarker( (Aspect_TypeOfMarker)( aTypeOfMarker-1 ) ); + anAspect->SetColor( HasColor() ? + // predefined color, manually set to displayer via GEOM_Displayer::SetColor() function + (Quantity_NameOfColor)GetColor() : + // color from properties + SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::PointColor ) ).value() ) ); + AISShape->Attributes()->SetPointAspect( anAspect ); + } + else if ( aList.size() == 1 ) { + // custom marker string contains "IdOfTexture" + int textureId = aList[0].toInt(); + Standard_Integer aWidth, aHeight; +#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 + Handle(TColStd_HArray1OfByte) aTexture = +#else + Handle(Graphic3d_HArray1OfBytes) aTexture = +#endif + GeometryGUI::getTexture( study, textureId, aWidth, aHeight ); + if ( !aTexture.IsNull() ) { + static int TextureId = 0; + Handle(Prs3d_PointAspect) aTextureAspect = + new Prs3d_PointAspect( HasColor() ? + // predefined color, manually set to displayer via GEOM_Displayer::SetColor() function + (Quantity_NameOfColor)GetColor() : + // color from properties + SalomeApp_Tools::color( propMap.value( GEOM::propertyName( GEOM::PointColor ) ).value() ), + ++TextureId, + aWidth, aHeight, + aTexture ); + AISShape->Attributes()->SetPointAspect( aTextureAspect ); + } + } + } + + if ( create && !isTemporary && aMgrId != -1 ) { + // set properties to the study + study->setObjectPropMap( aMgrId, entry, propMap ); + } + + // AISShape->SetName(???); ??? necessary to set name ??? +} + +void GEOM_Displayer::updateActorProperties( GEOM_Actor* actor, bool create ) +{ + // check that actor is not null + if ( !actor ) return; + + // check that study is active + SalomeApp_Study* study = getStudy(); + if ( !study ) return; + + // set interactive object + + Handle( SALOME_InteractiveObject ) anIO; + + if ( !myIO.IsNull() ) { + actor->setIO( myIO ); + anIO = myIO; + } + else if ( !myName.empty() ) { + // workaround to allow selection of temporary objects + static int tempId = 0; + anIO = new SALOME_InteractiveObject( QString( "TEMP_VTK_%1" ).arg( tempId++ ).toLatin1().data(), "GEOM", myName.c_str() ); + actor->setIO( anIO ); + } + + // presentation study entry (empty for temporary objects like preview) + QString entry = !anIO.IsNull() ? QString( anIO->getEntry() ) : QString(); + // flag: temporary object + bool isTemporary = entry.isEmpty() || entry.startsWith( "TEMP_" ); + // currently active view window's ID (-1 if no active view) + int aMgrId = !anIO.IsNull() ? getViewManagerId( myViewFrame ) : -1; + + // get presentation properties + PropMap propMap = getObjectProperties( study, entry, myViewFrame ); + QColor c; + + ///////////////////////////////////////////////////////////////////////// + // VSR: for VTK viewer currently deflection coefficient is hardcoded + // due to performance problem + // actor->SetShape(myShape,aDefPropMap.value(GEOM::propertyName( GEOM::Deflection )).toDouble(),myType == GEOM_VECTOR); + ///////////////////////////////////////////////////////////////////////// + if ( !actor->getTopo().IsSame( myShape ) ) + actor->SetShape( myShape, VTK_MIN_DEFLECTION, myType == GEOM_VECTOR ); + + // set material + Material_Model material; + material.fromProperties( propMap.value( GEOM::propertyName( GEOM::Material ) ).toString() ); + std::vector mprops; + mprops.push_back( material.getMaterialVTKProperty( true ) ); + mprops.push_back( material.getMaterialVTKProperty( false) ); + actor->SetMaterial( mprops ); + + // set iso-lines properties + + // - set number of iso-lines + int nbIsos[2]= { 1, 1 }; + QStringList isos = propMap.value( GEOM::propertyName( GEOM::NbIsos ) ).toString().split( GEOM::subSectionSeparator() ); + nbIsos[0] = isos[0].toInt(); + nbIsos[1] = isos[1].toInt(); + actor->SetNbIsos( nbIsos ); + + // - set iso-lines width + actor->SetIsosWidth( propMap.value( GEOM::propertyName( GEOM::IsosWidth ) ).toInt() ); + + // - set iso-lines color + c = propMap.value( GEOM::propertyName( GEOM::IsosColor ) ).value(); + actor->SetIsosColor( c.redF(), c.greenF(), c.blueF() ); + + // set colors + + if ( HasColor() ) { + // - same color for all sub-actors + Quantity_Color aColor( (Quantity_NameOfColor)GetColor() ); + actor->SetColor( aColor.Red(), aColor.Green(), aColor.Blue() ); + } + else { + // shading color (for non-physical materials) + if ( !material.isPhysical() ) { + c = propMap.value( GEOM::propertyName( GEOM::ShadingColor ) ).value(); + actor->GetFrontMaterial()->SetColor( c.redF(), c.greenF(), c.blueF() ); + actor->GetBackMaterial()->SetColor( c.redF(), c.greenF(), c.blueF() ); + } + + // - standalone edge color + c = propMap.value( GEOM::propertyName( GEOM::WireframeColor ) ).value(); + actor->SetIsolatedEdgeColor( c.redF(), c.greenF(), c.blueF() ); + + c = propMap.value( GEOM::propertyName( GEOM::WireframeColor ) ).value(); + // - shared edges color ??? + actor->SetSharedEdgeColor( c.redF(), c.greenF(), c.blueF() ); + + c = propMap.value( GEOM::propertyName( GEOM::FreeBndColor ) ).value(); + // - free edges color ??? + actor->SetFreeEdgeColor( c.redF(), c.greenF(), c.blueF() ); + + // - point color + c = propMap.value( GEOM::propertyName( GEOM::PointColor ) ).value(); + actor->SetPointColor( c.redF(), c.greenF(), c.blueF() ); + } + + // - color for edges in shading+edges mode + c = propMap.value( GEOM::propertyName( GEOM::OutlineColor ) ).value(); + actor->SetEdgesInShadingColor( c.redF(), c.greenF(), c.blueF() ); + + // set opacity + actor->SetOpacity( 1.0 - propMap.value( GEOM::propertyName( GEOM::Transparency ) ).toDouble() ); + + // set line width + actor->SetWidth( HasWidth() ? + // predefined line width, manually set to displayer via GEOM_Displayer::SetLineWidth() function + GetWidth() : + // libe width from properties + propMap.value( GEOM::propertyName( GEOM::LineWidth ) ).toInt() ); + + // set display vectors flag + actor->SetVectorMode( propMap.value( GEOM::propertyName( GEOM::EdgesDirection ) ).toBool() ); + + // set display mode + int displayMode = HasDisplayMode() ? + // predefined display mode, manually set to displayer via GEOM_Displayer::SetDisplayMode() function + GetDisplayMode() : + // display mode from properties + propMap.value( GEOM::propertyName( GEOM::DisplayMode ) ).toInt(); + + // specific processing of 'shading with edges' mode, as VTK provides only the following standard display modes: + // Points - 0, Wireframe - 1, Surface - 2, Insideframe - 3, SurfaceWithEdges - 4 + // GEOM actor allows alternative display modes (see VTKViewer::Representation enum) and enum in GEOM_Actor: + // eWireframe - 0, eShading - 1, eShadingWithEdges - 3 + + if ( displayMode == 2 ) + // this is 'Shading with edges' mode => we have to do the correct mapping to EDisplayMode + // enum in GEOM_Actor (and further to VTKViewer::Representation enum) + displayMode++; + actor->setDisplayMode( displayMode ); + + if ( myToActivate ) + actor->PickableOn(); + else + actor->PickableOff(); + + if ( create && !isTemporary && aMgrId != -1 ) { + // set properties to the study + study->setObjectPropMap( aMgrId, entry, propMap ); + } +} + //================================================================= /*! * GEOM_Displayer::Erase @@ -576,11 +945,17 @@ void GEOM_Displayer::Redisplay( const SALOME_ListIO& theIOList, const bool updat void GEOM_Displayer::Update( SALOME_OCCPrs* prs ) { SOCC_Prs* occPrs = dynamic_cast( prs ); - if ( !occPrs ) + SalomeApp_Study* study = getStudy(); + + if ( !occPrs || myShape.IsNull() || !study ) return; - if ( myType == GEOM_MARKER && !myShape.IsNull() && myShape.ShapeType() == TopAbs_FACE ) + if ( myType == GEOM_MARKER && myShape.ShapeType() == TopAbs_FACE ) { + // + // specific processing for local coordinate system presentation + // + TopoDS_Face aFace = TopoDS::Face( myShape ); Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast( BRep_Tool::Surface( aFace ) ); if ( !aPlane.IsNull() ) @@ -592,450 +967,99 @@ void GEOM_Displayer::Update( SALOME_OCCPrs* prs ) if ( occPrs->IsNull() ) { + // new presentation is being created aTrh = new GEOM_AISTrihedron( aPlc ); - - if ( HasColor() ) - aTrh->SetColor( (Quantity_NameOfColor)GetColor() ); - - if ( HasWidth() ) - aTrh->SetWidth( GetWidth() ); - - if ( !myIO.IsNull() ) - { - aTrh->setIO( myIO ); - aTrh->SetOwner( myIO ); - } - occPrs->AddObject( aTrh ); } else { + // presentation is being updated AIS_ListOfInteractive aList; occPrs->GetObjects( aList ); AIS_ListIteratorOfListOfInteractive anIter( aList ); - for ( ; anIter.More(); anIter.Next() ) - { + for ( ; anIter.More() && aTrh.IsNull(); anIter.Next() ) { aTrh = Handle(GEOM_AISTrihedron)::DownCast( anIter.Value() ); - if ( !aTrh.IsNull() ) - { - aTrh->SetComponent( aPlc ); - aTrh->SetToUpdate(); - } + } + } + + if ( !aTrh.IsNull() ) { + // predefined color, manually set to displayer via GEOM_Displayer::SetColor() function + if ( HasColor() ) + aTrh->SetColor( (Quantity_NameOfColor)GetColor() ); + // predefined line width, manually set to displayer via GEOM_Displayer::SetLineWidth() function + if ( HasWidth() ) + aTrh->SetWidth( GetWidth() ); + + if ( !myIO.IsNull() ) + { + aTrh->setIO( myIO ); + aTrh->SetOwner( myIO ); } + aTrh->SetComponent( aPlc ); + aTrh->SetToUpdate(); } - occPrs->SetToActivate( ToActivate() ); } } else { + // + // processing for usual geometry presentation + // + // if presentation is empty we try to create new one if ( occPrs->IsNull() ) { - SalomeApp_Study* aStudy = getStudy(); - if(!aStudy) - return; - if ( !myShape.IsNull() ) { - - bool onlyVertex = (myShape.ShapeType() == TopAbs_VERTEX || isCompoundOfVertices( myShape )); - - QString anEntry; - int aMgrId = -1; - if(!myIO.IsNull()) { - aMgrId = getViewManagerId(myViewFrame); - anEntry = myIO->getEntry(); - } - bool useStudy = !anEntry.isEmpty() && aMgrId != -1; - bool useObjColor = false; - bool useObjMarker = false; - - PropMap aPropMap; - PropMap aDefPropMap; - - //Handle(GEOM_AISShape) AISShape = new GEOM_AISShape( myShape, "" ); - Handle(GEOM_AISShape) AISShape; - if (myType == GEOM_VECTOR) - AISShape = new GEOM_AISVector (myShape, ""); - else { - if (myShape.ShapeType() != TopAbs_VERTEX && // fix pb with not displayed points - !TopoDS_Iterator(myShape).More()) - return;// NPAL15983 (Bug when displaying empty groups) - AISShape = new GEOM_AISShape (myShape, ""); - } - // Temporary staff: vertex must be infinite for correct visualization - AISShape->SetInfiniteState( myShape.Infinite() ); // || myShape.ShapeType() == TopAbs_VERTEX // VSR: 05/04/2010: Fix 20668 (Fit All for points & lines) - - if(useStudy){ - aPropMap = aStudy->getObjectPropMap(aMgrId,anEntry); - aDefPropMap = getDefaultPropertyMap(SOCC_Viewer::Type()); - Quantity_Color quant_col; - if(aPropMap.contains(COLOR_PROP)) { - quant_col = SalomeApp_Tools::color( aPropMap.value(COLOR_PROP).value()); - AISShape->SetShadingColor( quant_col ); - } else - useObjColor = true; - MergePropertyMaps(aPropMap, aDefPropMap); - if(!useObjColor && aPropMap.contains(COLOR_PROP)) { - quant_col = SalomeApp_Tools::color( aPropMap.value(COLOR_PROP).value()); - AISShape->SetShadingColor( quant_col ); - } - - // Setup shape properties here ..., e.g. display mode, color, transparency, etc - Standard_Boolean isTopLevel = Standard_False; - if(aPropMap.contains(TOP_LEVEL_PROP)) { - isTopLevel = aPropMap.value(TOP_LEVEL_PROP).value(); - } - AISShape->SetDisplayMode( aPropMap.value(DISPLAY_MODE_PROP).toInt() ); - AISShape->setTopLevel(isTopLevel); - - AISShape->SetDisplayVectors(aPropMap.value(VECTOR_MODE_PROP).toInt()); - }else { - AISShape->SetDisplayMode( myDisplayMode ); - AISShape->SetShadingColor( myShadingColor ); - } - - // Set color and number for iso lines - SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); - QColor col = aResMgr->colorValue( "Geometry", "isos_color", - QColor(int(0.5*255), int(0.5*255), int(0.5*255)) ); - Quantity_Color aColor = SalomeApp_Tools::color( col ); - - //get the ISOS number, set transparency if need - int anUIsoNumber, aVIsoNumber; - if(useStudy) { - QString anIsos = aPropMap.value(ISOS_PROP).toString(); - QStringList uv = anIsos.split(DIGIT_SEPARATOR); - anUIsoNumber = uv[0].toInt(); - aVIsoNumber = uv[1].toInt(); - AISShape->SetTransparency(aPropMap.value(TRANSPARENCY_PROP).toDouble()); - } else { - anUIsoNumber = aResMgr->integerValue("OCCViewer", "iso_number_u", 1); - aVIsoNumber = aResMgr->integerValue("OCCViewer", "iso_number_v", 1); - } - - Handle(Prs3d_IsoAspect) anAspect = AISShape->Attributes()->UIsoAspect(); - anAspect->SetNumber( anUIsoNumber ); - anAspect->SetColor( aColor ); - - if(HasIsosWidth()) - anAspect->SetWidth( GetIsosWidth() ); - AISShape->Attributes()->SetUIsoAspect( anAspect ); - anAspect = AISShape->Attributes()->VIsoAspect(); - anAspect->SetNumber( aVIsoNumber ); - if(HasIsosWidth()) - anAspect->SetWidth( GetIsosWidth() ); - anAspect->SetColor( aColor ); - AISShape->Attributes()->SetVIsoAspect( anAspect ); - - if ( HasColor() ) - { - AISShape->SetColor( (Quantity_NameOfColor)GetColor() ); - if ( onlyVertex ) - { - if(aPropMap.contains(MARKER_TYPE_PROP)) { - QStringList aList = aPropMap.value(MARKER_TYPE_PROP).toString().split(DIGIT_SEPARATOR); - if(aList.size() == 2) { //Standard marker string contains "TypeOfMarker:ScaleOfMarker" - Handle(Prs3d_PointAspect) anAspect = AISShape->Attributes()->PointAspect(); - int aTypeOfMarker = aList[0].toInt(); - double aScaleOfMarker = aList[1].toDouble(); - anAspect->SetScale( aScaleOfMarker ); - anAspect->SetTypeOfMarker((Aspect_TypeOfMarker) (aTypeOfMarker-1)); - anAspect->SetColor((Quantity_NameOfColor)GetColor()); - AISShape->Attributes()->SetPointAspect(anAspect); - } else { //Custom marker string contains "IdOfTexsture" - int textureId = aList[0].toInt(); - Standard_Integer aWidth, aHeight; -#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 - Handle(TColStd_HArray1OfByte) aTexture = -#else - Handle(Graphic3d_HArray1OfBytes) aTexture = -#endif - GeometryGUI::getTexture(aStudy, textureId, aWidth, aHeight); - if (!aTexture.IsNull()) { - static int TextureId = 0; - Handle(Prs3d_PointAspect) aTextureAspect = - new Prs3d_PointAspect ((Quantity_NameOfColor)GetColor(), - ++TextureId, - aWidth, aHeight, - aTexture); - AISShape->Attributes()->SetPointAspect(aTextureAspect); - } else { - useObjMarker = true; - } - } - } else { - useObjMarker = true; - } - } - } - else - { - if ( onlyVertex ) - { - col = aResMgr->colorValue( "Geometry", "point_color", QColor( 255, 255, 0 ) ); - aColor = SalomeApp_Tools::color( col ); - - if(aPropMap.contains(MARKER_TYPE_PROP)) { - QStringList aList = aPropMap.value(MARKER_TYPE_PROP).toString().split(DIGIT_SEPARATOR); - if(aList.size() == 2) { //Standard marker string contains "TypeOfMarker:ScaleOfMarker" - int aTypeOfMarker = aList[0].toInt(); - double aScaleOfMarker = aList[1].toDouble(); - Handle(Prs3d_PointAspect) anAspect = AISShape->Attributes()->PointAspect(); - anAspect->SetScale( aScaleOfMarker ); - anAspect->SetTypeOfMarker((Aspect_TypeOfMarker) (aTypeOfMarker-1) ); - anAspect->SetColor( aColor ); - AISShape->Attributes()->SetPointAspect( anAspect ); - } else { //Custom marker string contains "IdOfTexsture" - int textureId = aList[0].toInt(); - Standard_Integer aWidth, aHeight; -#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 - Handle(TColStd_HArray1OfByte) aTexture = -#else - Handle(Graphic3d_HArray1OfBytes) aTexture = -#endif - GeometryGUI::getTexture(aStudy, textureId, aWidth, aHeight); - if (!aTexture.IsNull()) { - static int TextureId = 0; - Handle(Prs3d_PointAspect) aTextureAspect = - new Prs3d_PointAspect (aColor, ++TextureId, aWidth, aHeight, aTexture); - AISShape->Attributes()->SetPointAspect( aTextureAspect ); - } else { - useObjMarker = true; - } - } - } else { - useObjMarker = true; - } - } - else { - // Set line aspect - col = aResMgr->colorValue( "Geometry", "wireframe_color", QColor( 255, 255, 0 ) ); - aColor = SalomeApp_Tools::color( col ); - - Handle(Prs3d_LineAspect) anAspect = AISShape->Attributes()->LineAspect(); - anAspect->SetColor( aColor ); - AISShape->Attributes()->SetLineAspect( anAspect ); - - // Set unfree boundaries aspect - anAspect = AISShape->Attributes()->UnFreeBoundaryAspect(); - anAspect->SetColor( aColor ); - AISShape->Attributes()->SetUnFreeBoundaryAspect( anAspect ); - AISShape->storeBoundaryColors(); - - // Set free boundaries aspect - col = aResMgr->colorValue( "Geometry", "free_bound_color", QColor( 0, 255, 0 ) ); - aColor = SalomeApp_Tools::color( col ); - - anAspect = AISShape->Attributes()->FreeBoundaryAspect(); - anAspect->SetColor( aColor ); - AISShape->Attributes()->SetFreeBoundaryAspect( anAspect ); - - // Set wire aspect - col = aResMgr->colorValue( "Geometry", "line_color", QColor( 255, 0, 0 ) ); - aColor = SalomeApp_Tools::color( col ); - - anAspect = AISShape->Attributes()->WireAspect(); - anAspect->SetColor( aColor ); - AISShape->Attributes()->SetWireAspect( anAspect ); - - // Set color for edges in shading - col = aResMgr->colorValue( "Geometry", "edges_in_shading_color", QColor( 255, 255, 0 ) ); - aColor = SalomeApp_Tools::color( col ); - AISShape->SetEdgesInShadingColor( aColor ); - - // bug [SALOME platform 0019868] - // Set deviation angle. Default one is 12 degrees (Prs3d_Drawer.cxx:18) - //AISShape->SetOwnDeviationAngle( 10*PI/180 ); - - // IMP 0020626 - double aDC = 0; - if(useStudy) { - aDC = aPropMap.value(DEFLECTION_COEFF_PROP).toDouble(); - SetWidth(aPropMap.value(EDGE_WIDTH_PROP).toInt()); - SetIsosWidth(aPropMap.value(ISOS_WIDTH_PROP).toInt()); - } - else { - aDC = aResMgr->doubleValue("Geometry", "deflection_coeff", 0.001); - } - - aDC = std::max( aDC, DEFLECTION_MIN ); // to avoid to small values of the coefficient - AISShape->SetOwnDeviationCoefficient(aDC); - } - } - - if ( HasTexture() ) - { - AISShape->SetTextureFileName(TCollection_AsciiString(myTexture.c_str())); - AISShape->SetTextureMapOn(); - AISShape->DisableTextureModulate(); - AISShape->SetDisplayMode(3); - } - - if ( HasWidth() ) - AISShape->SetWidth( GetWidth() ); - - if ( !myIO.IsNull() ) - { - AISShape->setIO( myIO ); - AISShape->SetOwner( myIO ); - } - else if ( !myName.empty() ) - { - // Workaround to allow selection of temporary objects - static int tempId = 0; - char buf[50]; - sprintf( buf, "TEMP_%d", tempId++ ); - Handle( SALOME_InteractiveObject ) anObj = - new SALOME_InteractiveObject( buf, "GEOM", myName.c_str() ); - AISShape->setIO( anObj ); - AISShape->SetOwner( anObj ); - } + // create presentation (specific for vectors) + Handle(GEOM_AISShape) AISShape = ( myType == GEOM_VECTOR ) ? new GEOM_AISVector( myShape, "" ) + : new GEOM_AISShape ( myShape, "" ); + // update shape properties + updateShapeProperties( AISShape, true ); - Handle( SALOME_InteractiveObject ) anIO = AISShape->getIO(); - if ( !anIO.IsNull() ) { - _PTR(SObject) SO ( aStudy->studyDS()->FindObjectID( anIO->getEntry() ) ); - if ( SO ) { - // get CORBA reference to data object - CORBA::Object_var object = GeometryGUI::ClientSObjectToObject(SO); - if ( !CORBA::is_nil( object ) ) { - // downcast to GEOM object - GEOM::GEOM_Object_var aGeomObject = GEOM::GEOM_Object::_narrow( object ); - bool hasColor = false; - SALOMEDS::Color aSColor = getColor(aGeomObject,hasColor); - if( hasColor && useObjColor) { - Quantity_Color aQuanColor( aSColor.R, aSColor.G, aSColor.B, Quantity_TOC_RGB ); - AISShape->SetColor( aQuanColor ); - AISShape->SetShadingColor( aQuanColor ); - if ( onlyVertex ) { - Handle(Prs3d_PointAspect) anAspect = AISShape->Attributes()->PointAspect(); - anAspect->SetColor( aQuanColor ); - anAspect->SetScale( myScaleOfMarker ); - anAspect->SetTypeOfMarker( myTypeOfMarker ); - AISShape->Attributes()->SetPointAspect( anAspect ); - } - aStudy->setObjectProperty( aMgrId, anIO->getEntry(), COLOR_PROP, SalomeApp_Tools::color( aQuanColor ) ); - } else if( !hasColor ) { - //In case if color wasn't defined in the property map of the object - //and GEOM_Object color also wasn't defined get default color from Resource Mgr. - QColor col = aResMgr->colorValue( "Geometry", "shading_color", QColor( 255, 0, 0 ) ); - Quantity_Color aQuanColor = SalomeApp_Tools::color( col ); - AISShape->SetShadingColor( aQuanColor ); - aStudy->setObjectProperty( aMgrId, anIO->getEntry(), COLOR_PROP, col ); - } - - // ... marker type - if(useObjMarker) { - GEOM::marker_type aType = aGeomObject->GetMarkerType(); - GEOM::marker_size aSize = aGeomObject->GetMarkerSize(); - if ( aType > GEOM::MT_NONE && aType < GEOM::MT_USER && aSize > GEOM::MS_NONE && aSize <= GEOM::MS_70 ) { - Aspect_TypeOfMarker aMType = (Aspect_TypeOfMarker)( (int)aType-1 ); - double aMSize = ((int)aSize+1)*0.5; - Handle(Prs3d_PointAspect) anAspect = AISShape->Attributes()->PointAspect(); - anAspect->SetScale( aMSize ); - anAspect->SetTypeOfMarker( aMType ); - Quantity_Color aQuanColor = SalomeApp_Tools::color( aResMgr->colorValue( "Geometry", "point_color", QColor( 255, 255, 0 ) ) ); - if ( hasColor ) - aQuanColor = Quantity_Color( aSColor.R, aSColor.G, aSColor.B, Quantity_TOC_RGB ); - anAspect->SetColor( aQuanColor ); - AISShape->Attributes()->SetPointAspect( anAspect ); - } - else if ( aType == GEOM::MT_USER ) { - int aTextureId = aGeomObject->GetMarkerTexture(); - Quantity_Color aQuanColor = SalomeApp_Tools::color( aResMgr->colorValue( "Geometry", "point_color", QColor( 255, 255, 0 ) ) ); - if ( hasColor ) aQuanColor = Quantity_Color( aSColor.R, aSColor.G, aSColor.B, Quantity_TOC_RGB ); - Standard_Integer aWidth, aHeight; -#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 - Handle(TColStd_HArray1OfByte) aTexture = -#else - Handle(Graphic3d_HArray1OfBytes) aTexture = -#endif - GeometryGUI::getTexture(getStudy(), aTextureId, aWidth, aHeight); - if (!aTexture.IsNull()) { - static int TextureId = 0; - Handle(Prs3d_PointAspect) aTextureAspect = - new Prs3d_PointAspect(aQuanColor, ++TextureId, aWidth, aHeight, aTexture ); - AISShape->Attributes()->SetPointAspect( aTextureAspect ); - } - } else { //Use marker from the preferences - Handle(Prs3d_PointAspect) anAspect = AISShape->Attributes()->PointAspect(); - anAspect->SetScale( myScaleOfMarker ); - anAspect->SetTypeOfMarker( myTypeOfMarker ); - Quantity_Color aQuanColor = SalomeApp_Tools::color( aResMgr->colorValue( "Geometry", "point_color", QColor( 255, 255, 0 ) ) ); - if ( hasColor ) - aQuanColor = Quantity_Color( aSColor.R, aSColor.G, aSColor.B, Quantity_TOC_RGB ); - anAspect->SetColor( aQuanColor ); - AISShape->Attributes()->SetPointAspect( anAspect ); - } - } - } - } + // add shape to the presentation + occPrs->AddObject( AISShape ); - // get material properties, set material - Material_Model material; - if ( useStudy ) { - // Get material property from study and construct material model - material.fromProperties( aPropMap.value(MATERIAL_PROP).toString() ); - } else { - // Get material property from study and construct material model - QString mname = aResMgr->stringValue( "Geometry", "material", "Plastic" ); - material.fromResources( mname ); - } + // In accordance with ToActivate() value object will be activated/deactivated + // when it will be displayed + occPrs->SetToActivate( ToActivate() ); - aStudy->setObjectProperty( aMgrId, anIO->getEntry(), MATERIAL_PROP, material.toProperties() ); + if ( AISShape->isTopLevel() && GEOM_AISShape::topLevelDisplayMode() == GEOM_AISShape::TopShowAdditionalWActor ) { + // 21671: EDF 1829 GEOM : Bring to front selected objects (continuation): - // Set material for the selected shape - AISShape->SetMaterial( material.getMaterialOCCAspect() ); - if(HasWidth()) - aStudy->setObjectProperty( aMgrId, anIO->getEntry(), EDGE_WIDTH_PROP, GetWidth() ); - if(HasIsosWidth()) - aStudy->setObjectProperty( aMgrId, anIO->getEntry(), ISOS_WIDTH_PROP, GetIsosWidth() ); - } + // create additional wireframe shape + Handle(GEOM_TopWireframeShape) aWirePrs = new GEOM_TopWireframeShape(myShape); + aWirePrs->SetWidth(AISShape->Width()); + if ( !myIO.IsNull() ) { + aWirePrs->setIO( myIO ); + aWirePrs->SetOwner( myIO ); + } - // AISShape->SetName(???); ??? necessary to set name ??? - occPrs->AddObject( AISShape ); - - // In accordance with ToActivate() value object will be activated/deactivated - // when it will be displayed - occPrs->SetToActivate( ToActivate() ); - - if( AISShape->isTopLevel() && AISShape->topLevelDisplayMode() == GEOM_AISShape::TopShowAdditionalWActor) { - //21671: EDF 1829 GEOM : Bring to front selected objects (continuation): - // Display wireframe presentation additionally - Handle(GEOM_TopWireframeShape) aWirePrs = new GEOM_TopWireframeShape(myShape); - aWirePrs->SetWidth(AISShape->Width()); - if ( !myIO.IsNull() ) { - aWirePrs->setIO( myIO ); - aWirePrs->SetOwner( myIO ); - } - occPrs->AddObject(aWirePrs); - } + // add shape to the presentation + occPrs->AddObject( aWirePrs ); } } // if presentation is found -> set again shape for it else { - if ( !myShape.IsNull() ) + AIS_ListOfInteractive IOList; + occPrs->GetObjects( IOList ); + AIS_ListIteratorOfListOfInteractive Iter( IOList ); + for ( ; Iter.More(); Iter.Next() ) { - AIS_ListOfInteractive IOList; - occPrs->GetObjects( IOList ); - AIS_ListIteratorOfListOfInteractive Iter( IOList ); - for ( ; Iter.More(); Iter.Next() ) - { - Handle(GEOM_AISShape) AISShape = Handle(GEOM_AISShape)::DownCast( Iter.Value() ); - if ( AISShape.IsNull() ) - continue; - if ( AISShape->Shape() != myShape ) - { - AISShape->Set( myShape ); - AISShape->UpdateSelection(); - AISShape->SetToUpdate(); - } - if ( !myIO.IsNull() ) - { - AISShape->setIO( myIO ); - AISShape->SetOwner( myIO ); - } - } + Handle(GEOM_AISShape) AISShape = Handle(GEOM_AISShape)::DownCast( Iter.Value() ); + if ( AISShape.IsNull() ) + continue; + + // re-set shape (it might be changed) + if ( AISShape->Shape() != myShape ) + AISShape->Set( myShape ); + + // update shape properties + updateShapeProperties( AISShape, false ); + + // force updating + AISShape->UpdateSelection(); + AISShape->SetToUpdate(); } } } @@ -1050,224 +1074,99 @@ void GEOM_Displayer::Update( SALOME_OCCPrs* prs ) //================================================================= void GEOM_Displayer::Update( SALOME_VTKPrs* prs ) { - SalomeApp_Study* aStudy = getStudy(); - int aMgrId = -1; SVTK_Prs* vtkPrs = dynamic_cast( prs ); + SalomeApp_Study* study = getStudy(); - if ( !vtkPrs || myShape.IsNull() || !aStudy) + if ( !vtkPrs || myShape.IsNull() || !study ) return; - bool useStudy = false; - bool useObjCol = false; - PropMap aPropMap; - - vtkActorCollection* theActors = 0; - - QString anEntry; - if(!myIO.IsNull()) { - anEntry = myIO->getEntry(); - } - - if ( myType == GEOM_MARKER && myShape.ShapeType() == TopAbs_FACE ) { - //myToActivate = false; // ouv: commented to make the trihedron pickable (see IPAL18657) - GEOM_VTKTrihedron* aTrh = GEOM_VTKTrihedron::New(); - - if ( HasColor() ) { - Quantity_Color aColor( (Quantity_NameOfColor)GetColor() ); - aTrh->SetColor( aColor.Red(), aColor.Green(), aColor.Blue() ); - } - - Handle(Geom_Plane) aPlane = - Handle(Geom_Plane)::DownCast( BRep_Tool::Surface( TopoDS::Face( myShape ) ) ); - if ( aPlane.IsNull() ) - return; - - gp_Ax2 anAx2 = aPlane->Pln().Position().Ax2(); - aTrh->SetPlacement( new Geom_Axis2Placement( anAx2 ) ); - - // if ( SVTK_Viewer* vf = dynamic_cast( GetActiveView() ) ) - // aTrh->SetSize( 0.5 * vf->GetTrihedronSize() ); - - vtkPrs->AddObject( aTrh ); + if ( myType == GEOM_MARKER && myShape.ShapeType() == TopAbs_FACE ) + { + // + // specific processing for local coordinate system presentation + // - theActors = vtkActorCollection::New(); - theActors->AddItem( aTrh ); - } - else { - PropMap aDefPropMap = getDefaultPropertyMap(SVTK_Viewer::Type()); + TopoDS_Face aFace = TopoDS::Face( myShape ); + Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast( BRep_Tool::Surface( aFace ) ); + if ( !aPlane.IsNull() ) { + gp_Ax3 aPos = aPlane->Pln().Position(); + Handle(Geom_Axis2Placement) aPlc = new Geom_Axis2Placement( aPos.Ax2() ); - if(!myIO.IsNull()) { - aMgrId = getViewManagerId(myViewFrame); - } - useStudy = !anEntry.isEmpty() && aMgrId != -1; + GEOM_VTKTrihedron* aTrh = 0; + if ( vtkPrs->IsNull() ) { + // new presentation is being created + aTrh = GEOM_VTKTrihedron::New(); + vtkPrs->AddObject( aTrh ); + } + else { + // presentation is being updated + vtkActorCollection* actors = vtkPrs->GetObjects(); + if ( actors ) { + actors->InitTraversal(); + vtkActor* a = actors->GetNextActor(); + while ( a && !aTrh ) { + aTrh = GEOM_VTKTrihedron::SafeDownCast( a ); + a = actors->GetNextActor(); + } + } + } + + if ( aTrh ) { + // predefined color, manually set to displayer via GEOM_Displayer::SetColor() function + if ( HasColor() ) { + Quantity_Color aColor( (Quantity_NameOfColor)GetColor() ); + aTrh->SetColor( aColor.Red(), aColor.Green(), aColor.Blue() ); + } +#ifdef VTK_TRIHEDRON_WIDTH + // + // VSR: currently isn't supported + // + // predefined line width, manually set to displayer via GEOM_Displayer::SetLineWidth() function + if ( HasWidth() ) + aTrh->SetWidth( GetWidth() ); +#endif - theActors = vtkActorCollection::New(); - GEOM_Actor* aGeomActor = GEOM_Actor::New(); - aGeomActor->SetShape(myShape,aDefPropMap.value(DEFLECTION_COEFF_PROP).toDouble(),myType == GEOM_VECTOR); - theActors->AddItem(aGeomActor); - aGeomActor->Delete(); + if ( !myIO.IsNull() ) + aTrh->setIO( myIO ); - if(useStudy) { - aPropMap = aStudy->getObjectPropMap(aMgrId,anEntry); - if(!aPropMap.contains(COLOR_PROP)) - useObjCol = true; - MergePropertyMaps(aPropMap, aDefPropMap); + aTrh->SetPlacement( aPlc ); + } } } - - theActors->InitTraversal(); - - vtkActor* anActor = (vtkActor*)theActors->GetNextActor(); - - vtkProperty* aProp = 0; - - if ( HasColor() || HasWidth() ) - { - aProp = vtkProperty::New(); - aProp->SetRepresentationToWireframe(); - } - - if ( HasColor() ) - { - Quantity_Color aColor( (Quantity_NameOfColor)GetColor() ); - aProp->SetColor( aColor.Red(), aColor.Green(), aColor.Blue() ); - } - - while ( anActor != NULL ) + else { - SALOME_Actor* GActor = SALOME_Actor::SafeDownCast( anActor ); - - GActor->setIO( myIO ); + // + // processing for usual geometry presentation + // - if ( aProp ) + // if presentation is empty we try to create new one + if ( vtkPrs->IsNull() ) { - GActor->SetProperty( aProp ); - GActor->SetPreviewProperty( aProp ); + // create an actor + GEOM_Actor* actor = GEOM_Actor::New(); + // update actor properties + updateActorProperties( actor, true ); + // add actor to the presentation + vtkPrs->AddObject( actor ); } - - GEOM_Actor* aGeomGActor = GEOM_Actor::SafeDownCast( anActor ); - if ( aGeomGActor != 0 ) - { - if ( aProp ) { - aGeomGActor->SetShadingProperty( aProp ); - aGeomGActor->SetWireframeProperty( aProp ); - } - - // Set color for edges in shading - SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); - if(aResMgr) { - QColor c = aResMgr->colorValue( "Geometry", "edges_in_shading_color", QColor( 255, 255, 0 ) ); - aGeomGActor->SetEdgesInShadingColor( c.red()/255., c.green()/255., c.blue()/255. ); - } - - int aIsos[2]= { 1, 1 }; - if(useStudy) { - QString anIsos = aPropMap.value(ISOS_PROP).toString(); - QStringList uv = anIsos.split(DIGIT_SEPARATOR); - aIsos[0] = uv[0].toInt(); aIsos[1] = uv[1].toInt(); - aGeomGActor->SetNbIsos(aIsos); - aGeomGActor->SetOpacity(1.0 - aPropMap.value(TRANSPARENCY_PROP).toDouble()); - SetWidth(aPropMap.value(EDGE_WIDTH_PROP).toInt()); - SetIsosWidth(aPropMap.value(ISOS_WIDTH_PROP).toInt()); - aGeomGActor->SetVectorMode(aPropMap.value(VECTOR_MODE_PROP).toInt()); - int aDispModeId = aPropMap.value(DISPLAY_MODE_PROP).toInt(); - // Specially processing of 'Shading with edges' mode from preferences, - // because there is the following enum in VTK viewer: - // Points - 0, Wireframe - 1, Surface - 2, Insideframe - 3, SurfaceWithEdges - 4 - // (see VTKViewer::Representation enum) and the following enum in GEOM_Actor: - // eWireframe - 0, eShading - 1, eShadingWithEdges - 3 - if ( aDispModeId == 2 ) - // this is 'Shading with edges' mode => do the correct mapping to EDisplayMode - // enum in GEOM_Actor (and further to VTKViewer::Representation enum) - aDispModeId++; - aGeomGActor->setDisplayMode(aDispModeId); - aGeomGActor->SetDeflection(aPropMap.value(DEFLECTION_COEFF_PROP).toDouble()); - - // Create material model - Material_Model material; - material.fromProperties( aPropMap.value(MATERIAL_PROP).toString() ); - // Set material properties for the object - aStudy->setObjectProperty( aMgrId, anEntry, MATERIAL_PROP, material.toProperties() ); - // Set the same front and back materials for the selected shape - std::vector aProps; - aProps.push_back( material.getMaterialVTKProperty() ); - aGeomGActor->SetMaterial(aProps); - - vtkFloatingPointType aColor[3] = {1.,0.,0.}; - if ( useObjCol ) { //Get Color from geom object - Handle( SALOME_InteractiveObject ) anIO = aGeomGActor->getIO(); - if ( !anIO.IsNull() ) { - _PTR(SObject) SO ( aStudy->studyDS()->FindObjectID( anIO->getEntry() ) ); - if ( SO ) { - // get CORBA reference to data object - CORBA::Object_var object = GeometryGUI::ClientSObjectToObject(SO); - if ( !CORBA::is_nil( object ) ) { - // downcast to GEOM object - GEOM::GEOM_Object_var aGeomObject = GEOM::GEOM_Object::_narrow( object ); - bool hasColor = false; - SALOMEDS::Color aSColor = getColor(aGeomObject,hasColor); - if(hasColor) { - aColor[0] = aSColor.R; aColor[1] = aSColor.G; aColor[2] = aSColor.B; - } else { - SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); - if(aResMgr) { - QColor c = aResMgr->colorValue( "Geometry", "shading_color", QColor( 255, 0, 0 ) ); - aColor[0] = c.red()/255.; aColor[1] = c.green()/255.; aColor[2] = c.blue()/255.; - } - } - aStudy->setObjectProperty( aMgrId, anIO->getEntry(), COLOR_PROP, QColor( aColor[0] *255, aColor[1] * 255, aColor[2]* 255) ); - } - } - } - } else { - QColor c = aPropMap.value(COLOR_PROP).value(); - aColor[0] = c.red()/255.; aColor[1] = c.green()/255.; aColor[2] = c.blue()/255.; - } - - if ( !material.isPhysical() ) - aGeomGActor->SetColor(aColor[0],aColor[1],aColor[2]); - } - else { - SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); - if ( aResMgr ) { - // Create material model - Material_Model material; - // Get material name from resources - QString mname = aResMgr->stringValue( "Geometry", "material", "Plastic" ); - material.fromResources( mname ); - // Set material properties for the object - aStudy->setObjectProperty( aMgrId, anEntry, MATERIAL_PROP, material.toProperties() ); - // Set material for the selected shape - std::vector aProps; - aProps.push_back( material.getMaterialVTKProperty() ); - aGeomGActor->SetMaterial(aProps); - } + else { + // presentation is being updated + vtkActorCollection* actors = vtkPrs->GetObjects(); + if ( actors ) { + actors->InitTraversal(); + vtkActor* a = actors->GetNextActor(); + while ( a ) { + GEOM_Actor* actor = GEOM_Actor::SafeDownCast( a ); + if ( actor ) { + // update actor properties + updateActorProperties( actor, false ); + a = actors->GetNextActor(); + } + } } } - if ( aGeomGActor ) - { - if ( HasWidth() ) - aGeomGActor->SetWidth( GetWidth() ); - - if ( HasIsosWidth() ) - aGeomGActor->SetIsosWidth( GetIsosWidth() ); - } - - if ( myToActivate ) - GActor->PickableOn(); - else - GActor->PickableOff(); - - vtkPrs->AddObject( GActor ); - - anActor = (vtkActor*)theActors->GetNextActor(); } - - if ( aProp ) - aProp->Delete(); - - theActors->Delete(); } //================================================================= @@ -1625,8 +1524,8 @@ void GEOM_Displayer::AfterDisplay( SALOME_View* v, const SALOME_OCCPrs* p ) Handle(SALOME_InteractiveObject) IO = sh->getIO(); if ( IO.IsNull() ) continue; PropMap aPropMap = aStudy->getObjectPropMap( aMgrId, IO->getEntry() ); - if ( aPropMap.contains( TRANSPARENCY_PROP ) ) { - double transparency = aPropMap.value(TRANSPARENCY_PROP).toDouble(); + if ( aPropMap.contains( GEOM::propertyName( GEOM::Transparency ) ) ) { + double transparency = aPropMap.value(GEOM::propertyName( GEOM::Transparency )).toDouble(); ic->SetTransparency( sh, transparency, true ); } } @@ -1728,7 +1627,7 @@ int GEOM_Displayer::GetIsosWidth() const return myIsosWidth; } -void GEOM_Displayer::SetIsosWidth(const int width) +void GEOM_Displayer::SetIsosWidth(const int width) { myIsosWidth = width; } @@ -1807,12 +1706,12 @@ bool GEOM_Displayer::canBeDisplayed( const QString& entry, const QString& viewer int GEOM_Displayer::SetDisplayMode( const int theMode ) { int aPrevMode = myDisplayMode; - if ( theMode != -1 ) + if ( theMode != -1 ) { myDisplayMode = theMode; - else - { - SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); - myDisplayMode = resMgr->integerValue( "Geometry", "display_mode", 0 ); + myHasDisplayMode = true; + } + else { + UnsetDisplayMode(); } return aPrevMode; } @@ -1827,9 +1726,15 @@ int GEOM_Displayer::UnsetDisplayMode() int aPrevMode = myDisplayMode; SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); myDisplayMode = resMgr->integerValue( "Geometry", "display_mode", 0 ); + myHasDisplayMode = false; return aPrevMode; } +bool GEOM_Displayer::HasDisplayMode() const +{ + return myHasDisplayMode; +} + SALOMEDS::Color GEOM_Displayer::getPredefinedUniqueColor() { static QList colors; @@ -1918,122 +1823,171 @@ SALOMEDS::Color GEOM_Displayer::getUniqueColor( const QList& th return aSColor; } +PropMap GEOM_Displayer::getObjectProperties( SalomeApp_Study* study, + const QString& entry, + SALOME_View* view ) +{ + // get default properties for the explicitly specified default view type + PropMap propMap = GEOM_Displayer::getDefaultPropertyMap(); + if ( study && view ) { + SUIT_ViewModel* viewModel = dynamic_cast( view ); + SUIT_ViewManager* viewMgr = ( viewModel != 0 ) ? viewModel->getViewManager() : 0; + int viewId = ( viewMgr != 0 ) ? viewMgr->getGlobalId() : -1; + + if ( viewModel && viewId != -1 ) { + // get properties from the study + PropMap storedMap = study->getObjectPropMap( viewId, entry ); + // overwrite default properties from stored ones (that are specified) + for ( int prop = GEOM::Visibility; prop <= GEOM::LastProperty; prop++ ) { + if ( storedMap.contains( GEOM::propertyName( (GEOM::Property)prop ) ) ) + propMap.insert( GEOM::propertyName( (GEOM::Property)prop ), + storedMap.value( GEOM::propertyName( (GEOM::Property)prop ) ) ); + } + // ... specific processing for color + // ... current implementation is to use same stored color for all aspects + // ... (TODO) possible future improvements about free boundaries, standalone edges etc colors can be here + if ( storedMap.contains( GEOM::propertyName( GEOM::Color ) ) ) { + propMap.insert( GEOM::propertyName( GEOM::ShadingColor ), storedMap.value( GEOM::propertyName( GEOM::Color ) ) ); + propMap.insert( GEOM::propertyName( GEOM::WireframeColor ), storedMap.value( GEOM::propertyName( GEOM::Color ) ) ); + propMap.insert( GEOM::propertyName( GEOM::LineColor ), storedMap.value( GEOM::propertyName( GEOM::Color ) ) ); + propMap.insert( GEOM::propertyName( GEOM::FreeBndColor ), storedMap.value( GEOM::propertyName( GEOM::Color ) ) ); + propMap.insert( GEOM::propertyName( GEOM::PointColor ), storedMap.value( GEOM::propertyName( GEOM::Color ) ) ); + } -PropMap GEOM_Displayer::getDefaultPropertyMap(const QString& viewer_type) { - PropMap aDefaultMap; - SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); - //1. Visibility - aDefaultMap.insert(VISIBILITY_PROP , 1); - - //2. Nb Isos - int anUIsoNumber; - int aVIsoNumber; - if(viewer_type == SOCC_Viewer::Type()) { - anUIsoNumber = aResMgr->integerValue("OCCViewer", "iso_number_u", 1); - aVIsoNumber = aResMgr->integerValue("OCCViewer", "iso_number_v", 1); - } else if( viewer_type==SVTK_Viewer::Type()) { - anUIsoNumber = aResMgr->integerValue("VTKViewer", "iso_number_u", 1); - aVIsoNumber = aResMgr->integerValue("VTKViewer", "iso_number_u", 1); + if ( !entry.isEmpty() ) { + // get CORBA reference to geom object + _PTR(SObject) SO( study->studyDS()->FindObjectID( entry.toStdString() ) ); + if ( SO ) { + CORBA::Object_var object = GeometryGUI::ClientSObjectToObject( SO ); + if ( !CORBA::is_nil( object ) ) { + GEOM::GEOM_Object_var geomObject = GEOM::GEOM_Object::_narrow( object ); + // check that geom object has color properly set + bool hasColor = false; + SALOMEDS::Color aSColor = getColor( geomObject, hasColor ); + // set color from geometry object (only once, if it is not yet set in GUI) + // current implementation is to use same color for all aspects + // (TODO) possible future improvements about free boundaries, standalone edges etc colors can be here + if ( hasColor && !storedMap.contains( GEOM::propertyName( GEOM::Color ) ) ) { + QColor objColor = QColor::fromRgbF( aSColor.R, aSColor.G, aSColor.B ); + propMap.insert( GEOM::propertyName( GEOM::ShadingColor ), objColor ); + propMap.insert( GEOM::propertyName( GEOM::WireframeColor ), objColor ); + propMap.insert( GEOM::propertyName( GEOM::LineColor ), objColor ); + propMap.insert( GEOM::propertyName( GEOM::FreeBndColor ), objColor ); + propMap.insert( GEOM::propertyName( GEOM::PointColor ), objColor ); + } + // check that object has point marker properly set + GEOM::marker_type mType = geomObject->GetMarkerType(); + GEOM::marker_size mSize = geomObject->GetMarkerSize(); + int mTextureId = geomObject->GetMarkerTexture(); + bool hasMarker = ( mType > GEOM::MT_NONE && mType < GEOM::MT_USER && mSize > GEOM::MS_NONE && mSize <= GEOM::MS_70 ) || + ( mType == GEOM::MT_USER && mTextureId > 0 ); + // set point marker from geometry object (only once, if it is not yet set in GUI) + if ( hasMarker && !storedMap.contains( GEOM::propertyName( GEOM::PointMarker ) ) ) { + if ( mType > GEOM::MT_NONE && mType < GEOM::MT_USER ) { + // standard type + propMap.insert( GEOM::propertyName( GEOM::PointMarker ), + QString( "%1%2%3" ).arg( (int)mType ).arg( GEOM::subSectionSeparator() ).arg( (int)mSize ) ); + } + else if ( mType == GEOM::MT_USER ) { + // custom texture + propMap.insert( GEOM::propertyName( GEOM::PointMarker ), QString::number( mTextureId ) ); + } + } + } + } + } + } } - QString anIsos("%1%2%3"); - anIsos = anIsos.arg(anUIsoNumber);anIsos = anIsos.arg(DIGIT_SEPARATOR);anIsos = anIsos.arg(aVIsoNumber); - aDefaultMap.insert(ISOS_PROP , anIsos); + return propMap; +} - //3. Transparency - aDefaultMap.insert( TRANSPARENCY_PROP , 0.0 ); +PropMap GEOM_Displayer::getDefaultPropertyMap() +{ + PropMap propMap; - //4. Display Mode - aDefaultMap.insert( DISPLAY_MODE_PROP , aResMgr->integerValue("Geometry", "display_mode", 0)); + // get resource manager + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); - //5. Vector Mode - aDefaultMap.insert( VECTOR_MODE_PROP , 0); + // fill in the properties map with default values - //6. Color - QColor col = aResMgr->colorValue( "Geometry", "shading_color", QColor( 255, 0, 0 ) ); - aDefaultMap.insert( COLOR_PROP , col); + // - visibility (false by default) + propMap.insert( GEOM::propertyName( GEOM::Visibility ), false ); - //7. Deflection Coeff - double aDC; + // - nb isos (take default value from preferences) + propMap.insert( GEOM::propertyName( GEOM::NbIsos ), + QString( "%1%2%3" ). + arg( resMgr->integerValue( "Geometry", "iso_number_u", 1 ) ). + arg( GEOM::subSectionSeparator() ). + arg( resMgr->integerValue( "Geometry", "iso_number_v", 1 ) ) ); - if(viewer_type == SOCC_Viewer::Type()) { - aDC = aResMgr->doubleValue("Geometry", "deflection_coeff", 0.001); - } else if( viewer_type==SVTK_Viewer::Type()) { - aDC = 0.001; - } + // - transparency (opacity = 1-transparency) + propMap.insert( GEOM::propertyName( GEOM::Transparency ), 0.0 ); - aDefaultMap.insert( DEFLECTION_COEFF_PROP , aDC); + // - display mode (take default value from preferences) + propMap.insert( GEOM::propertyName( GEOM::DisplayMode ), + resMgr->integerValue( "Geometry", "display_mode", 0 ) ); - //8. Material - Material_Model material; - QString mname = aResMgr->stringValue( "Geometry", "material", "Plastic" ); - material.fromResources( mname ); - aDefaultMap.insert( MATERIAL_PROP, material.toProperties() ); + // - show edges direction flag (false by default) + propMap.insert( GEOM::propertyName( GEOM::EdgesDirection ), false ); - //9. Width of the edges - aDefaultMap.insert( EDGE_WIDTH_PROP , aResMgr->integerValue("Geometry", "edge_width", 1)); + // - shading color (take default value from preferences) + propMap.insert( GEOM::propertyName( GEOM::ShadingColor ), + colorFromResources( "shading_color", QColor( 255, 255, 0 ) ) ); + // - wireframe color (take default value from preferences) + propMap.insert( GEOM::propertyName( GEOM::WireframeColor ), + colorFromResources( "wireframe_color", QColor( 255, 255, 0 ) ) ); - //10. Width of iso-lines - aDefaultMap.insert( ISOS_WIDTH_PROP , aResMgr->integerValue("Geometry", "isolines_width", 1)); + // - standalone edges color (take default value from preferences) + propMap.insert( GEOM::propertyName( GEOM::LineColor ), + colorFromResources( "line_color", QColor( 255, 0, 0 ) ) ); - if(viewer_type == SOCC_Viewer::Type()) { + // - free boundaries color (take default value from preferences) + propMap.insert( GEOM::propertyName( GEOM::FreeBndColor ), + colorFromResources( "free_bound_color", QColor( 0, 255, 0 ) ) ); - aDefaultMap.insert(TOP_LEVEL_PROP, Standard_False); - } + // - points color (take default value from preferences) + propMap.insert( GEOM::propertyName( GEOM::PointColor ), + colorFromResources( "point_color", QColor( 255, 255, 0 ) ) ); - return aDefaultMap; -} + // - isos color (take default value from preferences) + propMap.insert( GEOM::propertyName( GEOM::IsosColor ), + colorFromResources( "isos_color", QColor( 200, 200, 200 ) ) ); -bool GEOM_Displayer::MergePropertyMaps(PropMap& theOrigin, PropMap& theDefault) { - int nbInserted = 0; - if(!theOrigin.contains(VISIBILITY_PROP)) { - theOrigin.insert(VISIBILITY_PROP, 0); - nbInserted++; - } - if(!theOrigin.contains(TRANSPARENCY_PROP)) { - theOrigin.insert(TRANSPARENCY_PROP, theDefault.value(TRANSPARENCY_PROP)); - nbInserted++; - } - if(!theOrigin.contains(DISPLAY_MODE_PROP)) { - theOrigin.insert(DISPLAY_MODE_PROP, theDefault.value(DISPLAY_MODE_PROP)); - nbInserted++; - } - if(!theOrigin.contains(ISOS_PROP)) { - theOrigin.insert(ISOS_PROP, theDefault.value(ISOS_PROP)); - nbInserted++; - } - if(!theOrigin.contains(VECTOR_MODE_PROP)) { - theOrigin.insert(VECTOR_MODE_PROP, theDefault.value(VECTOR_MODE_PROP)); - nbInserted++; - } - if(!theOrigin.contains(DEFLECTION_COEFF_PROP)) { - theOrigin.insert(DEFLECTION_COEFF_PROP, theDefault.value(DEFLECTION_COEFF_PROP)); - nbInserted++; - } - if(!theOrigin.contains(MATERIAL_PROP)) { - theOrigin.insert(MATERIAL_PROP, theDefault.value(MATERIAL_PROP)); - nbInserted++; - } + // - outlines color (take default value from preferences) + propMap.insert( GEOM::propertyName( GEOM::OutlineColor ), + colorFromResources( "edges_in_shading_color", QColor( 180, 180, 180 ) ) ); - if(!theOrigin.contains(EDGE_WIDTH_PROP)) { - theOrigin.insert(EDGE_WIDTH_PROP, theDefault.value(EDGE_WIDTH_PROP)); - nbInserted++; - } + // - deflection coefficient (take default value from preferences) + propMap.insert( GEOM::propertyName( GEOM::Deflection ), + resMgr->doubleValue( "Geometry", "deflection_coeff", 0.001 ) ); - if(!theOrigin.contains(ISOS_WIDTH_PROP)) { - theOrigin.insert(ISOS_WIDTH_PROP, theDefault.value(ISOS_WIDTH_PROP)); - nbInserted++; - } + // - material (take default value from preferences) + Material_Model material; + material.fromResources( resMgr->stringValue( "Geometry", "material", "Plastic" ) ); + propMap.insert( GEOM::propertyName( GEOM::Material ), material.toProperties() ); - if(!theOrigin.contains(COLOR_PROP)) { - theOrigin.insert(COLOR_PROP, theDefault.value(COLOR_PROP)); - nbInserted++; - } + // - edge width (take default value from preferences) + propMap.insert( GEOM::propertyName( GEOM::LineWidth ), + resMgr->integerValue( "Geometry", "edge_width", 1 ) ); - return (nbInserted > 0); -} + // - isos width (take default value from preferences) + propMap.insert( GEOM::propertyName( GEOM::IsosWidth ), + resMgr->integerValue( "Geometry", "isolines_width", 1 ) ); + // - point marker (take default value from preferences) + propMap.insert( GEOM::propertyName( GEOM::PointMarker ), + QString( "%1%2%3" ). + arg( resMgr->integerValue( "Geometry", "type_of_marker", 1 ) + 1 ). + arg( GEOM::subSectionSeparator() ). + arg( resMgr->integerValue( "Geometry", "marker_scale", 1 ) ) ); + + // - top-level flag (false by default) + propMap.insert( GEOM::propertyName( GEOM::TopLevel ), false ); + + return propMap; +} SALOMEDS::Color GEOM_Displayer::getColor(GEOM::GEOM_Object_var theGeomObject, bool& hasColor) { SALOMEDS::Color aSColor; @@ -2073,7 +2027,7 @@ SALOMEDS::Color GEOM_Displayer::getColor(GEOM::GEOM_Object_var theGeomObject, bo GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(aChildSObject)); if ( CORBA::is_nil( aChildObject ) ) continue; - + SALOMEDS::Color aReservedColor = aChildObject->GetColor(); if ( aReservedColor.R >= 0 && aReservedColor.G >= 0 && aReservedColor.B >= 0 ) aReservedColors.append( aReservedColor ); diff --git a/src/GEOMGUI/GEOM_Displayer.h b/src/GEOMGUI/GEOM_Displayer.h index 656612776..8cd96e5d1 100644 --- a/src/GEOMGUI/GEOM_Displayer.h +++ b/src/GEOMGUI/GEOM_Displayer.h @@ -31,6 +31,7 @@ #include +class GEOM_Actor; class SALOME_ListIO; class SALOME_View; class SALOME_Prs; @@ -63,6 +64,7 @@ class LightApp_SelectionMgr; class SalomeApp_Study; class SalomeApp_Application; class SUIT_SelectionFilter; +class Handle_GEOM_AISShape; //class SALOME_Selection; class GEOMGUI_EXPORT GEOM_Displayer : public LightApp_Displayer @@ -144,7 +146,7 @@ public: int SetDisplayMode( const int ); int GetDisplayMode() const; int UnsetDisplayMode(); - + bool HasDisplayMode() const; /* Sets name - for temporary objects only */ void SetName( const char* theName ); @@ -171,10 +173,6 @@ public: static SALOMEDS::Color getUniqueColor( const QList& ); static SALOMEDS::Color getPredefinedUniqueColor(); - static PropMap getDefaultPropertyMap(const QString& viewer_type); - - static bool MergePropertyMaps(PropMap& theOrigin, PropMap& theDefault); - /*Get color of the geom object*/ static SALOMEDS::Color getColor(GEOM::GEOM_Object_var aGeomObject, bool& hasColor); @@ -209,6 +207,14 @@ protected: SUIT_SelectionFilter* getFilter( const int theMode ); SUIT_SelectionFilter* getComplexFilter( const QList* ); + Quantity_Color qColorFromResources( const QString&, const QColor& ); + QColor colorFromResources( const QString&, const QColor& ); + void updateShapeProperties( const Handle(GEOM_AISShape)&, bool ); + void updateActorProperties( GEOM_Actor*, bool ); + + PropMap getObjectProperties( SalomeApp_Study*, const QString&, SALOME_View* = 0 ); + PropMap getDefaultPropertyMap(); + protected: Handle(SALOME_InteractiveObject) myIO; TopoDS_Shape myShape; @@ -224,11 +230,13 @@ protected: int myIsosWidth; bool myToActivate; int myDisplayMode; + bool myHasDisplayMode; Aspect_TypeOfMarker myTypeOfMarker; double myScaleOfMarker; private: SalomeApp_Application* myApp; + friend class GEOM_Swig; }; #endif // GEOM_DISPLAYER_H diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index 9cd7e615e..e375fc5d5 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -259,6 +259,10 @@ ICON_DLG_FREE_FACES free_faces.png + + ICON_DLG_FREE_BOUNDS + free_bound.png + ICON_DLG_FUSE fuse.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index ed57921e0..dfe43b573 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -125,6 +125,10 @@ Please, select face, shell or solid and try again GEOM_ANGLE_1 Angle + + GEOM_ANGLE_STEP + Angular step : + GEOM_ARC_ELLIPSE Arc of ellipse @@ -1070,6 +1074,14 @@ Please, select face, shell or solid and try again GEOM_MIN Min : + + GEOM_MINDIST_NAME + MinDist + + + GEOM_MINDIST_NO_SOL + No solution found + GEOM_MINDIST_OBJ Objects And Results @@ -1198,6 +1210,14 @@ Please, select face, shell or solid and try again GEOM_SOURCE_OBJECT Source vertex, edge or wire + + GEOM_SOLUTION + Solution : + + + GEOM_SOLUTION_I + Solution %1 + GEOM_TARGET_OBJECT Target face @@ -1950,6 +1970,10 @@ Please, select face, shell or solid and try again GEOM_STEP Step : + + GEOM_STEP_R + Radial step : + GEOM_STEP_TITLE Step value for GUI constructions @@ -2966,6 +2990,10 @@ Please, select face, shell or solid and try again MEN_TOOLS Tools + + MEN_MATERIALS_LIBRARY + Materials library + MEN_TORUS Torus @@ -3026,6 +3054,10 @@ Please, select face, shell or solid and try again MEN_POP_MATERIAL_PROPERTIES Material Properties + + MEN_POP_PREDEF_MATER_CUSTOM + Custom... + NAME_LBL Name: @@ -3170,6 +3202,14 @@ Please, select face, shell or solid and try again PREF_MATERIAL Default material + + PREF_PREDEF_MATERIALS + Show predefined materials in popup menu + + + PREF_EDITGROUP_COLOR + Subshapes color for editing a group + PREF_EDGE_WIDTH Edges width @@ -3186,10 +3226,26 @@ Please, select face, shell or solid and try again PREF_MEASURES_LINE_WIDTH Measures lines width + + PREF_ISOS + Number of isolines + + + PREF_ISOS_U + Along U + + + PREF_ISOS_V + Along V + PROCESS_SHAPE_NEW_OBJ_NAME ProcessShape + + MATERIAL_LIBRARY_TLT + Materials Library + REMOVE_HOLES_NEW_OBJ_NAME SupressHoles @@ -3602,6 +3658,14 @@ Please, select face, shell or solid and try again STB_POP_WIREFRAME Wireframe + + STB_MATERIALS_LIBRARY + Displays content of Materials library + + + STB_POP_PREDEF_MATER_CUSTOM + Custom... + STB_PROPAGATE Propagate @@ -4871,6 +4935,22 @@ be specified in meters). GEOM_IS_REORDER Reorder vertices taking into account distances + + GEOM_INTERPOL_TANGENTS + Tangents + + + GEOM_INTERPOL_FIRST_VEC + First tangent vector + + + GEOM_INTERPOL_LAST_VEC + Last tangent vector + + + GEOM_BOTH_TANGENTS_REQUIRED + Both tangent vectors must be defined + GEOM_CURVE_CRMODE Creation Mode @@ -5386,6 +5466,14 @@ Number of sketch points too small NUMBER_OPEN Number of open free boundaries: + + NAME_CLOSED + Closed_Free_Boundary_%1 + + + NAME_OPEN + Open_Free_Boundary_%1 + RepairGUI_GlueDlg @@ -5530,6 +5618,14 @@ Would you like to continue? MATERIAL_PROPERTIES_TLT Color and Material Properties + + FRONT_FACE + Front face + + + BACK_FACE + Back face + REFLECTION_0 Ambient @@ -5546,10 +5642,6 @@ Would you like to continue? REFLECTION_3 Emissive - - ENABLED - Enabled - SHININESS Shininess: diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 81d5072c6..81418e0c8 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -2966,6 +2966,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau MEN_TOOLS Outils + + MEN_MATERIALS_LIBRARY + Materials library + MEN_TORUS Tore @@ -3026,6 +3030,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau MEN_POP_MATERIAL_PROPERTIES Propriétés des matériaux + + MEN_POP_PREDEF_MATER_CUSTOM + Custom... + NAME_LBL Nom : @@ -3170,6 +3178,14 @@ Choisissez une face, une coque ou un solide et essayez de nouveau PREF_MATERIAL Matériau + + PREF_PREDEF_MATERIALS + Show predefined materials in popup menu + + + PREF_EDITGROUP_COLOR + Subshapes color for editing a group + PREF_EDGE_WIDTH Epaisseur des arêtes @@ -3186,10 +3202,26 @@ Choisissez une face, une coque ou un solide et essayez de nouveau PREF_MEASURES_LINE_WIDTH Epaisseur des traits de mesure + + PREF_ISOS + Nombre d'isolignes + + + PREF_ISOS_U + Selon U + + + PREF_ISOS_V + Selon V + PROCESS_SHAPE_NEW_OBJ_NAME FormeRetraitee + + MATERIAL_LIBRARY_TLT + Materials Library + REMOVE_HOLES_NEW_OBJ_NAME SupprimerTrous @@ -3602,6 +3634,14 @@ Choisissez une face, une coque ou un solide et essayez de nouveau STB_POP_WIREFRAME Contours + + STB_MATERIALS_LIBRARY + Displays content of Materials library + + + STB_POP_PREDEF_MATER_CUSTOM + Custom... + STB_PROPAGATE Propager @@ -4870,6 +4910,22 @@ le paramètre '%1' aux préférences du module Géométrie.GEOM_IS_REORDER Réarranger les points en prenant en compte les distances + + GEOM_INTERPOL_TANGENTS + Tangents + + + GEOM_INTERPOL_FIRST_VEC + First tangent vector + + + GEOM_INTERPOL_LAST_VEC + Last tangent vector + + + GEOM_BOTH_TANGENTS_REQUIRED + Both tangent vectors must be defined + GEOM_CURVE_CRMODE Mode de création @@ -5385,6 +5441,14 @@ Le nombre de points n'est pas suffisant NUMBER_OPEN Nombre de contours libres ouverts + + NAME_CLOSED + Closed_Free_Boundary_%1 + + + NAME_OPEN + Open_Free_Boundary_%1 + RepairGUI_GlueDlg @@ -5529,6 +5593,14 @@ Voulez-vous continuer? MATERIAL_PROPERTIES_TLT Couleur et propriétés des matériaux + + FRONT_FACE + Front face + + + BACK_FACE + Back face + REFLECTION_0 Ambiante @@ -5545,10 +5617,6 @@ Voulez-vous continuer? REFLECTION_3 Emissive - - ENABLED - Activée - SHININESS Brillance: diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index d13a0fd99..10c4d4ec6 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -38,6 +38,7 @@ #include "GEOM_Actor.h" #include +#include #include #include @@ -84,6 +85,7 @@ #include #include #include +#include #include #include @@ -188,8 +190,7 @@ void GeometryGUI::Modified (bool theIsUpdateActions) // purpose : Constructor //======================================================================= GeometryGUI::GeometryGUI() : - SalomeApp_Module( "GEOM" ), - LightApp_Module( "GEOM" ) + SalomeApp_Module( "GEOM" ) { if ( CORBA::is_nil( myComponentGeom ) ) { @@ -206,6 +207,8 @@ GeometryGUI::GeometryGUI() : myDisplayer = 0; myLocalSelectionMode = GEOM_ALLOBJECTS; + + connect( Material_ResourceMgr::resourceMgr(), SIGNAL( changed() ), this, SLOT( updateMaterials() ) ); } //======================================================================= @@ -359,7 +362,7 @@ void GeometryGUI::OnGUIEvent() // function : GeometryGUI::OnGUIEvent() // purpose : manage all events on GUI [static] //======================================================================= -void GeometryGUI::OnGUIEvent( int id ) +void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam ) { SUIT_Application* anApp = application(); if (!anApp) return; @@ -408,6 +411,7 @@ void GeometryGUI::OnGUIEvent( int id ) case GEOMOp::OpSelectAll: // POPUP MENU - SELECT ONLY - SELECT ALL case GEOMOp::OpDelete: // MENU EDIT - DELETE case GEOMOp::OpCheckGeom: // MENU TOOLS - CHECK GEOMETRY + case GEOMOp::OpMaterialsLibrary: // MENU TOOLS - MATERIALS LIBRARY case GEOMOp::OpDeflection: // POPUP MENU - DEFLECTION COEFFICIENT case GEOMOp::OpColor: // POPUP MENU - COLOR case GEOMOp::OpSetTexture: // POPUP MENU - SETTEXTURE @@ -425,6 +429,8 @@ void GeometryGUI::OnGUIEvent( int id ) case GEOMOp::OpPublishObject: // ROOT GEOM OBJECT - POPUP MENU - PUBLISH case GEOMOp::OpPointMarker: // POPUP MENU - POINT MARKER case GEOMOp::OpMaterialProperties: // POPUP MENU - MATERIAL PROPERTIES + case GEOMOp::OpPredefMaterial: // POPUP MENU - + case GEOMOp::OpPredefMaterCustom: // POPUP MENU - MATERIAL PROPERTIES - CUSTOM... case GEOMOp::OpEdgeWidth: // POPUP MENU - LINE WIDTH - EDGE WIDTH case GEOMOp::OpIsosWidth: // POPUP MENU - LINE WIDTH - ISOS WIDTH case GEOMOp::OpBringToFront: // POPUP MENU - BRING TO FRONT @@ -595,18 +601,10 @@ void GeometryGUI::OnGUIEvent( int id ) // call method of corresponding GUI library if ( library ) { - library->OnGUIEvent( id, desk ); - - // Update a list of materials for "Preferences" dialog - if ( id == GEOMOp::OpMaterialProperties ) { - LightApp_Preferences* pref = preferences(); - if ( pref ) { - Material_ResourceMgr aMatResMgr; - setPreferenceProperty( pref->rootItem()->findItem( tr( "PREF_MATERIAL" ), true )->id(), - "strings", - aMatResMgr.materials() ); - } - } + if( !theParam.isValid() ) + library->OnGUIEvent( id, desk ); + else + library->OnGUIEvent( id, desk, theParam); } else SUIT_MessageBox::critical( desk, tr( "GEOM_ERROR" ), tr( "GEOM_ERR_LIB_NOT_FOUND" ), tr( "GEOM_BUT_OK" ) ); @@ -846,6 +844,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( GEOMOp::OpCheckGeom, "CHECK_GEOMETRY" ); #endif + createGeomAction( GEOMOp::OpMaterialsLibrary, "MATERIALS_LIBRARY" ); createGeomAction( GEOMOp::OpDMWireframe, "WIREFRAME" ); createGeomAction( GEOMOp::OpDMShading, "SHADING" ); createGeomAction( GEOMOp::OpDMShadingWithEdges, "SHADING_WITH_EDGES" ); @@ -887,7 +886,8 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( GEOMOp::OpUnpublishObject, "POP_UNPUBLISH_OBJ" ); createGeomAction( GEOMOp::OpPublishObject, "POP_PUBLISH_OBJ" ); createGeomAction( GEOMOp::OpPointMarker, "POP_POINT_MARKER" ); - createGeomAction( GEOMOp::OpMaterialProperties, "POP_MATERIAL_PROPERTIES" ); + createGeomAction( GEOMOp::OpMaterialProperties, "POP_MATERIAL_PROPERTIES" ); + createGeomAction( GEOMOp::OpPredefMaterCustom, "POP_PREDEF_MATER_CUSTOM" ); createGeomAction( GEOMOp::OpPipeTShape, "PIPETSHAPE" ); @@ -1080,11 +1080,15 @@ void GeometryGUI::initialize( CAM_Application* app ) createMenu( GEOMOp::OpGetNonBlocks, measurId, -1 ); createMenu( GEOMOp::OpCheckSelfInters, measurId, -1 ); -#ifdef _DEBUG_ // PAL16821 int toolsId = createMenu( tr( "MEN_TOOLS" ), -1, -1, 50 ); +#if defined(_DEBUG_) || defined(_DEBUG) // PAL16821 createMenu( separator(), toolsId, -1 ); createMenu( GEOMOp::OpCheckGeom, toolsId, -1 ); #endif + + createMenu( separator(), toolsId, -1 ); + createMenu( GEOMOp::OpMaterialsLibrary, toolsId, -1 ); + createMenu( separator(), toolsId, -1 ); int viewId = createMenu( tr( "MEN_VIEW" ), -1, -1 ); createMenu( separator(), viewId, -1 ); @@ -1273,44 +1277,49 @@ void GeometryGUI::initialize( CAM_Application* app ) mgr->insert( separator(), -1, -1 ); // ----------- dispmodeId = mgr->insert( tr( "MEN_DISPLAY_MODE" ), -1, -1 ); // display mode menu mgr->insert( action( GEOMOp::OpWireframe ), dispmodeId, -1 ); // wireframe - mgr->setRule( action( GEOMOp::OpWireframe ), clientOCCorVTK_AndSomeVisible, QtxPopupMgr::VisibleRule ); + mgr->setRule( action( GEOMOp::OpWireframe ), clientOCCorVTK_AndSomeVisible + " and ($component={'GEOM'})", QtxPopupMgr::VisibleRule ); mgr->setRule( action( GEOMOp::OpWireframe ), clientOCCorVTK + " and displaymode='Wireframe'", QtxPopupMgr::ToggleRule ); mgr->insert( action( GEOMOp::OpShading ), dispmodeId, -1 ); // shading - mgr->setRule( action( GEOMOp::OpShading ), clientOCCorVTK_AndSomeVisible, QtxPopupMgr::VisibleRule ); + mgr->setRule( action( GEOMOp::OpShading ), clientOCCorVTK_AndSomeVisible + " and ($component={'GEOM'})", QtxPopupMgr::VisibleRule ); mgr->setRule( action( GEOMOp::OpShading ), clientOCCorVTK + " and displaymode='Shading'", QtxPopupMgr::ToggleRule ); mgr->insert( action( GEOMOp::OpShadingWithEdges ), dispmodeId, -1 ); // shading with edges - mgr->setRule( action( GEOMOp::OpShadingWithEdges ), clientOCCorVTK_AndSomeVisible, QtxPopupMgr::VisibleRule ); + mgr->setRule( action( GEOMOp::OpShadingWithEdges ), clientOCCorVTK_AndSomeVisible + " and ($component={'GEOM'})", QtxPopupMgr::VisibleRule ); mgr->setRule( action( GEOMOp::OpShadingWithEdges ), clientOCCorVTK + " and displaymode='ShadingWithEdges'", QtxPopupMgr::ToggleRule ); mgr->insert( action( GEOMOp::OpTexture ), dispmodeId, -1 ); // wireframe mgr->setRule( action( GEOMOp::OpTexture ), clientOCC_AndSomeVisible, QtxPopupMgr::VisibleRule ); mgr->setRule( action( GEOMOp::OpTexture), clientOCC + " and displaymode='Texture'", QtxPopupMgr::ToggleRule ); mgr->insert( separator(), dispmodeId, -1 ); mgr->insert( action( GEOMOp::OpVectors ), dispmodeId, -1 ); // vectors - mgr->setRule( action( GEOMOp::OpVectors ), clientOCCorVTK_AndSomeVisible, QtxPopupMgr::VisibleRule ); + mgr->setRule( action( GEOMOp::OpVectors ), clientOCCorVTK_AndSomeVisible + " and ($component={'GEOM'})", QtxPopupMgr::VisibleRule ); mgr->setRule( action( GEOMOp::OpVectors ), clientOCCorVTK + " and isVectorsMode", QtxPopupMgr::ToggleRule ); mgr->insert( separator(), -1, -1 ); // ----------- + mgr->insert( action( GEOMOp::OpColor ), -1, -1 ); // color mgr->setRule( action( GEOMOp::OpColor ), clientOCCorVTKorOB_AndSomeVisible + " and ($component={'GEOM'})" + "and isPhysicalMaterial=false", QtxPopupMgr::VisibleRule ); mgr->insert( action( GEOMOp::OpTransparency ), -1, -1 ); // transparency - mgr->setRule( action( GEOMOp::OpTransparency ), clientOCCorVTK_AndSomeVisible, QtxPopupMgr::VisibleRule ); + mgr->setRule( action( GEOMOp::OpTransparency ), clientOCCorVTK_AndSomeVisible + " and ($component={'GEOM'})", QtxPopupMgr::VisibleRule ); mgr->insert( action( GEOMOp::OpIsos ), -1, -1 ); // isos - mgr->setRule( action( GEOMOp::OpIsos ), clientOCCorVTK_AndSomeVisible + " and selcount>0 and isVisible", QtxPopupMgr::VisibleRule ); + mgr->setRule( action( GEOMOp::OpIsos ), clientOCCorVTK_AndSomeVisible + " and selcount>0 and isVisible" + " and ($component={'GEOM'})", QtxPopupMgr::VisibleRule ); mgr->insert( action( GEOMOp::OpDeflection ), -1, -1 ); // deflection - mgr->setRule( action( GEOMOp::OpDeflection ), clientOCCorVTK_AndSomeVisible + " and selcount>0 and isVisible", QtxPopupMgr::VisibleRule ); + mgr->setRule( action( GEOMOp::OpDeflection ), clientOCCorVTK_AndSomeVisible + " and selcount>0 and isVisible" + " and ($component={'GEOM'})", QtxPopupMgr::VisibleRule ); mgr->insert( action( GEOMOp::OpPointMarker ), -1, -1 ); // point marker //mgr->setRule( action( GEOMOp::OpPointMarker ), QString( "selcount>0 and $typeid in {%1}" ).arg(GEOM_POINT ), QtxPopupMgr::VisibleRule ); mgr->setRule( action( GEOMOp::OpPointMarker ), QString( "selcount>0 and ( $typeid in {%1} or compoundOfVertices=true ) " ).arg(GEOM::VERTEX).arg(GEOM::COMPOUND), QtxPopupMgr::VisibleRule ); - mgr->insert( action( GEOMOp::OpMaterialProperties ), -1, -1 ); // material properties - mgr->setRule( action( GEOMOp::OpMaterialProperties ), clientOCCorVTK_AndSomeVisible + " and ($component={'GEOM'}) and selcount>0 and isVisible", QtxPopupMgr::VisibleRule ); - mgr->insert( action( GEOMOp::OpSetTexture ), -1, -1 ); // texture + + // material properties + mgr->insert( action( GEOMOp::OpMaterialProperties ), -1, -1 ); + mgr->setRule( action( GEOMOp::OpMaterialProperties ), clientOCCorVTK_AndSomeVisible + " and ($component={'GEOM'})", QtxPopupMgr::VisibleRule ); + + // texture + mgr->insert( action( GEOMOp::OpSetTexture ), -1, -1 ); mgr->setRule( action( GEOMOp::OpSetTexture ), clientOCCorOB_AndSomeVisible + " and ($component={'GEOM'})", QtxPopupMgr::VisibleRule ); int lineW = mgr->insert( tr( "MEN_LINE_WIDTH" ), -1, -1 ); // line width menu mgr->insert( action( GEOMOp::OpEdgeWidth ), lineW, -1 ); // edge width - mgr->setRule( action( GEOMOp::OpEdgeWidth ), clientOCCorVTK_AndSomeVisible, QtxPopupMgr::VisibleRule ); + mgr->setRule( action( GEOMOp::OpEdgeWidth ), clientOCCorVTK_AndSomeVisible + " and ($component={'GEOM'})", QtxPopupMgr::VisibleRule ); mgr->insert( action( GEOMOp::OpIsosWidth ), lineW, -1 ); // isos width - mgr->setRule( action( GEOMOp::OpIsosWidth ), clientOCCorVTK_AndSomeVisible, QtxPopupMgr::VisibleRule ); + mgr->setRule( action( GEOMOp::OpIsosWidth ), clientOCCorVTK_AndSomeVisible + " and ($component={'GEOM'})", QtxPopupMgr::VisibleRule ); mgr->insert( separator(), -1, -1 ); // ----------- mgr->insert( action( GEOMOp::OpAutoColor ), -1, -1 ); // auto color @@ -1612,7 +1621,7 @@ void GeometryGUI::onViewManagerRemoved( SUIT_ViewManager* vm ) if ( GEOMGUI_OCCSelector* sr = itOCCSel.next() ) if ( sr->viewer() == viewer ) { - delete myOCCSelectors.takeAt( myOCCSelectors.indexOf( sr ) ); + /*delete*/ myOCCSelectors.takeAt( myOCCSelectors.indexOf( sr ) ); break; } } @@ -1623,7 +1632,7 @@ void GeometryGUI::onViewManagerRemoved( SUIT_ViewManager* vm ) if ( LightApp_VTKSelector* sr = itVTKSel.next() ) if ( sr->viewer() == viewer ) { - delete myVTKSelectors.takeAt( myVTKSelectors.indexOf( sr ) ); + /*delete*/ myVTKSelectors.takeAt( myVTKSelectors.indexOf( sr ) ); break; } } @@ -1689,6 +1698,58 @@ void GeometryGUI::contextMenuPopup( const QString& client, QMenu* menu, QString& SalomeApp_Module::contextMenuPopup( client, menu, title ); SALOME_ListIO lst; getApp()->selectionMgr()->selectedObjects( lst ); + + //Add submenu for predefined materials + bool isPredefMat = SUIT_Session::session()->resourceMgr()->booleanValue( "Geometry", "predef_materials" ); + if ( ( client == "OCCViewer" || client == "VTKViewer" ) && lst.Extent() > 0 ) { + QtxPopupMgr* mgr = popupMgr(); + //get parrent for submenu + QAction* act = mgr->action( mgr->actionId( action( GEOMOp::OpMaterialProperties ) ) ); + //Clear old menu + QMenu* oldMenu = act->menu() ; + if( oldMenu ) { + delete oldMenu; + } + if( isPredefMat ){ + QMenu* matMenu = new QMenu(); + QSignalMapper* signalMapper = new QSignalMapper( matMenu ); + + //Get current material model for the object + QVariant v; + LightApp_Application* anApp = dynamic_cast( getApp() ); + if ( anApp && anApp->activeViewManager() ) { + LightApp_Study* aStudy = dynamic_cast( anApp->activeStudy() ); + if( aStudy ) { + v = aStudy->getObjectProperty( anApp->activeViewManager()->getGlobalId(), lst.Last()->getEntry(), GEOM::propertyName( GEOM::Material ), QVariant() ); + } + } + QString curModel = ""; + if ( v.canConvert() ) curModel = v.toString(); + // get list of all predefined materials + QStringList materials = Material_ResourceMgr::resourceMgr()->materials(); + bool found = false; + foreach ( QString material, materials ) + { + QAction* menAct = matMenu->addAction( material ); + connect(menAct, SIGNAL( toggled( bool ) ), signalMapper, SLOT( map() ) ); + signalMapper->setMapping( menAct, material ); + menAct->setCheckable( true ); + // Set checked if this material is current + Material_Model aModel; + aModel.fromResources( material ); + if ( !found && aModel.toProperties() == curModel ) { + menAct->setChecked( true ); + found = true; + } + } + matMenu->insertAction( matMenu->addSeparator(), action( GEOMOp::OpPredefMaterCustom ) ); + matMenu->insertSeparator( action( GEOMOp::OpPredefMaterCustom ) ); + connect( signalMapper, SIGNAL( mapped( const QString & ) ), + this, SLOT( OnSetMaterial( const QString & ) ) ); + act->setMenu( matMenu ); + } + } + //Set name if ( ( client == "OCCViewer" || client == "VTKViewer" ) && lst.Extent() == 1 ) { Handle(SALOME_InteractiveObject) io = lst.First(); SalomeApp_Study* appStudy = dynamic_cast( application()->activeStudy() ); @@ -1702,6 +1763,12 @@ void GeometryGUI::contextMenuPopup( const QString& client, QMenu* menu, QString& } } +void GeometryGUI::OnSetMaterial(const QString& theName) +{ + OnGUIEvent( GEOMOp::OpPredefMaterial, QVariant( theName ) ); +} + + void GeometryGUI::createPreferences() { int tabId = addPreference( tr( "PREF_TAB_SETTINGS" ) ); @@ -1746,9 +1813,15 @@ void GeometryGUI::createPreferences() int defl = addPreference( tr( "PREF_DEFLECTION" ), genGroup, LightApp_Preferences::DblSpin, "Geometry", "deflection_coeff" ); + addPreference( tr( "PREF_PREDEF_MATERIALS" ), genGroup, + LightApp_Preferences::Bool, "Geometry", "predef_materials" ); + int material = addPreference( tr( "PREF_MATERIAL" ), genGroup, - LightApp_Preferences::Selector, - "Geometry", "material" ); + LightApp_Preferences::Selector, + "Geometry", "material" ); + + addPreference( tr( "PREF_EDITGROUP_COLOR" ), genGroup, + LightApp_Preferences::Color, "Geometry", "editgroup_color" ); const int nb = 4; int wd[nb]; @@ -1770,6 +1843,17 @@ void GeometryGUI::createPreferences() setPreferenceProperty( wd[i], "min", 1 ); setPreferenceProperty( wd[i], "max", 5 ); } + + int isoGroup = addPreference( tr( "PREF_ISOS" ), tabId ); + setPreferenceProperty( isoGroup, "columns", 2 ); + int isoU = addPreference( tr( "PREF_ISOS_U" ), isoGroup, + LightApp_Preferences::IntSpin, "Geometry", "iso_number_u" ); + setPreferenceProperty( isoU, "min", 0 ); + setPreferenceProperty( isoU, "max", 100000 ); + int isoV = addPreference( tr( "PREF_ISOS_V" ), isoGroup, + LightApp_Preferences::IntSpin, "Geometry", "iso_number_v" ); + setPreferenceProperty( isoV, "min", 0 ); + setPreferenceProperty( isoV, "max", 100000 ); // Quantities with individual precision settings int precGroup = addPreference( tr( "GEOM_PREF_GROUP_PRECISION" ), tabId ); @@ -1848,15 +1932,14 @@ void GeometryGUI::createPreferences() setPreferenceProperty( step, "precision", 3 ); // Set property for deflection value for spinboxes - setPreferenceProperty( defl, "min", DEFLECTION_MIN ); + setPreferenceProperty( defl, "min", GEOM::minDeflection() ); setPreferenceProperty( defl, "max", 1.0 ); setPreferenceProperty( defl, "step", 1.0e-04 ); setPreferenceProperty( defl, "precision", 6 ); // Set property for default material - Material_ResourceMgr aMatResMgr; - setPreferenceProperty( material, "strings", aMatResMgr.materials() ); - + setPreferenceProperty( material, "strings", Material_ResourceMgr::resourceMgr()->materials() ); + // Set property vertex marker type QList aMarkerTypeIndicesList; QList aMarkerTypeIconsList; @@ -1995,83 +2078,82 @@ void GeometryGUI::storeVisualParameters (int savePoint) if (!obj->FindAttribute(anAttr, "AttributeIOR")) continue; - std::string param,occParam = vType.toLatin1().data(); - occParam += NAME_SEPARATOR; - occParam += QString::number(aMgrId).toLatin1().data(); - occParam += NAME_SEPARATOR; + QString param, occParam = vType; + occParam += GEOM::sectionSeparator(); + occParam += QString::number(aMgrId); + occParam += GEOM::sectionSeparator(); - if (aProps.contains(VISIBILITY_PROP)) { - param = occParam + VISIBILITY_PROP; - ip->setParameter(entry, param, aProps.value(VISIBILITY_PROP).toInt() == 1 ? "On" : "Off"); + if (aProps.contains(GEOM::propertyName( GEOM::Visibility ))) { + param = occParam + GEOM::propertyName( GEOM::Visibility ); + ip->setParameter(entry, param.toStdString(), aProps.value(GEOM::propertyName( GEOM::Visibility )).toBool() ? "On" : "Off"); } - if (aProps.contains(DISPLAY_MODE_PROP)) { - param = occParam + DISPLAY_MODE_PROP; - ip->setParameter(entry, param, QString::number(aProps.value(DISPLAY_MODE_PROP).toInt()).toLatin1().data()); + if (aProps.contains(GEOM::propertyName( GEOM::DisplayMode ))) { + param = occParam + GEOM::propertyName( GEOM::DisplayMode ); + ip->setParameter(entry, param.toStdString(), aProps.value(GEOM::propertyName( GEOM::DisplayMode )).toString().toStdString()); } - if (aProps.contains(COLOR_PROP)) { - QColor c = aProps.value(COLOR_PROP).value(); - QString colorStr = QString::number(c.red()/255.); - colorStr += DIGIT_SEPARATOR; colorStr += QString::number(c.green()/255.); - colorStr += DIGIT_SEPARATOR; colorStr += QString::number(c.blue()/255.); - param = occParam + COLOR_PROP; - ip->setParameter(entry, param, colorStr.toLatin1().data()); + if (aProps.contains(GEOM::propertyName( GEOM::Color ))) { + QColor c = aProps.value(GEOM::propertyName( GEOM::Color )).value(); + QStringList val; + val << QString::number(c.redF()); + val << QString::number(c.greenF()); + val << QString::number(c.blueF()); + param = occParam + GEOM::propertyName( GEOM::Color ); + ip->setParameter(entry, param.toStdString(), val.join( GEOM::subSectionSeparator()).toStdString()); } if (vType == SVTK_Viewer::Type()) { - if (aProps.contains(OPACITY_PROP)) { - param = occParam + OPACITY_PROP; - ip->setParameter(entry, param, QString::number(1. - aProps.value(TRANSPARENCY_PROP).toDouble()).toLatin1().data()); + if (aProps.contains(GEOM::propertyName( GEOM::Opacity ))) { + param = occParam + GEOM::propertyName( GEOM::Opacity ); + ip->setParameter(entry, param.toStdString(), QString::number(1. - aProps.value(GEOM::propertyName( GEOM::Transparency )).toDouble()).toStdString()); } } else if (vType == SOCC_Viewer::Type()) { - if (aProps.contains(TRANSPARENCY_PROP)) { - param = occParam + TRANSPARENCY_PROP; - ip->setParameter(entry, param, QString::number(aProps.value(TRANSPARENCY_PROP).toDouble()).toLatin1().data()); + if (aProps.contains(GEOM::propertyName( GEOM::Transparency ))) { + param = occParam + GEOM::propertyName( GEOM::Transparency ); + ip->setParameter(entry, param.toStdString(), aProps.value(GEOM::propertyName( GEOM::Transparency )).toString().toStdString()); } - if (aProps.contains(TOP_LEVEL_PROP)) { - param = occParam + TOP_LEVEL_PROP; - Standard_Boolean val = aProps.value(TOP_LEVEL_PROP).value(); - if (val == Standard_True) - ip->setParameter(entry, param, "1"); + if (aProps.contains(GEOM::propertyName( GEOM::TopLevel ))) { + param = occParam + GEOM::propertyName( GEOM::TopLevel ); + ip->setParameter(entry, param.toStdString(), aProps.value(GEOM::propertyName( GEOM::TopLevel )).toString().toStdString()); } } - if (aProps.contains(ISOS_PROP)) { - param = occParam + ISOS_PROP; - ip->setParameter(entry, param, aProps.value(ISOS_PROP).toString().toLatin1().data()); + if (aProps.contains(GEOM::propertyName( GEOM::NbIsos ))) { + param = occParam + GEOM::propertyName( GEOM::NbIsos ); + ip->setParameter(entry, param.toStdString(), aProps.value(GEOM::propertyName( GEOM::NbIsos )).toString().toStdString()); } - if (aProps.contains(VECTOR_MODE_PROP)) { - param = occParam + VECTOR_MODE_PROP; - ip->setParameter(entry, param, QString::number(aProps.value(VECTOR_MODE_PROP).toInt()).toLatin1().data()); + if (aProps.contains(GEOM::propertyName( GEOM::EdgesDirection ))) { + param = occParam + GEOM::propertyName( GEOM::EdgesDirection ); + ip->setParameter(entry, param.toStdString(), aProps.value(GEOM::propertyName( GEOM::EdgesDirection )).toString().toStdString()); } - if (aProps.contains(DEFLECTION_COEFF_PROP)) { - param = occParam + DEFLECTION_COEFF_PROP; - ip->setParameter(entry, param, QString::number(aProps.value(DEFLECTION_COEFF_PROP).toDouble()).toLatin1().data()); + if (aProps.contains(GEOM::propertyName( GEOM::Deflection ))) { + param = occParam + GEOM::propertyName( GEOM::Deflection ); + ip->setParameter(entry, param.toStdString(), aProps.value(GEOM::propertyName( GEOM::Deflection )).toString().toStdString()); } //Marker type of the vertex - ONLY for the "Vertex" and "Compound of the Vertex" - if (aProps.contains(MARKER_TYPE_PROP)) { - param = occParam + MARKER_TYPE_PROP; - ip->setParameter(entry, param, aProps.value(MARKER_TYPE_PROP).toString().toLatin1().data()); + if (aProps.contains(GEOM::propertyName( GEOM::PointMarker ))) { + param = occParam + GEOM::propertyName( GEOM::PointMarker ); + ip->setParameter(entry, param.toStdString(), aProps.value(GEOM::propertyName( GEOM::PointMarker )).toString().toStdString()); } - if (aProps.contains(MATERIAL_PROP)) { - param = occParam + MATERIAL_PROP; - ip->setParameter(entry, param, aProps.value(MATERIAL_PROP).toString().toLatin1().data()); + if (aProps.contains(GEOM::propertyName( GEOM::Material ))) { + param = occParam + GEOM::propertyName( GEOM::Material ); + ip->setParameter(entry, param.toStdString(), aProps.value(GEOM::propertyName( GEOM::Material )).toString().toStdString()); } - if (aProps.contains(EDGE_WIDTH_PROP)) { - param = occParam + EDGE_WIDTH_PROP; - ip->setParameter(entry, param, aProps.value(EDGE_WIDTH_PROP).toString().toLatin1().data()); + if (aProps.contains(GEOM::propertyName( GEOM::LineWidth ))) { + param = occParam + GEOM::propertyName( GEOM::LineWidth ); + ip->setParameter(entry, param.toStdString(), aProps.value(GEOM::propertyName( GEOM::LineWidth )).toString().toStdString()); } - if (aProps.contains(ISOS_WIDTH_PROP)) { - param = occParam + ISOS_WIDTH_PROP; - ip->setParameter(entry, param, aProps.value(ISOS_WIDTH_PROP).toString().toLatin1().data()); + if (aProps.contains(GEOM::propertyName( GEOM::IsosWidth ))) { + param = occParam + GEOM::propertyName( GEOM::IsosWidth ); + ip->setParameter(entry, param.toStdString(), aProps.value(GEOM::propertyName( GEOM::IsosWidth )).toString().toStdString()); } } // object iterator } // for (views) @@ -2134,7 +2216,7 @@ void GeometryGUI::restoreVisualParameters (int savePoint) { // visual parameters are stored in strings as follows: ViewerType_ViewIndex_ParamName. // '_' is used as separator and should not be used in viewer type or parameter names. - QStringList lst = QString((*namesIt).c_str()).split(NAME_SEPARATOR, QString::SkipEmptyParts); + QStringList lst = QString((*namesIt).c_str()).split( GEOM::sectionSeparator(), QString::SkipEmptyParts); if (lst.size() != 3) continue; @@ -2152,36 +2234,36 @@ void GeometryGUI::restoreVisualParameters (int savePoint) } QString val((*valuesIt).c_str()); - if (paramNameStr == VISIBILITY_PROP) { - aListOfMap[viewIndex].insert(VISIBILITY_PROP, val == "On" ? 1 : 0); - } else if (paramNameStr == OPACITY_PROP) { - aListOfMap[viewIndex].insert(TRANSPARENCY_PROP, 1. - val.toDouble()); - } else if (paramNameStr == TRANSPARENCY_PROP) { - aListOfMap[viewIndex].insert( TRANSPARENCY_PROP, val.toDouble() ); - } else if (paramNameStr == TOP_LEVEL_PROP) { - aListOfMap[viewIndex].insert( TRANSPARENCY_PROP, val == "1" ? Standard_True : Standard_False ); - } else if (paramNameStr == DISPLAY_MODE_PROP) { - aListOfMap[viewIndex].insert( DISPLAY_MODE_PROP, val.toInt()); - } else if (paramNameStr == ISOS_PROP) { - aListOfMap[viewIndex].insert( ISOS_PROP, val); - } else if (paramNameStr == COLOR_PROP) { - QStringList rgb = val.split(DIGIT_SEPARATOR); + if (paramNameStr == GEOM::propertyName( GEOM::Visibility )) { + aListOfMap[viewIndex].insert(GEOM::propertyName( GEOM::Visibility ), val == "On"); + } else if (paramNameStr == GEOM::propertyName( GEOM::Opacity )) { + aListOfMap[viewIndex].insert(GEOM::propertyName( GEOM::Transparency ), 1. - val.toDouble()); + } else if (paramNameStr == GEOM::propertyName( GEOM::Transparency )) { + aListOfMap[viewIndex].insert( GEOM::propertyName( GEOM::Transparency ), val.toDouble() ); + } else if (paramNameStr == GEOM::propertyName( GEOM::TopLevel )) { + aListOfMap[viewIndex].insert( GEOM::propertyName( GEOM::TopLevel ), val == "true" || val == "1"); + } else if (paramNameStr == GEOM::propertyName( GEOM::DisplayMode )) { + aListOfMap[viewIndex].insert( GEOM::propertyName( GEOM::DisplayMode ), val.toInt()); + } else if (paramNameStr == GEOM::propertyName( GEOM::NbIsos )) { + aListOfMap[viewIndex].insert( GEOM::propertyName( GEOM::NbIsos ), val); + } else if (paramNameStr == GEOM::propertyName( GEOM::Color )) { + QStringList rgb = val.split(GEOM::subSectionSeparator()); if (rgb.count() == 3) { - QColor c(int(rgb[0].toDouble()*255), int(rgb[1].toDouble()*255), int(rgb[2].toDouble()*255)); - aListOfMap[viewIndex].insert( COLOR_PROP, c); + QColor c = QColor::fromRgbF(rgb[0].toDouble(), rgb[1].toDouble(), rgb[2].toDouble()); + aListOfMap[viewIndex].insert( GEOM::propertyName( GEOM::Color ), c); } - } else if (paramNameStr == VECTOR_MODE_PROP) { - aListOfMap[viewIndex].insert( VECTOR_MODE_PROP, val.toInt()); - } else if (paramNameStr == DEFLECTION_COEFF_PROP) { - aListOfMap[viewIndex].insert( DEFLECTION_COEFF_PROP, val.toDouble()); - } else if (paramNameStr == MARKER_TYPE_PROP) { - aListOfMap[viewIndex].insert( MARKER_TYPE_PROP, val); - } else if (paramNameStr == MATERIAL_PROP) { - aListOfMap[viewIndex].insert( MATERIAL_PROP, val); - } else if (paramNameStr == EDGE_WIDTH_PROP) { - aListOfMap[viewIndex].insert( EDGE_WIDTH_PROP, val); - } else if (paramNameStr == ISOS_WIDTH_PROP) { - aListOfMap[viewIndex].insert( ISOS_WIDTH_PROP, val); + } else if (paramNameStr == GEOM::propertyName( GEOM::EdgesDirection )) { + aListOfMap[viewIndex].insert( GEOM::propertyName( GEOM::EdgesDirection ), val == "true" || val == "1"); + } else if (paramNameStr == GEOM::propertyName( GEOM::Deflection )) { + aListOfMap[viewIndex].insert( GEOM::propertyName( GEOM::Deflection ), val.toDouble()); + } else if (paramNameStr == GEOM::propertyName( GEOM::PointMarker )) { + aListOfMap[viewIndex].insert( GEOM::propertyName( GEOM::PointMarker ), val); + } else if (paramNameStr == GEOM::propertyName( GEOM::Material )) { + aListOfMap[viewIndex].insert( GEOM::propertyName( GEOM::Material ), val); + } else if (paramNameStr == GEOM::propertyName( GEOM::LineWidth )) { + aListOfMap[viewIndex].insert( GEOM::propertyName( GEOM::LineWidth ), val.toInt()); + } else if (paramNameStr == GEOM::propertyName( GEOM::IsosWidth )) { + aListOfMap[viewIndex].insert( GEOM::propertyName( GEOM::IsosWidth ), val.toInt()); } } // for names/parameters iterator @@ -2192,7 +2274,7 @@ void GeometryGUI::restoreVisualParameters (int savePoint) appStudy->setObjectPropMap(index, entry, aListOfMap[index]); //Get Visibility property of the current PropMap - if (aListOfMap[index].value(VISIBILITY_PROP) == 1) { + if (aListOfMap[index].value(GEOM::propertyName( GEOM::Visibility )) == 1) { SUIT_ViewManager* vman = lst.at(index); SUIT_ViewModel* vmodel = vman->getViewModel(); displayer()->Display(entry, true, dynamic_cast(vmodel)); @@ -2306,3 +2388,22 @@ bool GeometryGUI::renameObject( const QString& entry, const QString& name) } return result; } + +void GeometryGUI::updateMaterials() +{ + LightApp_Preferences* pref = preferences(); + if ( pref ) { + QStringList materials = Material_ResourceMgr::resourceMgr()->materials(); + QString currentMaterial = SUIT_Session::session()->resourceMgr()->stringValue( "Geometry", "material" ); + if ( !materials.contains( currentMaterial ) ) + // user material set as default in the preferences, might be removed + SUIT_Session::session()->resourceMgr()->setValue( "Geometry", "material", QString( "Plastic" ) ); + + QtxPreferenceItem* prefItem = pref->rootItem()->findItem( tr( "PREF_MATERIAL" ), true ); + if ( prefItem ) { + setPreferenceProperty( prefItem->id(), + "strings", materials ); + prefItem->retrieve(); + } + } +} diff --git a/src/GEOMGUI/GeometryGUI.h b/src/GEOMGUI/GeometryGUI.h index bde9446a7..9bf6e6326 100644 --- a/src/GEOMGUI/GeometryGUI.h +++ b/src/GEOMGUI/GeometryGUI.h @@ -111,7 +111,7 @@ public: void EmitSignalDefaultStepValueChanged( double newVal ); // Process action - void OnGUIEvent( int id ); + void OnGUIEvent( int id, const QVariant& theParam = QVariant( QVariant::Invalid ) ); // The Working Plane management void SetWorkingPlane( gp_Ax3 wp ) { myWorkingPlane = wp; } @@ -151,6 +151,8 @@ private slots: void OnGUIEvent(); void onWindowActivated( SUIT_ViewWindow* ); void onViewAboutToShow(); + void OnSetMaterial( const QString& ); + void updateMaterials(); signals : void SignalDeactivateActiveDialog(); diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h index e17172e49..cea4c9048 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -29,6 +29,7 @@ namespace GEOMOp { OpExport = 1001, // MENU FILE - EXPORT OpDelete = 1020, // MENU EDIT - DELETE OpCheckGeom = 1030, // MENU TOOLS - CHECK GEOMETRY + OpMaterialsLibrary = 1040, // MENU TOOLS - MATERIALS LIBRARY OpSelectVertex = 1100, // POPUP MENU - SELECT ONLY - VERTEX OpSelectEdge = 1101, // POPUP MENU - SELECT ONLY - EDGE OpSelectWire = 1102, // POPUP MENU - SELECT ONLY - WIRE @@ -50,6 +51,8 @@ namespace GEOMOp { OpPointMarker = 1210, // POPUP MENU - POINT MARKER OpSetTexture = 1211, // POPUP MENU - SETTEXTURE OpMaterialProperties = 1212, // POPUP MENU - MATERIAL PROPERTIES + OpPredefMaterial = 1213, // POPUP MENU - MATERIAL PROPERTIES - + OpPredefMaterCustom = 1214, // POPUP MENU - MATERIAL PROPERTIES - CUSTOM... OpDiscloseChildren = 1250, // POPUP MENU - DISCLOSE CHILD ITEMS OpConcealChildren = 1251, // POPUP MENU - CONCEAL CHILD ITEMS OpUnpublishObject = 1253, // POPUP MENU - UNPUBLISH diff --git a/src/GEOMImpl/GEOMImpl_CircleDriver.cxx b/src/GEOMImpl/GEOMImpl_CircleDriver.cxx index b26507e88..e0c33a478 100644 --- a/src/GEOMImpl/GEOMImpl_CircleDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_CircleDriver.cxx @@ -18,17 +18,19 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include #include + #include #include + #include +#include + #include #include + #include #include #include @@ -48,29 +50,29 @@ //======================================================================= //function : GetID //purpose : -//======================================================================= +//======================================================================= const Standard_GUID& GEOMImpl_CircleDriver::GetID() { static Standard_GUID aCircleDriver("FF1BBB32-5D14-4df2-980B-3A668264EA16"); - return aCircleDriver; + return aCircleDriver; } //======================================================================= //function : GEOMImpl_CircleDriver -//purpose : +//purpose : //======================================================================= -GEOMImpl_CircleDriver::GEOMImpl_CircleDriver() +GEOMImpl_CircleDriver::GEOMImpl_CircleDriver() { } //======================================================================= //function : Execute //purpose : -//======================================================================= +//======================================================================= Standard_Integer GEOMImpl_CircleDriver::Execute(TFunction_Logbook& log) const { - if (Label().IsNull()) return 0; + if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); GEOMImpl_ICircle aCI (aFunction); @@ -95,20 +97,7 @@ Standard_Integer GEOMImpl_CircleDriver::Execute(TFunction_Logbook& log) const Handle(GEOM_Function) aRefVector = aCI.GetVector(); if (!aRefVector.IsNull()) { TopoDS_Shape aShapeVec = aRefVector->GetValue(); - if (aShapeVec.ShapeType() != TopAbs_EDGE) { - Standard_ConstructionError::Raise - ("Circle creation aborted: invalid vector argument, must be a vector or an edge"); - } - TopoDS_Edge anE = TopoDS::Edge(aShapeVec); - TopoDS_Vertex V1, V2; - TopExp::Vertices(anE, V1, V2, Standard_True); - if (!V1.IsNull() && !V2.IsNull()) { - aV = gp_Vec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2)); - if (aV.Magnitude() < gp::Resolution()) { - Standard_ConstructionError::Raise - ("Circle creation aborted: vector of zero length is given"); - } - } + aV = GEOMUtils::GetVector(aShapeVec); } // Axes gp_Ax2 anAxes (aP, aV); @@ -163,7 +152,7 @@ Standard_Integer GEOMImpl_CircleDriver::Execute(TFunction_Logbook& log) const //Make Circle gp_Ax2 anAxes (aP1, aDir); gp_Circ aCirc (anAxes, aRadius); - aShape = BRepBuilderAPI_MakeEdge(aCirc).Edge(); + aShape = BRepBuilderAPI_MakeEdge(aCirc).Edge(); } } else if (aType == CIRCLE_THREE_PNT) { @@ -187,7 +176,7 @@ Standard_Integer GEOMImpl_CircleDriver::Execute(TFunction_Logbook& log) const Standard_ConstructionError::Raise("Circle creation aborted: points lay on one line"); Handle(Geom_Circle) aCirc = GC_MakeCircle(aP1, aP2, aP3).Value(); aShape = BRepBuilderAPI_MakeEdge(aCirc).Edge(); - } + } } else { } @@ -196,26 +185,26 @@ Standard_Integer GEOMImpl_CircleDriver::Execute(TFunction_Logbook& log) const aFunction->SetValue(aShape); - log.SetTouched(Label()); + log.SetTouched(Label()); - return 1; + return 1; } //======================================================================= //function : GEOMImpl_CircleDriver_Type_ //purpose : -//======================================================================= +//======================================================================= Standard_EXPORT Handle_Standard_Type& GEOMImpl_CircleDriver_Type_() { static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver); if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver); static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared); - if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared); + if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared); static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient); if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient); - + static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL}; static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_CircleDriver", @@ -230,7 +219,7 @@ Standard_EXPORT Handle_Standard_Type& GEOMImpl_CircleDriver_Type_() //======================================================================= //function : DownCast //purpose : -//======================================================================= +//======================================================================= const Handle(GEOMImpl_CircleDriver) Handle(GEOMImpl_CircleDriver)::DownCast(const Handle(Standard_Transient)& AnObject) { Handle(GEOMImpl_CircleDriver) _anOtherObject; diff --git a/src/GEOMImpl/GEOMImpl_FaceDriver.cxx b/src/GEOMImpl/GEOMImpl_FaceDriver.cxx index 4aafb7114..708f8f450 100755 --- a/src/GEOMImpl/GEOMImpl_FaceDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_FaceDriver.cxx @@ -15,16 +15,15 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include #include + #include #include + #include -#include +#include #include #include @@ -89,7 +88,7 @@ Standard_Integer GEOMImpl_FaceDriver::Execute(TFunction_Logbook& log) const } else if (aRefShape.ShapeType() == TopAbs_FACE) { double aH = aFI.GetH() / 2.0; double aW = aFI.GetW() / 2.0; - gp_Ax3 anAx = GEOMImpl_IMeasureOperations::GetPosition(aRefShape); + gp_Ax3 anAx = GEOMUtils::GetPosition(aRefShape); gp_Pln aPln (anAx); aShape = BRepBuilderAPI_MakeFace(aPln, -aH, +aH, -aW, +aW).Shape(); } diff --git a/src/GEOMImpl/GEOMImpl_Fillet1dDriver.cxx b/src/GEOMImpl/GEOMImpl_Fillet1dDriver.cxx index f781f228e..38a0ba318 100644 --- a/src/GEOMImpl/GEOMImpl_Fillet1dDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_Fillet1dDriver.cxx @@ -23,10 +23,12 @@ #include #include #include -#include #include + #include +#include + #include #include #include @@ -352,7 +354,7 @@ bool GEOMImpl_Fillet1dDriver::MakeFillet(const TopoDS_Wire& aWire, aListOfNewEdge.Append(anEdgeToEdgeMap.Find(anEdge)); } - GEOMImpl_IShapesOperations::SortShapes(aListOfNewEdge); + GEOMUtils::SortShapes(aListOfNewEdge); BRepBuilderAPI_MakeWire aWireTool; aWireTool.Add(aListOfNewEdge); diff --git a/src/GEOMImpl/GEOMImpl_IBlocksOperations.cxx b/src/GEOMImpl/GEOMImpl_IBlocksOperations.cxx index efb69f42c..65b2ea018 100644 --- a/src/GEOMImpl/GEOMImpl_IBlocksOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IBlocksOperations.cxx @@ -34,7 +34,8 @@ #include #include #include -#include + +#include #include #include @@ -3492,13 +3493,13 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IBlocksOperations::Propagate } // while (listPrevEdges.Extent() > 0) // Sort shapes in current chain (Mantis issue 21053) - GEOMImpl_IShapesOperations::SortShapes(currentChain, Standard_False); + GEOMUtils::SortShapes(currentChain, Standard_False); aFirstInChains.Append(currentChain.First()); aMapChains.Bind(currentChain.First(), currentChain); } // Sort chains (Mantis issue 21053) - GEOMImpl_IShapesOperations::SortShapes(aFirstInChains, Standard_False); + GEOMUtils::SortShapes(aFirstInChains, Standard_False); // Store sorted chains in the document TopTools_ListIteratorOfListOfShape aChainsIt (aFirstInChains); diff --git a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx index 22237b786..60983a177 100644 --- a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx @@ -736,19 +736,19 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeSplineBezier GEOMImpl_ISpline aCI (aFunction); - int aLen = thePoints.size(); - aCI.SetLength(aLen); aCI.SetConstructorType(POINT_CONSTRUCTOR); - int ind = 1; + Handle(TColStd_HSequenceOfTransient) aPoints = new TColStd_HSequenceOfTransient; std::list::iterator it = thePoints.begin(); - for (; it != thePoints.end(); it++, ind++) { + for (; it != thePoints.end(); it++) { Handle(GEOM_Function) aRefPnt = (*it)->GetLastFunction(); - - if (aRefPnt.IsNull()) return NULL; - - aCI.SetPoint(ind, aRefPnt); + if (aRefPnt.IsNull()) { + SetErrorCode("NULL point for Besier curve"); + return NULL; + } + aPoints->Append(aRefPnt); } + aCI.SetPoints(aPoints); aCI.SetIsClosed(theIsClosed); @@ -798,7 +798,7 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeSplineInterpolation //Add a new Spline object Handle(GEOM_Object) aSpline = GetEngine()->AddObject(GetDocID(), GEOM_SPLINE); - //Add a new Spline function for creation a bezier curve relatively to points set + //Add a new Spline function for interpolation type Handle(GEOM_Function) aFunction = aSpline->AddFunction(GEOMImpl_SplineDriver::GetID(), SPLINE_INTERPOLATION); if (aFunction.IsNull()) return NULL; @@ -808,19 +808,18 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeSplineInterpolation GEOMImpl_ISpline aCI (aFunction); - int aLen = thePoints.size(); aCI.SetConstructorType(POINT_CONSTRUCTOR); - aCI.SetLength(aLen); - int ind = 1; + Handle(TColStd_HSequenceOfTransient) aPoints = new TColStd_HSequenceOfTransient; std::list::iterator it = thePoints.begin(); - for (; it != thePoints.end(); it++, ind++) { + for (; it != thePoints.end(); it++) { Handle(GEOM_Function) aRefPnt = (*it)->GetLastFunction(); - - if (aRefPnt.IsNull()) return NULL; - - aCI.SetPoint(ind, aRefPnt); + if (aRefPnt.IsNull()) { + return NULL; + } + aPoints->Append(aRefPnt); } + aCI.SetPoints(aPoints); aCI.SetIsClosed(theIsClosed); aCI.SetDoReordering(theDoReordering); @@ -856,6 +855,85 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeSplineInterpolation return aSpline; } + +//============================================================================= +/*! + * MakeSplineInterpolWithTangents + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeSplineInterpolWithTangents + (std::list thePoints, + Handle(GEOM_Object) theFirstVec, + Handle(GEOM_Object) theLastVec) +{ + SetErrorCode(KO); + + //Add a new Spline object + Handle(GEOM_Object) aSpline = GetEngine()->AddObject(GetDocID(), GEOM_SPLINE); + + //Add a new Spline function for interpolation type + Handle(GEOM_Function) aFunction = + aSpline->AddFunction(GEOMImpl_SplineDriver::GetID(), SPLINE_INTERPOL_TANGENTS); + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_SplineDriver::GetID()) return NULL; + + GEOMImpl_ISpline aCI (aFunction); + + aCI.SetConstructorType(POINT_CONSTRUCTOR); + + Handle(TColStd_HSequenceOfTransient) aPoints = new TColStd_HSequenceOfTransient; + std::list::iterator it = thePoints.begin(); + for (; it != thePoints.end(); it++) { + Handle(GEOM_Function) aRefPnt = (*it)->GetLastFunction(); + if (aRefPnt.IsNull()) { + SetErrorCode("NULL point for Interpolation"); + return NULL; + } + aPoints->Append(aRefPnt); + } + aCI.SetPoints(aPoints); + + Handle(GEOM_Function) aVec1 = theFirstVec->GetLastFunction(); + Handle(GEOM_Function) aVec2 = theLastVec->GetLastFunction(); + + if (aVec1.IsNull() || aVec2.IsNull()) return NULL; + + aCI.SetFirstVector(aVec1); + aCI.SetLastVector(aVec2); + + //Compute the Spline value + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Spline driver failed"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return NULL; + } + + //Make a Python command + GEOM::TPythonDump pd (aFunction); + pd << aSpline << " = geompy.MakeInterpolWithTangents(["; + + it = thePoints.begin(); + pd << (*it++); + while (it != thePoints.end()) { + pd << ", " << (*it++); + } + pd << "], " << theFirstVec << ", " << theLastVec << ")"; + + SetErrorCode(OK); + return aSpline; +} + //============================================================================= /*! * MakeCurveParametric @@ -864,7 +942,7 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeSplineInterpolation Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCurveParametric (const char* thexExpr, const char* theyExpr, const char* thezExpr, double theParamMin, double theParamMax, double theParamStep, - CurveType theCurveType, + CurveType theCurveType, int theParamNbStep, bool theNewMethod) { TCollection_AsciiString aPyScript; @@ -958,7 +1036,7 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCurveParametric coords = PyObject_CallFunction(func,(char*)"(d, d, i)", theParamMin, theParamMax, theParamNbStep ); else coords = PyObject_CallFunction(func,(char*)"(d, d, d)", theParamMin, theParamMax, theParamStep ); - + PyObject* new_stderr = NULL; if (coords == NULL){ @@ -1038,7 +1116,6 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCurveParametric GEOMImpl_ISpline aCI (aFunction); - aCI.SetLength(lsize); aCI.SetConstructorType(COORD_CONSTRUCTOR); aCI.SetIsClosed(false); aCI.SetCoordinates(aCoordsArray); @@ -1058,7 +1135,6 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCurveParametric GEOMImpl_ISpline aCI (aFunction); aCI.SetConstructorType(COORD_CONSTRUCTOR); - aCI.SetLength(lsize); aCI.SetIsClosed(false); aCI.SetDoReordering(false); aCI.SetCoordinates(aCoordsArray); diff --git a/src/GEOMImpl/GEOMImpl_ICurvesOperations.hxx b/src/GEOMImpl/GEOMImpl_ICurvesOperations.hxx index 829f9cc5d..f3e93170d 100644 --- a/src/GEOMImpl/GEOMImpl_ICurvesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_ICurvesOperations.hxx @@ -32,11 +32,11 @@ class GEOM_Engine; class Handle(GEOM_Object); class GEOMImpl_ICurvesOperations : public GEOM_IOperations { - + public: enum CurveType { Polyline, Bezier, Interpolation }; - + Standard_EXPORT GEOMImpl_ICurvesOperations(GEOM_Engine* theEngine, int theDocID); Standard_EXPORT ~GEOMImpl_ICurvesOperations(); @@ -57,7 +57,7 @@ class GEOMImpl_ICurvesOperations : public GEOM_IOperations { Standard_EXPORT Handle(GEOM_Object) MakeArc (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2, Handle(GEOM_Object) thePnt3); - + Standard_EXPORT Handle(GEOM_Object) MakeArcCenter (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2, Handle(GEOM_Object) thePnt3, @@ -77,9 +77,14 @@ class GEOMImpl_ICurvesOperations : public GEOM_IOperations { bool theIsClosed = false, bool theDoReordering = false); + Standard_EXPORT Handle(GEOM_Object) MakeSplineInterpolWithTangents + (std::list thePoints, + Handle(GEOM_Object) theFirstVec, + Handle(GEOM_Object) theLastVec); + Standard_EXPORT Handle(GEOM_Object) MakeCurveParametric - (const char* thexExpr, const char* theyExpr, const char* thezExpr, - double theParamMin, double theParamMax, double theParamStep, + (const char* thexExpr, const char* theyExpr, const char* thezExpr, + double theParamMin, double theParamMax, double theParamStep, CurveType theCurveType, int theParamNbStep=0, bool theNewMethod=false); Standard_EXPORT Handle(GEOM_Object) MakeSketcher (const char* theCommand, diff --git a/src/GEOMImpl/GEOMImpl_IInsertOperations.cxx b/src/GEOMImpl/GEOMImpl_IInsertOperations.cxx index afd889529..4fecfbca9 100644 --- a/src/GEOMImpl/GEOMImpl_IInsertOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IInsertOperations.cxx @@ -218,7 +218,7 @@ Handle(GEOM_Object) GEOMImpl_IInsertOperations::Import if (aFunction->GetDriverGUID() != GEOMImpl_ImportDriver::GetID()) return result; Handle(TCollection_HAsciiString) aHLibName; - if (!IsSupported(Standard_True, theFormatName/*.SubString(1,4)*/, aHLibName)) { + if (!IsSupported(Standard_True, theFormatName.SubString(1,4), aHLibName)) { return result; } TCollection_AsciiString aLibName = aHLibName->String(); @@ -302,7 +302,7 @@ TCollection_AsciiString GEOMImpl_IInsertOperations::ReadValue if (theFileName.IsEmpty() || theFormatName.IsEmpty() || theParameterName.IsEmpty()) return aValue; Handle(TCollection_HAsciiString) aHLibName; - if (!IsSupported(Standard_True, theFormatName/*.SubString(1,4)*/, aHLibName)) { + if (!IsSupported(Standard_True, theFormatName.SubString(1,4), aHLibName)) { return aValue; } TCollection_AsciiString aLibName = aHLibName->String(); diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index df3a87a49..b81e5c7ab 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -28,6 +28,8 @@ #include #include +#include + #include #include @@ -765,69 +767,6 @@ GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape return aKind; } -//============================================================================= -/*! Get LCS, corresponding to the given shape. - * Origin of the LCS is situated at the shape's center of mass. - * Axes of the LCS are obtained from shape's location or, - * if the shape is a planar face, from position of its plane. - */ -//============================================================================= -gp_Ax3 GEOMImpl_IMeasureOperations::GetPosition (const TopoDS_Shape& theShape) -{ - gp_Ax3 aResult; - - if (theShape.IsNull()) - return aResult; - - // Axes - aResult.Transform(theShape.Location().Transformation()); - if (theShape.ShapeType() == TopAbs_FACE) { - Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(theShape)); - if (!aGS.IsNull() && aGS->IsKind(STANDARD_TYPE(Geom_Plane))) { - Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast(aGS); - gp_Pln aPln = aGPlane->Pln(); - aResult = aPln.Position(); - // In case of reverse orinetation of the face invert the plane normal - // (the face's normal does not mathc the plane's normal in this case) - if(theShape.Orientation() == TopAbs_REVERSED) - { - gp_Dir Vx = aResult.XDirection(); - gp_Dir N = aResult.Direction().Mirrored(Vx); - gp_Pnt P = aResult.Location(); - aResult = gp_Ax3(P, N, Vx); - } - } - } - - // Origin - gp_Pnt aPnt; - - TopAbs_ShapeEnum aShType = theShape.ShapeType(); - - if (aShType == TopAbs_VERTEX) { - aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape)); - } - else { - if (aShType == TopAbs_COMPOUND) { - aShType = GEOMImpl_IShapesOperations::GetTypeOfSimplePart(theShape); - } - - GProp_GProps aSystem; - if (aShType == TopAbs_EDGE || aShType == TopAbs_WIRE) - BRepGProp::LinearProperties(theShape, aSystem); - else if (aShType == TopAbs_FACE || aShType == TopAbs_SHELL) - BRepGProp::SurfaceProperties(theShape, aSystem); - else - BRepGProp::VolumeProperties(theShape, aSystem); - - aPnt = aSystem.CentreOfMass(); - } - - aResult.SetLocation(aPnt); - - return aResult; -} - //============================================================================= /*! * GetPosition @@ -861,7 +800,7 @@ void GEOMImpl_IMeasureOperations::GetPosition OCC_CATCH_SIGNALS; #endif - gp_Ax3 anAx3 = GetPosition(aShape); + gp_Ax3 anAx3 = GEOMUtils::GetPosition(aShape); gp_Pnt anOri = anAx3.Location(); gp_Dir aDirZ = anAx3.Direction(); @@ -1227,6 +1166,59 @@ void GEOMImpl_IMeasureOperations::GetBoundingBox SetErrorCode(OK); } +//============================================================================= +/*! + * GetBoundingBox + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox + (Handle(GEOM_Object) theShape) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) return NULL; + + //Add a new BoundingBox object + Handle(GEOM_Object) aBnd = GetEngine()->AddObject(GetDocID(), GEOM_BOX); + + //Add a new BoundingBox function + Handle(GEOM_Function) aFunction = + aBnd->AddFunction(GEOMImpl_MeasureDriver::GetID(), BND_BOX_MEASURE); + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL; + + GEOMImpl_IMeasure aCI (aFunction); + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return NULL; + + aCI.SetBase(aRefShape); + + //Compute the BoundingBox value + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Measure driver failed to compute a bounding box"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return NULL; + } + + //Make a Python command + GEOM::TPythonDump(aFunction) << aBnd << " = geompy.MakeBoundingBox(" << theShape << ")"; + + SetErrorCode(OK); + return aBnd; +} + //============================================================================= /*! * GetTolerance @@ -1550,6 +1542,36 @@ TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object) return Astr; } +//============================================================================= +/*! + * AreCoordsInside + */ +//============================================================================= +std::vector GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Object) theShape, + const std::vector& coords, + double tolerance) +{ + std::vector res; + if (!theShape.IsNull()) { + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (!aRefShape.IsNull()) { + TopoDS_Shape aShape = aRefShape->GetValue(); + if (!aShape.IsNull()) { + BRepClass3d_SolidClassifier SC(aShape); + unsigned int nb_points = coords.size()/3; + for (int i = 0; i < nb_points; i++) { + double x = coords[3*i]; + double y = coords[3*i+1]; + double z = coords[3*i+2]; + gp_Pnt aPnt(x, y, z); + SC.Perform(aPnt, tolerance); + res.push_back( ( SC.State() == TopAbs_IN ) || ( SC.State() == TopAbs_ON ) ); + } + } + } + } + return res; +} //======================================================================= //function : CheckSingularCase @@ -1853,38 +1875,6 @@ static bool CheckSingularCase(const TopoDS_Shape& aSh1, } */ - -//============================================================================= -/*! - * AreCoordsInside - */ -//============================================================================= -std::vector GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Object) theShape, - const std::vector& coords, - double tolerance) -{ - std::vector res; - if (!theShape.IsNull()) { - Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); - if (!aRefShape.IsNull()) { - TopoDS_Shape aShape = aRefShape->GetValue(); - if (!aShape.IsNull()) { - BRepClass3d_SolidClassifier SC(aShape); - unsigned int nb_points = coords.size()/3; - for (int i = 0; i < nb_points; i++) { - double x = coords[3*i]; - double y = coords[3*i+1]; - double z = coords[3*i+2]; - gp_Pnt aPnt(x, y, z); - SC.Perform(aPnt, tolerance); - res.push_back( ( SC.State() == TopAbs_IN ) || ( SC.State() == TopAbs_ON ) ); - } - } - } - } - return res; -} - //============================================================================= /*! * GetMinDistance @@ -1949,7 +1939,7 @@ Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance // additional workaround for bugs 19899, 19908 and 19910 from Mantis gp_Pnt Ptmp1, Ptmp2; double dist = CheckSingularCase(aShape1, aShape2, Ptmp1, Ptmp2); - if(dist>-1.0) { + if (dist > -1.0) { Ptmp1.Coord(X1, Y1, Z1); Ptmp2.Coord(X2, Y2, Z2); SetErrorCode(OK); @@ -1986,6 +1976,84 @@ Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance return MinDist; } +//======================================================================= +/*! + * Get coordinates of closest points of two shapes + */ +//======================================================================= +Standard_Integer GEOMImpl_IMeasureOperations::ClosestPoints (Handle(GEOM_Object) theShape1, + Handle(GEOM_Object) theShape2, + Handle(TColStd_HSequenceOfReal)& theDoubles) +{ + SetErrorCode(KO); + Standard_Integer nbSolutions = 0; + + if (theShape1.IsNull() || theShape2.IsNull()) return nbSolutions; + + Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction(); + Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction(); + if (aRefShape1.IsNull() || aRefShape2.IsNull()) return nbSolutions; + + TopoDS_Shape aShape1 = aRefShape1->GetValue(); + TopoDS_Shape aShape2 = aRefShape2->GetValue(); + if (aShape1.IsNull() || aShape2.IsNull()) { + SetErrorCode("One of Objects has NULL Shape"); + return nbSolutions; + } + + // Compute the extremities + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + + // skl 30.06.2008 + // additional workaround for bugs 19899, 19908 and 19910 from Mantis + gp_Pnt P1, P2; + double dist = CheckSingularCase(aShape1, aShape2, P1, P2); + if (dist > -1.0) { + nbSolutions = 1; + + theDoubles->Append(P1.X()); + theDoubles->Append(P1.Y()); + theDoubles->Append(P1.Z()); + theDoubles->Append(P2.X()); + theDoubles->Append(P2.Y()); + theDoubles->Append(P2.Z()); + + SetErrorCode(OK); + return nbSolutions; + } + + BRepExtrema_DistShapeShape dst (aShape1, aShape2); + if (dst.IsDone()) { + nbSolutions = dst.NbSolution(); + if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal; + + gp_Pnt P1, P2; + for (int i = 1; i <= nbSolutions; i++) { + P1 = dst.PointOnShape1(i); + P2 = dst.PointOnShape2(i); + + theDoubles->Append(P1.X()); + theDoubles->Append(P1.Y()); + theDoubles->Append(P1.Z()); + theDoubles->Append(P2.X()); + theDoubles->Append(P2.Y()); + theDoubles->Append(P2.Z()); + } + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return nbSolutions; + } + + SetErrorCode(OK); + return nbSolutions; +} + //======================================================================= /*! * Get coordinates of point diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx index d84b8743c..1a9071838 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #ifndef _GEOMImpl_IMeasureOperations_HXX_ #define _GEOMImpl_IMeasureOperations_HXX_ @@ -118,6 +117,8 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations { Standard_Real& Ymin, Standard_Real& Ymax, Standard_Real& Zmin, Standard_Real& Zmax); + Standard_EXPORT Handle(GEOM_Object) GetBoundingBox (Handle(GEOM_Object) theShape); + Standard_EXPORT void GetTolerance (Handle(GEOM_Object) theShape, Standard_Real& FaceMin, Standard_Real& FaceMax, Standard_Real& EdgeMin, Standard_Real& EdgeMax, @@ -143,6 +144,10 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations { Standard_Real& X1, Standard_Real& Y1, Standard_Real& Z1, Standard_Real& X2, Standard_Real& Y2, Standard_Real& Z2); + Standard_EXPORT Standard_Integer ClosestPoints (Handle(GEOM_Object) theShape1, + Handle(GEOM_Object) theShape2, + Handle(TColStd_HSequenceOfReal)& theDoubles); + Standard_EXPORT void PointCoordinates (Handle(GEOM_Object) theShape, Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ); @@ -168,9 +173,6 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations { Standard_EXPORT Standard_Real MinSurfaceCurvatureByPoint (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint); - public: - Standard_EXPORT static gp_Ax3 GetPosition (const TopoDS_Shape& theShape); - private: void StructuralDump (const BRepCheck_Analyzer& theAna, const TopoDS_Shape& theShape, diff --git a/src/GEOMImpl/GEOMImpl_IPipeDiffSect.hxx b/src/GEOMImpl/GEOMImpl_IPipeDiffSect.hxx index dbdb52601..393e65a47 100644 --- a/src/GEOMImpl/GEOMImpl_IPipeDiffSect.hxx +++ b/src/GEOMImpl/GEOMImpl_IPipeDiffSect.hxx @@ -18,15 +18,16 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// //NOTE: This is an intreface to a function for the Pipe creation. -// + #ifndef _GEOMImpl_IPIPEDIFFSECT_HXX_ #define _GEOMImpl_IPIPEDIFFSECT_HXX_ #include "GEOM_Function.hxx" +#include + #ifndef _GEOMImpl_IPIPE_HXX_ #include "GEOMImpl_IPipe.hxx" #endif diff --git a/src/GEOMImpl/GEOMImpl_IPipePath.hxx b/src/GEOMImpl/GEOMImpl_IPipePath.hxx index 028ab2f53..7b2ccd40a 100644 --- a/src/GEOMImpl/GEOMImpl_IPipePath.hxx +++ b/src/GEOMImpl/GEOMImpl_IPipePath.hxx @@ -23,6 +23,8 @@ #include "GEOM_Function.hxx" +#include + class GEOMImpl_IPipePath { public: diff --git a/src/GEOMImpl/GEOMImpl_IPipeShellSect.hxx b/src/GEOMImpl/GEOMImpl_IPipeShellSect.hxx index 0b3f35fd4..3061153f0 100644 --- a/src/GEOMImpl/GEOMImpl_IPipeShellSect.hxx +++ b/src/GEOMImpl/GEOMImpl_IPipeShellSect.hxx @@ -15,10 +15,9 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// //NOTE: This is an intreface to a function for the Pipe creation. -// + #ifndef _GEOMImpl_IPIPESHELLSECT_HXX_ #define _GEOMImpl_IPIPESHELLSECT_HXX_ @@ -28,6 +27,8 @@ #include "GEOMImpl_IPipeDiffSect.hxx" #endif +#include + #define PIPEDS_LIST_SUBBASES 6 diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index 682311302..fd1771a6a 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -48,6 +48,8 @@ #include "GEOM_ISubShape.hxx" #include "GEOM_PythonDump.hxx" +#include "GEOMUtils.hxx" + #include "GEOMAlgo_ClsfBox.hxx" #include "GEOMAlgo_ClsfSolid.hxx" #include "GEOMAlgo_CoupleOfShapes.hxx" @@ -141,8 +143,6 @@ #include #include -#define STD_SORT_ALGO 1 - //============================================================================= /*! * constructor: @@ -1023,7 +1023,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueShapes } // for stable order of returned entities - GEOMImpl_IShapesOperations::SortShapes(listOnePerSet, Standard_False); + GEOMUtils::SortShapes(listOnePerSet, Standard_False); TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet); for (; aListIt.More(); aListIt.Next()) { @@ -1267,7 +1267,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode bool isOldSorting = false; if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN) isOldSorting = true; - SortShapes(listShape, isOldSorting); + GEOMUtils::SortShapes(listShape, isOldSorting); } TopTools_IndexedMapOfShape anIndices; @@ -1391,7 +1391,7 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs bool isOldSorting = false; if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN) isOldSorting = true; - SortShapes(listShape, isOldSorting); + GEOMUtils::SortShapes(listShape, isOldSorting); } TopTools_IndexedMapOfShape anIndices; @@ -1558,14 +1558,62 @@ Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Objec TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(aMainShape, anIndices); - if (anIndices.Contains(aSubShape)) { +// if (anIndices.Contains(aSubShape)) { +// SetErrorCode(OK); +// return anIndices.FindIndex(aSubShape); +// } + int id = anIndices.FindIndex(aSubShape); + if (id > 0) + { SetErrorCode(OK); - return anIndices.FindIndex(aSubShape); + return id; } - return -1; } + + +//============================================================================= +/*! + * GetSubShapeIndices + */ +//============================================================================= +Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape, + std::list theSubShapes) +{ + MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices") + SetErrorCode(KO); + + Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger; + + TopoDS_Shape aMainShape = theMainShape->GetValue(); + if (aMainShape.IsNull()) + { + MESSAGE("NULL main shape") + return NULL; + } + + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aMainShape, anIndices); + + std::list::iterator it; + for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it) + { + TopoDS_Shape aSubShape = (*it)->GetValue(); + if (aSubShape.IsNull()) + { + MESSAGE("NULL subshape") + return NULL; + } + int id = anIndices.FindIndex(aSubShape); + aSeq->Append(id); + } + + SetErrorCode(OK); + return aSeq; +} + + //============================================================================= /*! * GetTopologyIndex @@ -2217,7 +2265,7 @@ Handle(TColStd_HSequenceOfInteger) TopoDS_Shape aShape = theShape->GetValue(); // Check presence of triangulation, build if need - if (!CheckTriangulation(aShape)) { + if (!GEOMUtils::CheckTriangulation(aShape)) { SetErrorCode("Cannot build triangulation on the shape"); return aSeqOfIDs; } @@ -2302,7 +2350,7 @@ Handle(TColStd_HSequenceOfInteger) Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction(); // Make a Python command - GEOM::TPythonDump(aFunction) + GEOM::TPythonDump(aFunction, /*append=*/true) << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs(" << theBox << ", " << theShape << ", " @@ -2384,7 +2432,7 @@ Handle(TColStd_HSequenceOfInteger) TopTools_ListOfShape res; // Check presence of triangulation, build if need - if (!CheckTriangulation(aShape)) { + if (!GEOMUtils::CheckTriangulation(aShape)) { SetErrorCode("Cannot build triangulation on the shape"); return aSeqOfIDs; } @@ -2475,7 +2523,7 @@ Handle(TColStd_HSequenceOfInteger) GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction(); // Make a Python command - GEOM::TPythonDump(aFunction) + GEOM::TPythonDump(aFunction, /*append=*/true) << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs(" << theCheckShape << ", " << theShape << ", " @@ -2604,7 +2652,7 @@ Handle(TColStd_HSequenceOfInteger) Handle(TColStd_HSequenceOfInteger) aSeqOfIDs; // Check presence of triangulation, build if need - if (!CheckTriangulation(theShape)) { + if (!GEOMUtils::CheckTriangulation(theShape)) { SetErrorCode("Cannot build triangulation on the shape"); return aSeqOfIDs; } @@ -3321,7 +3369,7 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphere // Make a Python command GEOM::TPythonDump(aFunction, /*append=*/true) - << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs" + << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs" << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", " << theRadius << ", " << theState << ")"; @@ -3385,7 +3433,7 @@ Handle(TColStd_HSequenceOfInteger) Handle(TColStd_HSequenceOfInteger) aSeqOfIDs; // Check presence of triangulation, build if need - if (!CheckTriangulation(aShape)) { + if (!GEOMUtils::CheckTriangulation(aShape)) { SetErrorCode("Cannot build triangulation on the shape"); return aSeqOfIDs; } @@ -3776,28 +3824,6 @@ namespace { } } -//================================================================================ -/*! - * \brief Return type of shape for explode. In case of compound it will be a type of sub-shape. - */ -//================================================================================ -TopAbs_ShapeEnum GEOMImpl_IShapesOperations::GetTypeOfSimplePart (const TopoDS_Shape& theShape) -{ - TopAbs_ShapeEnum aType = theShape.ShapeType(); - if (aType == TopAbs_VERTEX) return TopAbs_VERTEX; - else if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) return TopAbs_EDGE; - else if (aType == TopAbs_FACE || aType == TopAbs_SHELL) return TopAbs_FACE; - else if (aType == TopAbs_SOLID || aType == TopAbs_COMPSOLID) return TopAbs_SOLID; - else if (aType == TopAbs_COMPOUND) { - // Only the iType of the first shape in the compound is taken into account - TopoDS_Iterator It (theShape, Standard_False, Standard_False); - if (It.More()) { - return GetTypeOfSimplePart(It.Value()); - } - } - return TopAbs_SHAPE; -} - //============================================================================= /*! * case GetInPlace: @@ -3839,7 +3865,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) GProp_GProps aProps; // Find the iType of the aWhat shape - iType = GetTypeOfSimplePart(aWhat); + iType = GEOMUtils::GetTypeOfSimplePart(aWhat); if (iType == TopAbs_SHAPE) { SetErrorCode("Error: An attempt to extract a shape of not supported type."); return NULL; @@ -4041,7 +4067,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Objec return NULL; } */ - iType = GetTypeOfSimplePart(aWhat); + iType = GEOMUtils::GetTypeOfSimplePart(aWhat); if (iType == TopAbs_SHAPE) { SetErrorCode("Error: An attempt to extract a shape of not supported type."); return NULL; @@ -4266,321 +4292,6 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory return aResult; } -//======================================================================= -//function : ShapeToDouble -//purpose : used by CompareShapes::operator() -//======================================================================= -std::pair ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting) -{ - // Computing of CentreOfMass - gp_Pnt GPoint; - double Len; - - if (S.ShapeType() == TopAbs_VERTEX) { - GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S)); - Len = (double)S.Orientation(); - } - else { - GProp_GProps GPr; - // BEGIN: fix for Mantis issue 0020842 - if (isOldSorting) { - BRepGProp::LinearProperties(S, GPr); - } - else { - if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) { - BRepGProp::LinearProperties(S, GPr); - } - else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) { - BRepGProp::SurfaceProperties(S, GPr); - } - else { - BRepGProp::VolumeProperties(S, GPr); - } - } - // END: fix for Mantis issue 0020842 - GPoint = GPr.CentreOfMass(); - Len = GPr.Mass(); - } - - double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9; - return std::make_pair(dMidXYZ, Len); -} - -//======================================================================= -//function : CompareShapes::operator() -//purpose : used by std::sort(), called from SortShapes() -//======================================================================= -bool GEOMImpl_IShapesOperations::CompareShapes::operator()(const TopoDS_Shape& theShape1, - const TopoDS_Shape& theShape2) -{ - if (!myMap.IsBound(theShape1)) { - myMap.Bind(theShape1, ShapeToDouble(theShape1, myIsOldSorting)); - } - - if (!myMap.IsBound(theShape2)) { - myMap.Bind(theShape2, ShapeToDouble(theShape2, myIsOldSorting)); - } - - std::pair val1 = myMap.Find(theShape1); - std::pair val2 = myMap.Find(theShape2); - - double tol = Precision::Confusion(); - bool exchange = Standard_False; - - double dMidXYZ = val1.first - val2.first; - if (dMidXYZ >= tol) { - exchange = Standard_True; - } - else if (Abs(dMidXYZ) < tol) { - double dLength = val1.second - val2.second; - if (dLength >= tol) { - exchange = Standard_True; - } - else if (Abs(dLength) < tol && theShape1.ShapeType() <= TopAbs_FACE) { - // PAL17233 - // equal values possible on shapes such as two halves of a sphere and - // a membrane inside the sphere - Bnd_Box box1,box2; - BRepBndLib::Add(theShape1, box1); - if (!box1.IsVoid()) { - BRepBndLib::Add(theShape2, box2); - Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent(); - if (dSquareExtent >= tol) { - exchange = Standard_True; - } - else if (Abs(dSquareExtent) < tol) { - Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2; - box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); - val1 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9; - box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); - val2 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9; - if ((val1 - val2) >= tol) { - exchange = Standard_True; - } - } - } - } - } - - //return val1 < val2; - return !exchange; -} - -//======================================================================= -//function : SortShapes -//purpose : -//======================================================================= -void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL, - const Standard_Boolean isOldSorting) -{ -#ifdef STD_SORT_ALGO - std::vector aShapesVec; - aShapesVec.reserve(SL.Extent()); - - TopTools_ListIteratorOfListOfShape it (SL); - for (; it.More(); it.Next()) { - aShapesVec.push_back(it.Value()); - } - SL.Clear(); - - CompareShapes shComp (isOldSorting); - std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp); - //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp); - - std::vector::const_iterator anIter = aShapesVec.begin(); - for (; anIter != aShapesVec.end(); ++anIter) { - SL.Append(*anIter); - } -#else - // old implementation - Standard_Integer MaxShapes = SL.Extent(); - TopTools_Array1OfShape aShapes (1,MaxShapes); - TColStd_Array1OfInteger OrderInd(1,MaxShapes); - TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z; - TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z; - - // Computing of CentreOfMass - Standard_Integer Index; - GProp_GProps GPr; - gp_Pnt GPoint; - TopTools_ListIteratorOfListOfShape it(SL); - for (Index=1; it.More(); Index++) - { - TopoDS_Shape S = it.Value(); - SL.Remove( it ); // == it.Next() - aShapes(Index) = S; - OrderInd.SetValue (Index, Index); - if (S.ShapeType() == TopAbs_VERTEX) { - GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S )); - Length.SetValue( Index, (Standard_Real) S.Orientation()); - } - else { - // BEGIN: fix for Mantis issue 0020842 - if (isOldSorting) { - BRepGProp::LinearProperties (S, GPr); - } - else { - if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) { - BRepGProp::LinearProperties (S, GPr); - } - else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) { - BRepGProp::SurfaceProperties(S, GPr); - } - else { - BRepGProp::VolumeProperties(S, GPr); - } - } - // END: fix for Mantis issue 0020842 - GPoint = GPr.CentreOfMass(); - Length.SetValue(Index, GPr.Mass()); - } - MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9); - //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl; - } - - // Sorting - Standard_Integer aTemp; - Standard_Boolean exchange, Sort = Standard_True; - Standard_Real tol = Precision::Confusion(); - while (Sort) - { - Sort = Standard_False; - for (Index=1; Index < MaxShapes; Index++) - { - exchange = Standard_False; - Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1)); - Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1)); - if ( dMidXYZ >= tol ) { -// cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <= tol ) { -// cout << "Length: " << Length(OrderInd(Index))<< " > " <= tol ) { -// cout << "SquareExtent: " << box1.SquareExtent()<<" > "< val2; - if ((val1 - val2) >= tol) { - exchange = Standard_True; - } - //cout << "box: " << val1<<" > "<GetLastFunction(); // Make a Python command - GEOM::TPythonDump(aFunction) + GEOM::TPythonDump(aFunction, /*append=*/true) << "listSameIDs = geompy.GetSameIDs(" << theShapeWhere << ", " << theShapeWhat << ")"; diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index 21885888a..745142c8c 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -51,11 +51,6 @@ class GEOM_Engine; class Handle(GEOM_Object); class Handle(TColStd_HArray1OfInteger); -inline Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2) -{ - return S1.IsSame(S2); -} - class GEOMImpl_IShapesOperations : public GEOM_IOperations { public: @@ -142,6 +137,9 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations Standard_EXPORT Standard_Integer GetSubShapeIndex (Handle(GEOM_Object) theMainShape, Handle(GEOM_Object) theSubShape); + + Standard_EXPORT Handle(TColStd_HSequenceOfInteger) GetSubShapesIndices (Handle(GEOM_Object) theMainShape, + std::list theSubShapes); Standard_EXPORT Standard_Integer GetTopologyIndex (Handle(GEOM_Object) theMainShape, Handle(GEOM_Object) theSubShape); @@ -375,50 +373,6 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations const Standard_Integer theShapeType, GEOMAlgo_State theState); - public: - /*! - * \brief Sort shapes in the list by their coordinates. - * \param SL The list of shapes to sort. - */ - struct CompareShapes : public std::binary_function - { - CompareShapes (bool isOldSorting) - : myIsOldSorting(isOldSorting) {} - - bool operator()(const TopoDS_Shape& lhs, const TopoDS_Shape& rhs); - - typedef NCollection_DataMap > NCollection_DataMapOfShapeDouble; - NCollection_DataMapOfShapeDouble myMap; - bool myIsOldSorting; - }; - - Standard_EXPORT static void SortShapes (TopTools_ListOfShape& SL, - const Standard_Boolean isOldSorting = Standard_True); - - /*! - * \brief Convert TopoDS_COMPSOLID to TopoDS_COMPOUND. - * - * If the argument shape is not of type TopoDS_COMPSOLID, this method returns it as is. - * - * \param theCompsolid The compsolid to be converted. - * \retval TopoDS_Shape Returns the resulting compound. - */ - Standard_EXPORT static TopoDS_Shape CompsolidToCompound (const TopoDS_Shape& theCompsolid); - - /*! - * \brief Build a triangulation on \a theShape if it is absent. - * \param theShape The shape to check/build triangulation on. - * \retval bool Returns false if the shape has no faces, i.e. impossible to build triangulation. - */ - Standard_EXPORT static bool CheckTriangulation (const TopoDS_Shape& theShape); - - /*! - * \brief Return type of shape for explode. In case of compound it will be a type of its first sub shape. - * \param theShape The shape to get type of. - * \retval TopAbs_ShapeEnum Return type of shape for explode. - */ - Standard_EXPORT static TopAbs_ShapeEnum GetTypeOfSimplePart (const TopoDS_Shape& theShape); - private: Handle(GEOM_Object) MakeShape (std::list theShapes, const Standard_Integer theObjectType, diff --git a/src/GEOMImpl/GEOMImpl_ISpline.hxx b/src/GEOMImpl/GEOMImpl_ISpline.hxx index b20a7e6dc..e7f8b076a 100644 --- a/src/GEOMImpl/GEOMImpl_ISpline.hxx +++ b/src/GEOMImpl/GEOMImpl_ISpline.hxx @@ -18,53 +18,84 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // NOTE: This is an interface to a function for the Spline creation. -#include "GEOM_Function.hxx" -#include +#include -#define SPL_ARG_LENG 1 -#define SPL_ARG_CLOS 2 -#define SPL_ARG_REOR 3 -#define SPL_ARG_LAST 2 - -#define SPL_CONSTRUCTOR 4 -#define SPL_ARG_ARRAY 5 +#include +#include class GEOMImpl_ISpline { public: + enum { + ARG_POINTS = 1, + ARG_CLOSED = 2, + ARG_REORDER = 3, + CONSTRUCTOR = 4, + ARG_ARRAY = 5, + ARG_VEC_1 = 6, + ARG_VEC_2 = 7 + }; + GEOMImpl_ISpline(Handle(GEOM_Function) theFunction): _func(theFunction) {} - void SetLength(int theLen) { _func->SetInteger(SPL_ARG_LENG, theLen); } + // Set - void SetIsClosed(bool theIsClosed) { _func->SetInteger(SPL_ARG_CLOS, (int)theIsClosed); } + void SetPoints (const Handle(TColStd_HSequenceOfTransient)& thePoints) + { _func->SetReferenceList(ARG_POINTS, thePoints); } - void SetDoReordering(bool theDoReordering) { _func->SetInteger(SPL_ARG_REOR, (int)theDoReordering); } + void SetIsClosed (bool theIsClosed) { _func->SetInteger(ARG_CLOSED, (int)theIsClosed); } + void SetDoReordering (bool theDoReordering) { _func->SetInteger(ARG_REORDER, (int)theDoReordering); } - void SetPoint(int theId, Handle(GEOM_Function) theP) { _func->SetReference(SPL_ARG_LAST + theId, theP); } + void SetConstructorType (int theConstructor) { _func->SetInteger(CONSTRUCTOR, theConstructor); } - int GetLength() { return _func->GetInteger(SPL_ARG_LENG); } + void SetCoordinates (const Handle(TColStd_HArray1OfReal)& theValue) + { _func->SetRealArray(ARG_ARRAY, theValue); } - bool GetIsClosed() { return (bool)_func->GetInteger(SPL_ARG_CLOS); } + void SetFirstVector (Handle(GEOM_Function) theVec) { _func->SetReference(ARG_VEC_1, theVec); } + void SetLastVector (Handle(GEOM_Function) theVec) { _func->SetReference(ARG_VEC_2, theVec); } - bool GetDoReordering() { return (bool)_func->GetInteger(SPL_ARG_REOR); } + // Get - Handle(GEOM_Function) GetPoint(int theId) { return _func->GetReference(SPL_ARG_LAST + theId); } + Handle(TColStd_HSequenceOfTransient) GetPoints() { return _func->GetReferenceList(ARG_POINTS); } + bool GetIsClosed() { return (bool)_func->GetInteger(ARG_CLOSED); } + bool GetDoReordering() { return (bool)_func->GetInteger(ARG_REORDER); } - void SetConstructorType(int theConstructor) {_func->SetInteger(SPL_CONSTRUCTOR,theConstructor); } + int GetConstructorType() { return _func->GetInteger(CONSTRUCTOR); } - int GetConstructorType() { return _func->GetInteger(SPL_CONSTRUCTOR); } + Handle(TColStd_HArray1OfReal) GetCoordinates() { return _func->GetRealArray(ARG_ARRAY); } + Handle(GEOM_Function) GetFirstVector () { return _func->GetReference(ARG_VEC_1); } + Handle(GEOM_Function) GetLastVector () { return _func->GetReference(ARG_VEC_2); } + + /* Old implementation (Salome 6.6.0 and earlier) +#define SPL_ARG_LENG 1 +#define SPL_ARG_CLOS 2 +#define SPL_ARG_REOR 3 +#define SPL_ARG_LAST 2 + +#define SPL_CONSTRUCTOR 4 +#define SPL_ARG_ARRAY 5 + + void SetLength(int theLen) { _func->SetInteger(SPL_ARG_LENG, theLen); } + void SetIsClosed(bool theIsClosed) { _func->SetInteger(SPL_ARG_CLOS, (int)theIsClosed); } + void SetDoReordering(bool theDoReordering) { _func->SetInteger(SPL_ARG_REOR, (int)theDoReordering); } + void SetConstructorType(int theConstructor) {_func->SetInteger(SPL_CONSTRUCTOR,theConstructor); } + void SetPoint(int theId, Handle(GEOM_Function) theP) { _func->SetReference(SPL_ARG_LAST + theId, theP); } void SetCoordinates(const Handle(TColStd_HArray1OfReal)& theValue) { _func->SetRealArray(SPL_ARG_ARRAY, theValue); } - + int GetLength() { return _func->GetInteger(SPL_ARG_LENG); } + bool GetIsClosed() { return (bool)_func->GetInteger(SPL_ARG_CLOS); } + bool GetDoReordering() { return (bool)_func->GetInteger(SPL_ARG_REOR); } + int GetConstructorType() { return _func->GetInteger(SPL_CONSTRUCTOR); } + Handle(GEOM_Function) GetPoint(int theId) { return _func->GetReference(SPL_ARG_LAST + theId); } Handle(TColStd_HArray1OfReal) GetCoordinates() { return _func->GetRealArray(SPL_ARG_ARRAY); } + */ private: diff --git a/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx b/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx index 07098c561..c296d9c58 100644 --- a/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -143,7 +142,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::TranslateTwoPoints } //Make a Python command - GEOM::TPythonDump(aFunction) << "geompy.TrsfOp.TranslateTwoPoints(" + GEOM::TPythonDump(aFunction) << "geompy.TranslateTwoPoints(" << theObject << ", " << thePoint1 << ", " << thePoint2 << ")"; SetErrorCode(OK); @@ -362,7 +361,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::TranslateVector } //Make a Python command - GEOM::TPythonDump(aFunction) << "geompy.TrsfOp.TranslateVector(" + GEOM::TPythonDump(aFunction) << "geompy.TranslateVector(" << theObject << ", " << theVector << ")"; SetErrorCode(OK); @@ -500,7 +499,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::Translate1D { SetErrorCode(KO); - if (theObject.IsNull() || theVector.IsNull()) return NULL; + if (theObject.IsNull()) return NULL; Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction(); if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved @@ -515,9 +514,10 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::Translate1D //Check if the function is set correctly if (aFunction->GetDriverGUID() != GEOMImpl_TranslateDriver::GetID()) return NULL; - GEOMImpl_ITranslate aTI(aFunction); - aTI.SetVector(theVector->GetLastFunction()); + GEOMImpl_ITranslate aTI (aFunction); aTI.SetOriginal(aLastFunction); + if (!theVector.IsNull()) + aTI.SetVector(theVector->GetLastFunction()); aTI.SetStep1(theStep); aTI.SetNbIter1(theNbTimes); @@ -560,7 +560,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::Translate2D (Handle(GEOM_Obje { SetErrorCode(KO); - if (theObject.IsNull() || theVector.IsNull() || theVector2.IsNull()) return NULL; + if (theObject.IsNull()) return NULL; Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction(); if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved @@ -576,11 +576,13 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::Translate2D (Handle(GEOM_Obje if (aFunction->GetDriverGUID() != GEOMImpl_TranslateDriver::GetID()) return NULL; GEOMImpl_ITranslate aTI (aFunction); - aTI.SetVector(theVector->GetLastFunction()); - aTI.SetVector2(theVector2->GetLastFunction()); aTI.SetOriginal(aLastFunction); + if (!theVector.IsNull()) + aTI.SetVector(theVector->GetLastFunction()); aTI.SetStep1(theStep1); aTI.SetNbIter1(theNbTimes1); + if (!theVector2.IsNull()) + aTI.SetVector2(theVector2->GetLastFunction()); aTI.SetStep2(theStep2); aTI.SetNbIter2(theNbTimes2); @@ -799,7 +801,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::MirrorPlane } //Make a Python command - GEOM::TPythonDump(aFunction) << "geompy.TrsfOp.MirrorPlane(" + GEOM::TPythonDump(aFunction) << "geompy.MirrorByPlane(" << theObject << ", " << thePlane << ")"; SetErrorCode(OK); @@ -906,7 +908,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::MirrorPoint } //Make a Python command - GEOM::TPythonDump(aFunction) << "geompy.TrsfOp.MirrorPoint(" + GEOM::TPythonDump(aFunction) << "geompy.MirrorByPoint(" << theObject << ", " << thePoint << ")"; SetErrorCode(OK); @@ -1013,7 +1015,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::MirrorAxis } //Make a Python command - GEOM::TPythonDump(aFunction) << "geompy.TrsfOp.MirrorAxis(" + GEOM::TPythonDump(aFunction) << "geompy.MirrorByAxis(" << theObject << ", " << theAxis << ")"; SetErrorCode(OK); @@ -1118,7 +1120,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::OffsetShape } //Make a Python command - GEOM::TPythonDump(aFunction) << "geompy.TrsfOp.OffsetShape(" + GEOM::TPythonDump(aFunction) << "geompy.Offset(" << theObject << ", " << theOffset << ")"; SetErrorCode(OK); @@ -1285,7 +1287,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::ScaleShape } //Make a Python command - GEOM::TPythonDump(aFunction) << "geompy.TrsfOp.ScaleShape(" + GEOM::TPythonDump(aFunction) << "geompy.Scale(" << theObject << ", " << thePoint << ", " << theFactor << ")"; SetErrorCode(OK); @@ -1426,7 +1428,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::ScaleShapeAlongAxes (Handle(G return aCopy; } - GEOM::TPythonDump(aFunction) << "geompy.TrsfOp.ScaleShapeAlongAxes(" + GEOM::TPythonDump(aFunction) << "geompy.ScaleAlongAxes(" << theObject << ", " << thePoint << ", " << theFactorX << ", " << theFactorY << ", " << theFactorZ << ")"; return theObject; @@ -1482,7 +1484,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::PositionShape } //Make a Python command - GEOM::TPythonDump(aFunction) << "geompy.TrsfOp.PositionShape(" + GEOM::TPythonDump(aFunction) << "geompy.Position(" << theObject << ", " << theStartLCS << ", " << theEndLCS << ")"; SetErrorCode(OK); @@ -1604,13 +1606,13 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::PositionAlongPath //Make a Python command if (theCopy) { - GEOM::TPythonDump(aFunction) << aCopy << " = geompy.PositionAlongPath(" + GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakePositionAlongPath(" << theObject << ", " << thePath << ", " << theDistance << ", " << theCopy << ", " << theReverse << ")"; SetErrorCode(OK); return aCopy; } - GEOM::TPythonDump(aFunction) << "geompy.TrsfOp.PositionAlongPath(" + GEOM::TPythonDump(aFunction) << "geompy.PositionAlongPath(" << theObject << ", " << thePath << ", " << theDistance << ", " << theCopy << ", " << theReverse << ")"; SetErrorCode(OK); @@ -1675,10 +1677,12 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate (Handle(GEOM_Object) t //============================================================================= /*! - * Rotate + * RotateCopy */ //============================================================================= -Handle(GEOM_Object) GEOMImpl_ITransformOperations::RotateCopy (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theAxis, double theAngle) +Handle(GEOM_Object) GEOMImpl_ITransformOperations::RotateCopy (Handle(GEOM_Object) theObject, + Handle(GEOM_Object) theAxis, + double theAngle) { SetErrorCode(KO); @@ -1728,7 +1732,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::RotateCopy (Handle(GEOM_Objec //============================================================================= /*! - * Rotate1D + * Rotate1D (for MultiRotate1DNbTimes) */ //============================================================================= Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate1D (Handle(GEOM_Object) theObject, @@ -1737,7 +1741,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate1D (Handle(GEOM_Object) { SetErrorCode(KO); - if (theObject.IsNull() || theAxis.IsNull()) return NULL; + if (theObject.IsNull()) return NULL; Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction(); if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be rotated @@ -1754,7 +1758,8 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate1D (Handle(GEOM_Object) GEOMImpl_IRotate aRI(aFunction); aRI.SetOriginal(aLastFunction); - aRI.SetAxis(theAxis->GetLastFunction()); + if (!theAxis.IsNull()) + aRI.SetAxis(theAxis->GetLastFunction()); aRI.SetNbIter1(theNbTimes); //Compute the translation @@ -1774,7 +1779,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate1D (Handle(GEOM_Object) } //Make a Python command - GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MultiRotate1D(" + GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MultiRotate1DNbTimes(" << theObject << ", " << theAxis << ", " << theNbTimes << ")"; SetErrorCode(OK); @@ -1783,22 +1788,148 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate1D (Handle(GEOM_Object) //============================================================================= /*! - * Rotate2D + * Rotate1D (for MultiRotate1DByStep) + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate1D (Handle(GEOM_Object) theObject, + Handle(GEOM_Object) theAxis, + double theAngleStep, + Standard_Integer theNbSteps) +{ + SetErrorCode(KO); + + if (theObject.IsNull()) return NULL; + + Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction(); + if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be rotated + + //Add a new Copy object + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + + //Add a rotate function + aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_1D_STEP); + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL; + + //Convert angle into degrees + double anAngleStep = theAngleStep * 180. / M_PI; + + GEOMImpl_IRotate aRI (aFunction); + aRI.SetOriginal(aLastFunction); + if (!theAxis.IsNull()) + aRI.SetAxis(theAxis->GetLastFunction()); + aRI.SetAngle(anAngleStep); + aRI.SetNbIter1(theNbSteps); + + //Compute the translation + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Rotate driver failed"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return NULL; + } + + //Make a Python command + GEOM::TPythonDump(aFunction) + << aCopy << " = geompy.MultiRotate1DByStep(" << theObject << ", " + << theAxis << ", " << anAngleStep << "*math.pi/180.0, " << theNbSteps << ")"; + + SetErrorCode(OK); + return aCopy; +} + +//============================================================================= +/*! + * Rotate2D (for MultiRotate2DNbTimes) */ //============================================================================= Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate2D (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theAxis, - double theAngle, + Standard_Integer theNbObjects, + double theRadialStep, + Standard_Integer theNbSteps) +{ + SetErrorCode(KO); + + if (theObject.IsNull()) return NULL; + + Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction(); + if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be rotated + + //Add a new Copy object + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + + //Add a rotate function + aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_2D); + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL; + + double anAngle = 360. / (double)theNbObjects; + + GEOMImpl_IRotate aRI (aFunction); + aRI.SetOriginal(aLastFunction); + if (!theAxis.IsNull()) + aRI.SetAxis(theAxis->GetLastFunction()); + aRI.SetAngle(anAngle); + aRI.SetNbIter1(theNbObjects); + aRI.SetStep(theRadialStep); + aRI.SetNbIter2(theNbSteps); + + //Compute the translation + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Rotate driver failed"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return NULL; + } + + //Make a Python command + GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MultiRotate2DNbTimes(" + << theObject << ", " << theAxis << ", " << theNbObjects + << ", " << theRadialStep << ", " << theNbSteps << ")"; + + SetErrorCode(OK); + return aCopy; +} + +//============================================================================= +/*! + * Rotate2D (for MultiRotate2DByStep) + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate2D (Handle(GEOM_Object) theObject, + Handle(GEOM_Object) theAxis, + double theAngleStep, Standard_Integer theNbTimes1, double theStep, Standard_Integer theNbTimes2) { SetErrorCode(KO); - if (theObject.IsNull() || theAxis.IsNull()) return NULL; + if (theObject.IsNull()) return NULL; Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction(); - if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be rotated + if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be rotated //Add a new Copy object Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); @@ -1807,16 +1938,20 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate2D (Handle(GEOM_Object) aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_2D); if (aFunction.IsNull()) return NULL; - //Check if the function is set correctly + //Check if the function is set correctly if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL; - GEOMImpl_IRotate aRI(aFunction); - aRI.SetAxis(theAxis->GetLastFunction()); + //Convert angle into degrees + double anAngleStep = theAngleStep * 180. / M_PI; + + GEOMImpl_IRotate aRI (aFunction); aRI.SetOriginal(aLastFunction); + if (!theAxis.IsNull()) + aRI.SetAxis(theAxis->GetLastFunction()); + aRI.SetAngle(anAngleStep); aRI.SetNbIter1(theNbTimes1); - aRI.SetNbIter2(theNbTimes2); - aRI.SetAngle(theAngle); aRI.SetStep(theStep); + aRI.SetNbIter2(theNbTimes2); //Compute the translation try { @@ -1835,9 +1970,10 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate2D (Handle(GEOM_Object) } //Make a Python command - GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MultiRotate2D(" - << theObject << ", " << theAxis << ", " << theAngle << ", " - << theNbTimes1 << ", " << theStep << ", " << theNbTimes2 << ")"; + GEOM::TPythonDump(aFunction) + << aCopy << " = geompy.MultiRotate2DByStep(" << theObject << ", " + << theAxis << ", " << anAngleStep << "*math.pi/180.0, " + << theNbTimes1 << ", " << theStep << ", " << theNbTimes2 << ")"; SetErrorCode(OK); return aCopy; @@ -1858,7 +1994,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::RotateThreePoints (Handle(GEO if (theObject.IsNull() || theCentPoint.IsNull() || thePoint1.IsNull() || thePoint2.IsNull()) return NULL; Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction(); - if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be rotated + if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be rotated // Get last functions of the arguments Handle(GEOM_Function) aCPF = theCentPoint->GetLastFunction(); @@ -1897,7 +2033,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::RotateThreePoints (Handle(GEO } //Make a Python command - GEOM::TPythonDump(aFunction) << "geompy.TrsfOp.RotateThreePoints(" << theObject + GEOM::TPythonDump(aFunction) << "geompy.RotateThreePoints(" << theObject << ", " << theCentPoint << ", "< #include #include #include + #include -#include + +#include #include #include @@ -109,7 +110,7 @@ Standard_Integer GEOMImpl_MarkerDriver::Execute(TFunction_Logbook& log) const } else if (aType == MARKER_SHAPE) { Handle(GEOM_Function) aRefShape = aPI.GetShape(); TopoDS_Shape aSh = aRefShape->GetValue(); - gp_Ax3 anAx3 = GEOMImpl_IMeasureOperations::GetPosition(aSh); + gp_Ax3 anAx3 = GEOMUtils::GetPosition(aSh); gp_Pln aPln (anAx3); double aTrimSize = 100.0; diff --git a/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx b/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx index 5e014b4eb..33ead5986 100644 --- a/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx @@ -18,20 +18,24 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include #include #include -#include #include + #include +#include + #include +#include #include -#include +#include #include +#include +#include #include #include @@ -54,6 +58,7 @@ #include #include #include +#include //======================================================================= //function : GetID @@ -92,14 +97,47 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const { Handle(GEOM_Function) aRefBase = aCI.GetBase(); TopoDS_Shape aShapeBase = aRefBase->GetValue(); - if (aShapeBase.IsNull()) { + if (aShapeBase.IsNull()) Standard_NullObject::Raise("Shape for centre of mass calculation is null"); - } - gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(aShapeBase); + gp_Ax3 aPos = GEOMUtils::GetPosition(aShapeBase); gp_Pnt aCenterMass = aPos.Location(); aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape(); } + else if (aType == BND_BOX_MEASURE) + { + Handle(GEOM_Function) aRefBase = aCI.GetBase(); + TopoDS_Shape aShapeBase = aRefBase->GetValue(); + if (aShapeBase.IsNull()) + Standard_NullObject::Raise("Shape for bounding box calculation is null"); + + BRepBuilderAPI_Copy aCopyTool (aShapeBase); + if (!aCopyTool.IsDone()) + Standard_NullObject::Raise("Shape for bounding box calculation is bad"); + + aShapeBase = aCopyTool.Shape(); + + // remove triangulation to obtain more exact boundaries + BRepTools::Clean(aShapeBase); + + Bnd_Box B; + BRepBndLib::Add(aShapeBase, B); + + Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax; + B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); + + if (Xmax - Xmin < Precision::Confusion()) Xmax += Precision::Confusion(); + if (Ymax - Ymin < Precision::Confusion()) Ymax += Precision::Confusion(); + if (Zmax - Zmin < Precision::Confusion()) Zmax += Precision::Confusion(); + + gp_Pnt P1 (Xmin, Ymin, Zmin); + gp_Pnt P2 (Xmax, Ymax, Zmax); + + BRepPrimAPI_MakeBox MB (P1, P2); + MB.Build(); + if (!MB.IsDone()) StdFail_NotDone::Raise("Bounding box cannot be computed from the given shape"); + aShape = MB.Shape(); + } else if (aType == VERTEX_BY_INDEX) { Handle(GEOM_Function) aRefBase = aCI.GetBase(); @@ -189,7 +227,7 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const } else { - gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(aFace); + gp_Ax3 aPos = GEOMUtils::GetPosition(aFace); p1 = aPos.Location(); } diff --git a/src/GEOMImpl/GEOMImpl_PipeDriver.cxx b/src/GEOMImpl/GEOMImpl_PipeDriver.cxx index 400c2a03c..9812da16a 100644 --- a/src/GEOMImpl/GEOMImpl_PipeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PipeDriver.cxx @@ -19,11 +19,8 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -#include - #include -#include #include #include #include @@ -31,8 +28,11 @@ #include #include #include + #include +#include + #include #include #include @@ -97,6 +97,13 @@ #include "utilities.h" +////////////////////////////////////////////////////////////////////////// +// Uncomment below macro to perform gluing in the end of MakePipe operation +// as fix of issue 0020207. +////////////////////////////////////////////////////////////////////////// +//#define GLUE_0020207 + + //======================================================================= //function : GetID //purpose : @@ -2477,6 +2484,8 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const } // Glue (for bug 0020207) + // No gluing is needed as the bug 0020207 is fixed in OCCT. +#ifdef GLUE_0020207 TopExp_Explorer anExpV (aShape, TopAbs_VERTEX); if (anExpV.More()) { Standard_Real aVertMaxTol = -RealLast(); @@ -2490,8 +2499,9 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, aVertMaxTol, Standard_True); //aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, Precision::Confusion(), Standard_True); } +#endif - TopoDS_Shape aRes = GEOMImpl_IShapesOperations::CompsolidToCompound(aShape); + TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape); aFunction->SetValue(aRes); log.SetTouched(Label()); diff --git a/src/GEOMImpl/GEOMImpl_PipeTShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_PipeTShapeDriver.cxx index 025042282..f28ff1f27 100644 --- a/src/GEOMImpl/GEOMImpl_PipeTShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PipeTShapeDriver.cxx @@ -15,20 +15,20 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include #include + #include #include - #include + #include +#include + +#include -#include -#include "GEOMAlgo_FinderShapeOn1.hxx" -#include "GEOMAlgo_FinderShapeOn2.hxx" +#include +#include #include #include @@ -106,7 +106,7 @@ GEOMImpl_PipeTShapeDriver::GetShapesOnBoxIDs(const TopoDS_Shape& aBox, Handle(TColStd_HSequenceOfInteger) aSeqOfIDs; // Check presence of triangulation, build if need - if (!GEOMImpl_IShapesOperations::CheckTriangulation(aShape)) { + if (!GEOMUtils::CheckTriangulation(aShape)) { StdFail_NotDone::Raise("Cannot build triangulation on the shape"); return aSeqOfIDs; } @@ -179,7 +179,7 @@ Handle(TColStd_HSequenceOfInteger) Handle(TColStd_HSequenceOfInteger) aSeqOfIDs; // Check presence of triangulation, build if need - if (!GEOMImpl_IShapesOperations::CheckTriangulation(theShape)) { + if (!GEOMUtils::CheckTriangulation(theShape)) { StdFail_NotDone::Raise("Cannot build triangulation on the shape"); return aSeqOfIDs; } diff --git a/src/GEOMImpl/GEOMImpl_PlaneDriver.cxx b/src/GEOMImpl/GEOMImpl_PlaneDriver.cxx index e1968567b..8fc83e24e 100644 --- a/src/GEOMImpl/GEOMImpl_PlaneDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PlaneDriver.cxx @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -27,7 +26,7 @@ #include #include -#include +#include #include @@ -142,7 +141,7 @@ Standard_Integer GEOMImpl_PlaneDriver::Execute(TFunction_Logbook& log) const // Standard_TypeMismatch::Raise("Plane creation aborted: non-planar face given as argument"); //} //aShape = BRepBuilderAPI_MakeFace(aGS, -aSize, +aSize, -aSize, +aSize).Shape(); - gp_Ax3 anAx3 = GEOMImpl_IMeasureOperations::GetPosition(aRefShape); + gp_Ax3 anAx3 = GEOMUtils::GetPosition(aRefShape); gp_Pln aPln (anAx3); aShape = BRepBuilderAPI_MakeFace(aPln, -aSize, +aSize, -aSize, +aSize).Shape(); } @@ -223,7 +222,7 @@ Standard_Integer GEOMImpl_PlaneDriver::Execute(TFunction_Logbook& log) const TopoDS_Shape aRefShape = aRef->GetValue(); if (aRefShape.ShapeType() != TopAbs_FACE) return 0; - anAx3 = GEOMImpl_IMeasureOperations::GetPosition(aRefShape); + anAx3 = GEOMUtils::GetPosition(aRefShape); } if ( anOrientation == 2) diff --git a/src/GEOMImpl/GEOMImpl_PointDriver.cxx b/src/GEOMImpl/GEOMImpl_PointDriver.cxx index 9fa9cf9c0..832fdc15c 100644 --- a/src/GEOMImpl/GEOMImpl_PointDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PointDriver.cxx @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -142,8 +143,27 @@ Standard_Integer GEOMImpl_PointDriver::Execute(TFunction_Logbook& log) const } Standard_Real aFP, aLP, aP; Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aRefShape), aFP, aLP); - aP = aFP + (aLP - aFP) * aPI.GetParameter(); - aPnt = aCurve->Value(aP); + if ( !aCurve.IsNull() ) { + aP = aFP + (aLP - aFP) * aPI.GetParameter(); + aPnt = aCurve->Value(aP); + } + else { + // null curve, e.g. degenerated edge + TopoDS_Iterator It(aRefShape, Standard_False, Standard_False); + TopoDS_Vertex aVertex; + if ( It.More() ) { + TopoDS_Shape aShape = It.Value(); + if ( !aShape.IsNull() ) + aVertex = TopoDS::Vertex( aShape ); + } + if ( !aVertex.IsNull() ) { + aPnt = BRep_Tool::Pnt( aVertex ); + } + else { + Standard_TypeMismatch::Raise + ("Point On Curve creation aborted : null curve"); + } + } } else if (aType == POINT_CURVE_COORD) { Handle(GEOM_Function) aRefFunc = aPI.GetCurve(); @@ -201,25 +221,45 @@ Standard_Integer GEOMImpl_PointDriver::Execute(TFunction_Logbook& log) const // Check orientation Standard_Real UFirst, ULast; Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(aRefEdge, UFirst, ULast); - Handle(Geom_Curve) ReOrientedCurve = EdgeCurve; - - Standard_Real dU = ULast - UFirst; - Standard_Real par1 = UFirst + 0.1 * dU; - Standard_Real par2 = ULast - 0.1 * dU; - - gp_Pnt P1 = EdgeCurve->Value(par1); - gp_Pnt P2 = EdgeCurve->Value(par2); - if (aRefPnt.SquareDistance(P2) < aRefPnt.SquareDistance(P1)) { - ReOrientedCurve = EdgeCurve->Reversed(); - UFirst = EdgeCurve->ReversedParameter(ULast); + if ( !EdgeCurve.IsNull() ) { + Handle(Geom_Curve) ReOrientedCurve = EdgeCurve; + + Standard_Real dU = ULast - UFirst; + Standard_Real par1 = UFirst + 0.1 * dU; + Standard_Real par2 = ULast - 0.1 * dU; + + gp_Pnt P1 = EdgeCurve->Value(par1); + gp_Pnt P2 = EdgeCurve->Value(par2); + + if (aRefPnt.SquareDistance(P2) < aRefPnt.SquareDistance(P1)) { + ReOrientedCurve = EdgeCurve->Reversed(); + UFirst = EdgeCurve->ReversedParameter(ULast); + } + + // Get the point by length + GeomAdaptor_Curve AdapCurve = GeomAdaptor_Curve(ReOrientedCurve); + GCPnts_AbscissaPoint anAbsPnt (AdapCurve, aLength, UFirst); + Standard_Real aParam = anAbsPnt.Parameter(); + aPnt = AdapCurve.Value(aParam); + } + else { + // null curve, e.g. degenerated edge + TopoDS_Iterator It(aRefEdge, Standard_False, Standard_False); + TopoDS_Vertex aVertex; + if ( It.More() ) { + TopoDS_Shape aShape = It.Value(); + if ( !aShape.IsNull() ) + aVertex = TopoDS::Vertex( aShape ); + } + if ( !aVertex.IsNull() ) { + aPnt = BRep_Tool::Pnt( aVertex ); + } + else { + Standard_TypeMismatch::Raise + ("Point On Curve creation aborted : null curve"); + } } - - // Get the point by length - GeomAdaptor_Curve AdapCurve = GeomAdaptor_Curve(ReOrientedCurve); - GCPnts_AbscissaPoint anAbsPnt (AdapCurve, aLength, UFirst); - Standard_Real aParam = anAbsPnt.Parameter(); - aPnt = AdapCurve.Value(aParam); } else if (aType == POINT_SURFACE_PAR) { Handle(GEOM_Function) aRefFunc = aPI.GetSurface(); diff --git a/src/GEOMImpl/GEOMImpl_PositionDriver.cxx b/src/GEOMImpl/GEOMImpl_PositionDriver.cxx index be11e7dbb..73aed0fa2 100644 --- a/src/GEOMImpl/GEOMImpl_PositionDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PositionDriver.cxx @@ -18,16 +18,15 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -//#include -// #include + #include #include + #include -#include +#include // OCCT Includes #include @@ -117,10 +116,10 @@ Standard_Integer GEOMImpl_PositionDriver::Execute(TFunction_Logbook& log) const gp_Ax3 aStartAx3, aDestAx3; // End LCS - aDestAx3 = GEOMImpl_IMeasureOperations::GetPosition(aShapeEndLCS); + aDestAx3 = GEOMUtils::GetPosition(aShapeEndLCS); // Start LCS - aStartAx3 = GEOMImpl_IMeasureOperations::GetPosition(aShapeStartLCS); + aStartAx3 = GEOMUtils::GetPosition(aShapeStartLCS); // Set transformation aTrsf.SetDisplacement(aStartAx3, aDestAx3); @@ -145,7 +144,7 @@ Standard_Integer GEOMImpl_PositionDriver::Execute(TFunction_Logbook& log) const gp_Ax3 aStartAx3, aDestAx3; // End LCS - aDestAx3 = GEOMImpl_IMeasureOperations::GetPosition(aShapeEndLCS); + aDestAx3 = GEOMUtils::GetPosition(aShapeEndLCS); // Set transformation aTrsf.SetDisplacement(aStartAx3, aDestAx3); diff --git a/src/GEOMImpl/GEOMImpl_PrismDriver.cxx b/src/GEOMImpl/GEOMImpl_PrismDriver.cxx index 87b18275d..ae25ae0b8 100644 --- a/src/GEOMImpl/GEOMImpl_PrismDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PrismDriver.cxx @@ -18,17 +18,18 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include #include -#include -#include #include #include #include + #include +#include + +#include #include #include @@ -249,7 +250,7 @@ Standard_Integer GEOMImpl_PrismDriver::Execute(TFunction_Logbook& log) const } else { - TopoDS_Shape aRes = GEOMImpl_IShapesOperations::CompsolidToCompound(aShape); + TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape); aFunction->SetValue(aRes); } @@ -275,7 +276,7 @@ TopoDS_Shape GEOMImpl_PrismDriver::MakeScaledPrism (const TopoDS_Shape& theShape // 1. aCDG = geompy.MakeCDG(theBase) gp_Pnt aCDG = theCDG; if (!isCDG) { - gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(theShapeBase); + gp_Ax3 aPos = GEOMUtils::GetPosition(theShapeBase); aCDG = aPos.Location(); } TopoDS_Shape aShapeCDG_1 = BRepBuilderAPI_MakeVertex(aCDG).Shape(); diff --git a/src/GEOMImpl/GEOMImpl_RevolutionDriver.cxx b/src/GEOMImpl/GEOMImpl_RevolutionDriver.cxx index ea72dd7c3..44e68d973 100644 --- a/src/GEOMImpl/GEOMImpl_RevolutionDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_RevolutionDriver.cxx @@ -18,17 +18,18 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include #include -#include #include #include + #include +#include + #include #include #include @@ -128,7 +129,7 @@ Standard_Integer GEOMImpl_RevolutionDriver::Execute(TFunction_Logbook& log) cons if (aShape.IsNull()) return 0; - TopoDS_Shape aRes = GEOMImpl_IShapesOperations::CompsolidToCompound(aShape); + TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape); aFunction->SetValue(aRes); log.SetTouched(Label()); diff --git a/src/GEOMImpl/GEOMImpl_RotateDriver.cxx b/src/GEOMImpl/GEOMImpl_RotateDriver.cxx index 9f1e3035b..036538018 100644 --- a/src/GEOMImpl/GEOMImpl_RotateDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_RotateDriver.cxx @@ -18,36 +18,42 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include #include #include #include + #include -#include -#include -#include -#include -#include + +#include + #include -#include -#include -#include -#include +#include +#include +#include + #include #include +#include +#include #include +#include #include -#include -#include + #include #include #include -#include + #include +#include +#include +#include +#include +#include + //======================================================================= //function : GetID //purpose : @@ -92,13 +98,12 @@ Standard_Integer GEOMImpl_RotateDriver::Execute(TFunction_Logbook& log) const Handle(GEOM_Function) anAxis = RI.GetAxis(); if (anAxis.IsNull()) return 0; TopoDS_Shape A = anAxis->GetValue(); - if (A.IsNull() || A.ShapeType() != TopAbs_EDGE) return 0; + gp_Vec aV = GEOMUtils::GetVector(A); TopoDS_Edge anEdge = TopoDS::Edge(A); - gp_Pnt aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge)); - gp_Pnt aP2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge)); - gp_Dir aDir(gp_Vec(aP1, aP2)); - gp_Ax1 anAx1(aP1, aDir); + gp_Dir aDir (aV); + gp_Ax1 anAx1 (aP1, aDir); + Standard_Real anAngle = RI.GetAngle(); if (fabs(anAngle) < Precision::Angular()) anAngle += 2.*M_PI; // NPAL19665,19769 aTrsf.SetRotation(anAx1, anAngle); @@ -148,22 +153,24 @@ Standard_Integer GEOMImpl_RotateDriver::Execute(TFunction_Logbook& log) const TopLoc_Location aLocRes (aTrsfOrig); aShape = anOriginal.Located(aLocRes); } - else if (aType == ROTATE_1D) { + else if (aType == ROTATE_1D || aType == ROTATE_1D_STEP) { //Get direction + gp_Pnt aP1 = gp::Origin(); + gp_Dir D = gp::DZ(); Handle(GEOM_Function) anAxis = RI.GetAxis(); - if(anAxis.IsNull()) return 0; - TopoDS_Shape A = anAxis->GetValue(); - if(A.IsNull() || A.ShapeType() != TopAbs_EDGE) return 0; - TopoDS_Edge anEdge = TopoDS::Edge(A); - - gp_Pnt aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge)); - gp_Pnt aP2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge)); - gp_Dir D(gp_Vec(aP1, aP2)); - - gp_Ax1 AX1(aP1, D); + if (!anAxis.IsNull()) { + TopoDS_Shape A = anAxis->GetValue(); + gp_Vec aV = GEOMUtils::GetVector(A); + TopoDS_Edge anEdge = TopoDS::Edge(A); + aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge)); + D = gp_Dir(aV); + } + gp_Ax1 AX1 (aP1, D); Standard_Integer nbtimes = RI.GetNbIter1(); - Standard_Real angle = 360.0/nbtimes; + Standard_Real angle = 360. / nbtimes; + if (aType == ROTATE_1D_STEP) + angle = RI.GetAngle(); TopoDS_Compound aCompound; BRep_Builder B; @@ -177,7 +184,7 @@ Standard_Integer GEOMImpl_RotateDriver::Execute(TFunction_Logbook& log) const B.Add(aCompound, anOriginal); } else { - aTrsf.SetRotation(AX1, i*angle*M_PI/180.); + aTrsf.SetRotation(AX1, i * angle * M_PI / 180.); //TopLoc_Location aLocRes (aTrsf * aTrsfOrig); // gp_Trsf::Multiply() has a bug gp_Trsf aTrsfNew (aTrsfOrig); aTrsfNew.PreMultiply(aTrsf); @@ -194,16 +201,17 @@ Standard_Integer GEOMImpl_RotateDriver::Execute(TFunction_Logbook& log) const } else if (aType == ROTATE_2D) { //Get direction + gp_Pnt aP1 = gp::Origin(); + gp_Dir D = gp::DZ(); Handle(GEOM_Function) anAxis = RI.GetAxis(); - if(anAxis.IsNull()) return 0; - TopoDS_Shape A = anAxis->GetValue(); - if(A.IsNull() || A.ShapeType() != TopAbs_EDGE) return 0; - TopoDS_Edge anEdge = TopoDS::Edge(A); - gp_Pnt aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge)); - gp_Pnt aP2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge)); - gp_Dir D(gp_Vec(aP1, aP2)); - - gp_Ax1 AX1(aP1, D); + if (!anAxis.IsNull()) { + TopoDS_Shape A = anAxis->GetValue(); + gp_Vec aV = GEOMUtils::GetVector(A); + TopoDS_Edge anEdge = TopoDS::Edge(A); + aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge)); + D = gp_Dir(aV); + } + gp_Ax1 AX1 (aP1, D); gp_Trsf aTrsf1; gp_Trsf aTrsf2; @@ -274,7 +282,7 @@ Standard_Integer GEOMImpl_RotateDriver::Execute(TFunction_Logbook& log) const B.Add(aCompound, anOriginal.Located(aLocRes)); } else { - aTrsf2.SetRotation(AX1, j*ang*M_PI/180.); + aTrsf2.SetRotation(AX1, j * ang * M_PI / 180.); //TopLoc_Location aLocRes (aTrsf2 * aTrsf1 * aTrsfOrig); // gp_Trsf::Multiply() has a bug gp_Trsf aTrsfNew (aTrsfOrig); aTrsfNew.PreMultiply(aTrsf1); diff --git a/src/GEOMImpl/GEOMImpl_SketcherDriver.cxx b/src/GEOMImpl/GEOMImpl_SketcherDriver.cxx index 70e627719..0ebe757d0 100644 --- a/src/GEOMImpl/GEOMImpl_SketcherDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_SketcherDriver.cxx @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -27,7 +26,7 @@ #include #include -#include +#include #include @@ -117,7 +116,7 @@ Standard_Integer GEOMImpl_SketcherDriver::Execute(TFunction_Logbook& log) const // return 0; //Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast( aGS ); //aWPlane = aGPlane->Pln().Position(); - aWPlane = GEOMImpl_IMeasureOperations::GetPosition(aShape); + aWPlane = GEOMUtils::GetPosition(aShape); } gp_Trsf aTrans; aTrans.SetTransformation(aWPlane); diff --git a/src/GEOMImpl/GEOMImpl_SplineDriver.cxx b/src/GEOMImpl/GEOMImpl_SplineDriver.cxx index c87cdbc09..a94f0a279 100644 --- a/src/GEOMImpl/GEOMImpl_SplineDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_SplineDriver.cxx @@ -18,14 +18,14 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include #include + #include #include + #include +#include #include #include @@ -49,6 +49,10 @@ #include #include +#include + +#include + //======================================================================= //function : GetID //purpose : @@ -82,54 +86,73 @@ Standard_Integer GEOMImpl_SplineDriver::Execute(TFunction_Logbook& log) const TopoDS_Shape aShape; - if (aType == SPLINE_BEZIER || aType == SPLINE_INTERPOLATION) { + if (aType == SPLINE_BEZIER || + aType == SPLINE_INTERPOLATION || + aType == SPLINE_INTERPOL_TANGENTS) { bool useCoords = aCI.GetConstructorType() == COORD_CONSTRUCTOR; - TColgp_Array1OfPnt points(1, (useCoords ? aCI.GetLength() : 1) ); - if(useCoords) { - Handle(TColStd_HArray1OfReal) aCoordsArray = aCI.GetCoordinates(); + + Handle(TColStd_HArray1OfReal) aCoordsArray; // parametric case + Handle(TColStd_HSequenceOfTransient) aPoints; // points case + + int aLen = 0; + if (useCoords) { + aCoordsArray = aCI.GetCoordinates(); + aLen = aCoordsArray->Length() / 3; + } + else { + aPoints = aCI.GetPoints(); + aLen = aPoints->Length(); + } + + if (aLen < 2) return 0; + + TColgp_Array1OfPnt points (1, (useCoords ? aLen : 1)); + if (useCoords) { int anArrayLength = aCoordsArray->Length(); for (int i = 0, j = 1; i <= (anArrayLength-3); i += 3) { gp_Pnt aPnt = gp_Pnt(aCoordsArray->Value(i+1), aCoordsArray->Value(i+2), aCoordsArray->Value(i+3)); - points.SetValue(j,aPnt); + points.SetValue(j, aPnt); j++; - } + } } - - int ind, aLen = aCI.GetLength(); - if (aLen < 2) return 0; - Standard_Boolean isSeveral = Standard_False; - gp_Pnt aPrevP; int aRealLen = aLen; + if (aType == SPLINE_BEZIER && aCI.GetIsClosed()) { TopoDS_Vertex aV1; - if(useCoords) { + if (useCoords) { aV1 = BRepBuilderAPI_MakeVertex(points.Value(1)); - } else { - Handle(GEOM_Function) aFPoint = aCI.GetPoint(1); + } + else { + Handle(GEOM_Function) aFPoint = Handle(GEOM_Function)::DownCast(aPoints->Value(1)); TopoDS_Shape aFirstPnt = aFPoint->GetValue(); aV1 = TopoDS::Vertex(aFirstPnt); } TopoDS_Vertex aV2; - if(useCoords) { + if (useCoords) { aV2 = BRepBuilderAPI_MakeVertex(points.Value(aLen)); - } else { - Handle(GEOM_Function) aLPoint = aCI.GetPoint(aLen); + } + else { + Handle(GEOM_Function) aLPoint = Handle(GEOM_Function)::DownCast(aPoints->Value(aLen)); TopoDS_Shape aLastPnt = aLPoint->GetValue(); aV2 = TopoDS::Vertex(aLastPnt); } - + if (!aV1.IsNull() && !aV2.IsNull() && !aV1.IsSame(aV2)) { aRealLen++; } } - + + int ind; + Standard_Boolean isSeveral = Standard_False; + gp_Pnt aPrevP; + TColgp_Array1OfPnt CurvePoints (1, aRealLen); for (ind = 1; ind <= aLen; ind++) { gp_Pnt aP; - if( useCoords ) { + if (useCoords) { aP = points.Value(ind); if (!isSeveral && ind > 1) { if (aP.Distance(aPrevP) > Precision::Confusion()) { @@ -138,8 +161,9 @@ Standard_Integer GEOMImpl_SplineDriver::Execute(TFunction_Logbook& log) const } CurvePoints.SetValue(ind, aP); aPrevP = aP; - } else { - Handle(GEOM_Function) aRefPoint = aCI.GetPoint(ind); + } + else { + Handle(GEOM_Function) aRefPoint = Handle(GEOM_Function)::DownCast(aPoints->Value(ind)); TopoDS_Shape aShapePnt = aRefPoint->GetValue(); if (aShapePnt.ShapeType() == TopAbs_VERTEX) { aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt)); @@ -153,6 +177,7 @@ Standard_Integer GEOMImpl_SplineDriver::Execute(TFunction_Logbook& log) const } } } + if (aType == SPLINE_BEZIER) { if (!isSeveral) { Standard_ConstructionError::Raise("Points for Bezier Curve are too close"); @@ -160,13 +185,12 @@ Standard_Integer GEOMImpl_SplineDriver::Execute(TFunction_Logbook& log) const if (aRealLen > aLen) { // set last point equal to first for the closed curve CurvePoints.SetValue(aRealLen, CurvePoints.Value(1)); } - Handle(Geom_BezierCurve) GBC = new Geom_BezierCurve(CurvePoints); + Handle(Geom_BezierCurve) GBC = new Geom_BezierCurve (CurvePoints); aShape = BRepBuilderAPI_MakeEdge(GBC).Edge(); - } else { + } + else { //GeomAPI_PointsToBSpline GBC (CurvePoints); //aShape = BRepBuilderAPI_MakeEdge(GBC).Edge(); - - Handle(TColgp_HArray1OfPnt) aHCurvePoints = new TColgp_HArray1OfPnt(1, aLen); if (aCI.GetDoReordering()) { for (int curInd = 1; curInd < aLen - 1; curInd++) { @@ -194,18 +218,35 @@ Standard_Integer GEOMImpl_SplineDriver::Execute(TFunction_Logbook& log) const CurvePoints.SetValue(curInd + 1, nearPnt); } } - for (ind = 1; ind <= aLen; ind++) { - aHCurvePoints->SetValue(ind, CurvePoints.Value(ind)); - } } - else { - for (ind = 1; ind <= aLen; ind++) { - aHCurvePoints->SetValue(ind, CurvePoints.Value(ind)); - } + + Handle(TColgp_HArray1OfPnt) aHCurvePoints = new TColgp_HArray1OfPnt (1, aLen); + for (ind = 1; ind <= aLen; ind++) { + aHCurvePoints->SetValue(ind, CurvePoints.Value(ind)); } - - bool isClosed = aCI.GetIsClosed(); + + bool isClosed = Standard_False; + if (aType == SPLINE_INTERPOLATION) + isClosed = aCI.GetIsClosed(); + GeomAPI_Interpolate GBC (aHCurvePoints, isClosed, gp::Resolution()); + + if (aType == SPLINE_INTERPOL_TANGENTS) { + Handle(GEOM_Function) aVec1Ref = aCI.GetFirstVector(); + Handle(GEOM_Function) aVec2Ref = aCI.GetLastVector(); + + if (aVec1Ref.IsNull() || aVec2Ref.IsNull()) + Standard_NullObject::Raise("Null object is given for a vector"); + + TopoDS_Shape aVec1Sh = aVec1Ref->GetValue(); + TopoDS_Shape aVec2Sh = aVec2Ref->GetValue(); + + gp_Vec aV1 = GEOMUtils::GetVector(aVec1Sh); + gp_Vec aV2 = GEOMUtils::GetVector(aVec2Sh); + + GBC.Load(aV1, aV2, /*Scale*/Standard_True); + } + GBC.Perform(); if (GBC.IsDone()) aShape = BRepBuilderAPI_MakeEdge(GBC.Curve()).Edge(); @@ -215,13 +256,13 @@ Standard_Integer GEOMImpl_SplineDriver::Execute(TFunction_Logbook& log) const } else { } - + if (aShape.IsNull()) return 0; - + aFunction->SetValue(aShape); - + log.SetTouched(Label()); - + return 1; } diff --git a/src/GEOMImpl/GEOMImpl_TranslateDriver.cxx b/src/GEOMImpl/GEOMImpl_TranslateDriver.cxx index 575cbaea9..1f6de2170 100644 --- a/src/GEOMImpl/GEOMImpl_TranslateDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_TranslateDriver.cxx @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -173,13 +172,14 @@ Standard_Integer GEOMImpl_TranslateDriver::Execute(TFunction_Logbook& log) const B.MakeCompound( aCompound ); Handle(GEOM_Function) aVector = TI.GetVector(); - if(aVector.IsNull()) return 0; - TopoDS_Shape aV = aVector->GetValue(); - if(aV.IsNull() || aV.ShapeType() != TopAbs_EDGE) return 0; - TopoDS_Edge anEdge = TopoDS::Edge(aV); - - gp_Vec Vec(BRep_Tool::Pnt(TopExp::FirstVertex(anEdge)), BRep_Tool::Pnt(TopExp::LastVertex(anEdge))); - Vec.Normalize(); + gp_Vec Vec = gp::DX(); + if (!aVector.IsNull()) { + TopoDS_Shape aV = aVector->GetValue(); + if (aV.IsNull() || aV.ShapeType() != TopAbs_EDGE) return 0; + TopoDS_Edge anEdge = TopoDS::Edge(aV); + Vec = gp_Vec(BRep_Tool::Pnt(TopExp::FirstVertex(anEdge)), BRep_Tool::Pnt(TopExp::LastVertex(anEdge))); + Vec.Normalize(); + } TopLoc_Location aLocOrig = anOriginal.Location(); gp_Trsf aTrsfOrig = aLocOrig.Transformation(); @@ -202,32 +202,36 @@ Standard_Integer GEOMImpl_TranslateDriver::Execute(TFunction_Logbook& log) const } else if (aType == TRANSLATE_2D) { Standard_Integer nbtimes1 = TI.GetNbIter1(), nbtimes2 = TI.GetNbIter2(); - Standard_Real DX, DY, DZ, step1 = TI.GetStep1(), step2 = TI.GetStep2(); - gp_Vec aVec; + Standard_Real DX, DY, DZ, step1 = TI.GetStep1(), step2 = TI.GetStep2(); Handle(GEOM_Function) aVector = TI.GetVector(); - if(aVector.IsNull()) return 0; - TopoDS_Shape aV = aVector->GetValue(); - if(aV.IsNull() || aV.ShapeType() != TopAbs_EDGE) return 0; - TopoDS_Edge anEdge = TopoDS::Edge(aV); + Handle(GEOM_Function) aVector2 = TI.GetVector2(); - gp_Vec Vec1(BRep_Tool::Pnt(TopExp::FirstVertex(anEdge)), BRep_Tool::Pnt(TopExp::LastVertex(anEdge))); - Vec1.Normalize(); + gp_Vec Vec1 = gp::DX(); + gp_Vec Vec2 = gp::DY(); - Handle(GEOM_Function) aVector2 = TI.GetVector2(); - if(aVector2.IsNull()) return 0; - aV = aVector2->GetValue(); - if(aV.IsNull() || aV.ShapeType() != TopAbs_EDGE) return 0; - anEdge = TopoDS::Edge(aV); + if (!aVector.IsNull()) { + TopoDS_Shape aV = aVector->GetValue(); + if (aV.IsNull() || aV.ShapeType() != TopAbs_EDGE) return 0; + TopoDS_Edge anEdge = TopoDS::Edge(aV); + Vec1 = gp_Vec(BRep_Tool::Pnt(TopExp::FirstVertex(anEdge)), BRep_Tool::Pnt(TopExp::LastVertex(anEdge))); + Vec1.Normalize(); + } - gp_Vec Vec2(BRep_Tool::Pnt(TopExp::FirstVertex(anEdge)), BRep_Tool::Pnt(TopExp::LastVertex(anEdge))); - Vec2.Normalize(); + if (!aVector2.IsNull()) { + TopoDS_Shape aV = aVector2->GetValue(); + if (aV.IsNull() || aV.ShapeType() != TopAbs_EDGE) return 0; + TopoDS_Edge anEdge = TopoDS::Edge(aV); + Vec2 = gp_Vec(BRep_Tool::Pnt(TopExp::FirstVertex(anEdge)), BRep_Tool::Pnt(TopExp::LastVertex(anEdge))); + Vec2.Normalize(); + } TopoDS_Compound aCompound; BRep_Builder B; - B.MakeCompound( aCompound ); + B.MakeCompound(aCompound); TopLoc_Location aLocOrig = anOriginal.Location(); gp_Trsf aTrsfOrig = aLocOrig.Transformation(); + gp_Vec aVec; for (int i = 0; i < nbtimes1; i++) { for (int j = 0; j < nbtimes2; j++) { diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx index 4aeed6398..0419dd169 100755 --- a/src/GEOMImpl/GEOMImpl_Types.hxx +++ b/src/GEOMImpl/GEOMImpl_Types.hxx @@ -153,6 +153,7 @@ #define ROTATE_2D 4 #define ROTATE_THREE_POINTS 5 #define ROTATE_THREE_POINTS_COPY 6 +#define ROTATE_1D_STEP 7 #define MIRROR_PLANE 1 #define MIRROR_PLANE_COPY 2 @@ -234,8 +235,9 @@ #define POLYLINE_POINTS 1 -#define SPLINE_BEZIER 1 -#define SPLINE_INTERPOLATION 2 +#define SPLINE_BEZIER 1 +#define SPLINE_INTERPOLATION 2 +#define SPLINE_INTERPOL_TANGENTS 3 #define CIRCLE_THREE_PNT 1 #define CIRCLE_PNT_VEC_R 2 @@ -308,6 +310,7 @@ // Measures #define CDG_MEASURE 1 +#define BND_BOX_MEASURE 2 #define VECTOR_FACE_NORMALE 4 #define VERTEX_BY_INDEX 5 diff --git a/src/GEOMImpl/Makefile.am b/src/GEOMImpl/Makefile.am index 8ce12ca2e..f456551ce 100644 --- a/src/GEOMImpl/Makefile.am +++ b/src/GEOMImpl/Makefile.am @@ -238,14 +238,18 @@ libGEOMimpl_la_CPPFLAGS = \ -I$(srcdir)/../NMTDS \ -I$(srcdir)/../NMTTools \ -I$(srcdir)/../GEOM \ + -I$(srcdir)/../BlockFix \ -I$(srcdir)/../GEOMAlgo \ + -I$(srcdir)/../GEOMUtils \ -I$(srcdir)/../SKETCHER \ -I$(srcdir)/../ARCHIMEDE \ -I$(top_builddir)/idl libGEOMimpl_la_LDFLAGS = \ ../GEOM/libGEOMbasic.la \ + ../BlockFix/libBlockFix.la \ ../GEOMAlgo/libGEOMAlgo.la \ + ../GEOMUtils/libGEOMUtils.la \ ../ShHealOper/libShHealOper.la \ ../ARCHIMEDE/libGEOMArchimede.la \ ../SKETCHER/libGEOMSketcher.la \ diff --git a/src/GEOMToolsGUI/GEOMToolsGUI.cxx b/src/GEOMToolsGUI/GEOMToolsGUI.cxx index 01f2c182f..95b4507e8 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI.cxx @@ -325,7 +325,7 @@ bool GEOMToolsGUI::OnGUIEvent(int theCommandID, SUIT_Desktop* parent) case GEOMOp::OpColor: // POPUP - COLOR OnColor(); break; - case GEOMOp::OpSetTexture: // POPUP - TEXTURE + case GEOMOp::OpSetTexture: // POPUP - TEXTURE OnTexture(); break; case GEOMOp::OpTransparency: // POPUP - TRANSPARENCY @@ -349,6 +349,12 @@ bool GEOMToolsGUI::OnGUIEvent(int theCommandID, SUIT_Desktop* parent) case GEOMOp::OpMaterialProperties: // POPUP - MATERIAL PROPERTIES OnMaterialProperties(); break; + case GEOMOp::OpPredefMaterCustom: // POPUP - MATERIAL PROPERTIES - CUSTOM... + OnMaterialProperties(); + break; + case GEOMOp::OpMaterialsLibrary: // POPUP MENU - MATERIAL PROPERTIES + OnMaterialsLibrary(); + break; case GEOMOp::OpAutoColor: // POPUP - AUTO COLOR OnAutoColor(); break; @@ -387,6 +393,25 @@ bool GEOMToolsGUI::OnGUIEvent(int theCommandID, SUIT_Desktop* parent) return true; } +//======================================================================= +// function : OnGUIEvent() +// purpose : +//======================================================================= +bool GEOMToolsGUI::OnGUIEvent(int theCommandID, SUIT_Desktop* parent, const QVariant& theParam ) +{ + getGeometryGUI()->EmitSignalDeactivateDialog(); + + switch ( theCommandID ) { + case GEOMOp::OpPredefMaterial: // POPUP MENU - MATERIAL PROPERTIES - + OnSetMaterial( theParam ); + break; + default: + SUIT_Session::session()->activeApplication()->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID)); + break; + } + return true; +} + //=============================================================================== // function : OnEditDelete() // purpose : diff --git a/src/GEOMToolsGUI/GEOMToolsGUI.h b/src/GEOMToolsGUI/GEOMToolsGUI.h index 8b6c32c78..6c04a9be5 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI.h +++ b/src/GEOMToolsGUI/GEOMToolsGUI.h @@ -54,6 +54,8 @@ public: ~GEOMToolsGUI(); bool OnGUIEvent( int, SUIT_Desktop* ); + bool OnGUIEvent( int theCommandID, SUIT_Desktop*, const QVariant& ); + virtual void deactivate(); enum ActionType { SHOWDLG, INCR, DECR }; @@ -82,6 +84,8 @@ private: void OnPublishObject() ; void OnPointMarker(); void OnMaterialProperties(); + void OnMaterialsLibrary(); + void OnSetMaterial(const QVariant& ); void OnEdgeWidth(); void OnIsosWidth(); void OnBringToFront(); diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx b/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx index 526a9b1e4..268c101c1 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx @@ -34,7 +34,9 @@ #include "GEOMToolsGUI_PublishDlg.h" #include "GEOMToolsGUI_MaterialPropertiesDlg.h" #include "GEOMToolsGUI_LineWidthDlg.h" -#include "Material_Model.h" +#include + +#include #include #include @@ -109,6 +111,7 @@ // VTK includes #include +class QtxDialog; // If the next macro is defined, autocolor feature works for all sub-shapes; // if it is undefined, autocolor feature works for groups only #define GENERAL_AUTOCOLOR @@ -298,8 +301,8 @@ void GEOMToolsGUI::SetColor( const QString& entry, const QColor& color, bool upd SUIT_ViewWindow* window = app->desktop()->activeWindow(); if ( !window ) return; - bool isOCC = ( window && window->getViewManager()->getType() == OCCViewer_Viewer::Type() ); - bool isVTK = ( window && window->getViewManager()->getType() == SVTK_Viewer::Type() ); + bool isOCC = window->getViewManager()->getType() == OCCViewer_Viewer::Type(); + bool isVTK = window->getViewManager()->getType() == SVTK_Viewer::Type(); // get view id int mgrId = window->getViewManager()->getGlobalId(); @@ -354,7 +357,7 @@ void GEOMToolsGUI::OnColor() bool isVTK = ( window && window->getViewManager()->getType() == SVTK_Viewer::Type() ); // get view id - int mgrId = window->getViewManager()->getGlobalId(); + int mgrId = window ? window->getViewManager()->getGlobalId() : -1; if ( isVTK ) { SVTK_ViewWindow* vtkVW = dynamic_cast( window ); @@ -363,7 +366,7 @@ void GEOMToolsGUI::OnColor() // get initial color (use first object from selection) SVTK_View* aView = vtkVW->getView(); QColor color = aView->GetColor( selected.First() ); - QVariant v = appStudy->getObjectProperty( mgrId, selected.First()->getEntry(), COLOR_PROP, color ); + QVariant v = appStudy->getObjectProperty( mgrId, selected.First()->getEntry(), GEOM::propertyName( GEOM::Color ), color ); // show Choose Color dialog box color = QColorDialog::getColor( v.value(), app->desktop() ); @@ -387,7 +390,7 @@ void GEOMToolsGUI::OnColor() QColor color = QColor((int)( aColor.Red() * 255.0 ), (int)( aColor.Green() * 255.0 ), (int)( aColor.Blue() * 255.0 )); - QVariant v = appStudy->getObjectProperty( mgrId, selected.First()->getEntry(), COLOR_PROP, color ); + QVariant v = appStudy->getObjectProperty( mgrId, selected.First()->getEntry(), GEOM::propertyName( GEOM::Color ), color ); // show Choose Color dialog box color = QColorDialog::getColor( v.value(), app->desktop() ); @@ -419,14 +422,14 @@ void GEOMToolsGUI::setVtkColor( SalomeApp_Study* study, // s { // get material property QString matProp; - matProp = study->getObjectProperty( mgrId, IO->getEntry(), MATERIAL_PROP, matProp ).toString(); + matProp = study->getObjectProperty( mgrId, IO->getEntry(), GEOM::propertyName( GEOM::Material ), matProp ).toString(); Material_Model material; material.fromProperties( matProp ); // change color only for shapes with not physical type of material if ( !material.isPhysical() ) { view->SetColor( IO, color ); - study->setObjectProperty( mgrId, IO->getEntry(), COLOR_PROP, color ); + study->setObjectProperty( mgrId, IO->getEntry(), GEOM::propertyName( GEOM::Color ), color ); } // store color to GEOM_Object @@ -459,7 +462,7 @@ void GEOMToolsGUI::setOccColor( SalomeApp_Study* study, // s // get material property QString matProp; - matProp = study->getObjectProperty( mgrId, IO->getEntry(), MATERIAL_PROP, matProp ).toString(); + matProp = study->getObjectProperty( mgrId, IO->getEntry(), GEOM::propertyName( GEOM::Material ), matProp ).toString(); Material_Model material; material.fromProperties( matProp ); @@ -504,7 +507,7 @@ void GEOMToolsGUI::setOccColor( SalomeApp_Study* study, // s io->Redisplay( Standard_True ); - study->setObjectProperty( mgrId, IO->getEntry(), COLOR_PROP, color ); + study->setObjectProperty( mgrId, IO->getEntry(), GEOM::propertyName( GEOM::Color ), color ); } // store color to GEOM_Object @@ -661,6 +664,7 @@ void GEOMToolsGUI::OnNbIsos( ActionType actionType ) OCCViewer_Viewer* vm = dynamic_cast( window->getViewManager()->getViewModel() ); Handle (AIS_InteractiveContext) ic = vm->getAISContext(); + int aMgrId = window->getViewManager()->getGlobalId(); ic->InitCurrent(); if ( ic->MoreCurrent() ) { @@ -702,12 +706,11 @@ void GEOMToolsGUI::OnNbIsos( ActionType actionType ) } for(; ic->MoreCurrent(); ic->NextCurrent()) { - int aMgrId = window->getViewManager()->getGlobalId(); CurObject = Handle(GEOM_AISShape)::DownCast(ic->Current()); Handle(AIS_Drawer) CurDrawer = CurObject->Attributes(); - QVariant v = aStudy->getObjectProperty( aMgrId, CurObject->getIO()->getEntry(), EDGE_WIDTH_PROP , QVariant() ); + QVariant v = aStudy->getObjectProperty( aMgrId, CurObject->getIO()->getEntry(), GEOM::propertyName( GEOM::LineWidth ) , QVariant() ); int width = v.isValid() ? v.toInt() : 1; @@ -719,8 +722,8 @@ void GEOMToolsGUI::OnNbIsos( ActionType actionType ) ic->SetLocalAttributes(CurObject, CurDrawer); ic->Redisplay(CurObject); - QString anIsos("%1%2%3");anIsos = anIsos.arg(newNbUIso);anIsos = anIsos.arg(DIGIT_SEPARATOR);anIsos = anIsos.arg(newNbVIso); - aStudy->setObjectProperty(aMgrId ,CurObject->getIO()->getEntry(), ISOS_PROP, anIsos); + QString anIsos = QString("%1%2%3").arg(newNbUIso).arg(GEOM::subSectionSeparator()).arg(newNbVIso); + aStudy->setObjectProperty(aMgrId ,CurObject->getIO()->getEntry(), GEOM::propertyName( GEOM::NbIsos ), anIsos); } } GeometryGUI::Modified(); @@ -745,6 +748,8 @@ void GEOMToolsGUI::OnNbIsos( ActionType actionType ) if ( !vtkVW ) return; + int aMgrId = window->getViewManager()->getGlobalId(); + SALOME_View* view = GEOM_Displayer::GetActiveView(); vtkActorCollection* aCollection = vtkActorCollection::New(); @@ -814,9 +819,8 @@ void GEOMToolsGUI::OnNbIsos( ActionType actionType ) anActor->SetNbIsos(aIsos); anActor->StoreIsoNumbers(); - QString anIsos("%1%2%3");anIsos = anIsos.arg(newNbUIso);anIsos = anIsos.arg(DIGIT_SEPARATOR);anIsos = anIsos.arg(newNbVIso); - int aMgrId = window->getViewManager()->getGlobalId(); - aStudy->setObjectProperty(aMgrId ,anActor->getIO()->getEntry(), ISOS_PROP, anIsos); + QString anIsos = QString("%1%2%3").arg(newNbUIso).arg(GEOM::subSectionSeparator()).arg(newNbVIso); + aStudy->setObjectProperty(aMgrId ,anActor->getIO()->getEntry(), GEOM::propertyName( GEOM::NbIsos ), anIsos); } anAct = aCollection->GetNextActor(); } @@ -833,7 +837,7 @@ void GEOMToolsGUI::OnDeflection() bool isOCC = (window && window->getViewManager()->getType() == OCCViewer_Viewer::Type()); bool isVTK = (window && window->getViewManager()->getType() == SVTK_Viewer::Type()); - int mgrId = window->getViewManager()->getGlobalId(); + int mgrId = window ? window->getViewManager()->getGlobalId() : -1; if (isOCC) { // if is OCCViewer OCCViewer_Viewer* vm = dynamic_cast(window->getViewManager()->getViewModel()); @@ -863,7 +867,7 @@ void GEOMToolsGUI::OnDeflection() CurObject = Handle(GEOM_AISShape)::DownCast(ic->Current()); ic->SetDeviationCoefficient(CurObject, aNewDC, Standard_True); ic->Redisplay(CurObject); - appStudy->setObjectProperty(mgrId,CurObject->getIO()->getEntry(), DEFLECTION_COEFF_PROP, aNewDC); + appStudy->setObjectProperty(mgrId,CurObject->getIO()->getEntry(), GEOM::propertyName( GEOM::Deflection ), aNewDC); } } } @@ -932,7 +936,7 @@ void GEOMToolsGUI::OnDeflection() if (GEOM_Actor* anActor = GEOM_Actor::SafeDownCast(anAct)) { // There are no casting to needed actor. anActor->SetDeflection(aDC); - appStudy->setObjectProperty(mgrId, anActor->getIO()->getEntry(), DEFLECTION_COEFF_PROP, aDC); + appStudy->setObjectProperty(mgrId, anActor->getIO()->getEntry(), GEOM::propertyName( GEOM::Deflection ), aDC); } anAct = aCollection->GetNextActor(); } @@ -1006,7 +1010,14 @@ void GEOMToolsGUI::OnPointMarker() void GEOMToolsGUI::OnMaterialProperties() { - GEOMToolsGUI_MaterialPropertiesDlg dlg( SUIT_Session::session()->activeApplication()->desktop() ); + GEOMToolsGUI_MaterialPropertiesDlg* dlg = new GEOMToolsGUI_MaterialPropertiesDlg( SUIT_Session::session()->activeApplication()->desktop(), true, false, QtxDialog::OK | QtxDialog::Close | QtxDialog::Apply | QtxDialog::Help ); + dlg->show(); +} + +void GEOMToolsGUI::OnMaterialsLibrary() +{ + GEOMToolsGUI_MaterialPropertiesDlg dlg( SUIT_Session::session()->activeApplication()->desktop(), false, true, QtxDialog::Standard ); + dlg.setWindowTitle( tr( "MATERIAL_LIBRARY_TLT" ) ); dlg.exec(); } @@ -1093,7 +1104,7 @@ void GEOMToolsGUI::OnEdgeWidth() bool isOCC = (window && window->getViewManager()->getType() == OCCViewer_Viewer::Type()); bool isVTK = (window && window->getViewManager()->getType() == SVTK_Viewer::Type()); - int mgrId = window->getViewManager()->getGlobalId(); + int mgrId = window ? window->getViewManager()->getGlobalId() : -1; if (isOCC) { // if is OCCViewer OCCViewer_Viewer* vm = dynamic_cast(window->getViewManager()->getViewModel()); @@ -1126,7 +1137,7 @@ void GEOMToolsGUI::OnEdgeWidth() ic->Redisplay(cur); } } - appStudy->setObjectProperty(mgrId, CurObject->getIO()->getEntry(), EDGE_WIDTH_PROP, aNewWidth); + appStudy->setObjectProperty(mgrId, CurObject->getIO()->getEntry(), GEOM::propertyName( GEOM::LineWidth ), aNewWidth); } } } @@ -1195,7 +1206,7 @@ void GEOMToolsGUI::OnEdgeWidth() if (GEOM_Actor* anActor = GEOM_Actor::SafeDownCast(anAct)) { // There are no casting to needed actor. anActor->SetWidth(aWidth); - appStudy->setObjectProperty(mgrId, anActor->getIO()->getEntry(), EDGE_WIDTH_PROP, aWidth); + appStudy->setObjectProperty(mgrId, anActor->getIO()->getEntry(), GEOM::propertyName( GEOM::LineWidth ), aWidth); } anAct = aCollection->GetNextActor(); } @@ -1218,6 +1229,7 @@ void GEOMToolsGUI::OnIsosWidth() { OCCViewer_Viewer* vm = dynamic_cast( window->getViewManager()->getViewModel() ); Handle (AIS_InteractiveContext) ic = vm->getAISContext(); + int aMgrId = window->getViewManager()->getGlobalId(); ic->InitCurrent(); if ( ic->MoreCurrent() ) { @@ -1246,7 +1258,6 @@ void GEOMToolsGUI::OnIsosWidth() { return; for(; ic->MoreCurrent(); ic->NextCurrent()) { - int aMgrId = window->getViewManager()->getGlobalId(); CurObject = Handle(GEOM_AISShape)::DownCast(ic->Current()); Handle(AIS_Drawer) CurDrawer = CurObject->Attributes(); @@ -1256,7 +1267,7 @@ void GEOMToolsGUI::OnIsosWidth() { ic->Redisplay(CurObject); - aStudy->setObjectProperty(aMgrId ,CurObject->getIO()->getEntry(), ISOS_WIDTH_PROP, aWidth); + aStudy->setObjectProperty(aMgrId ,CurObject->getIO()->getEntry(), GEOM::propertyName( GEOM::IsosWidth ), aWidth); } GeometryGUI::Modified(); } @@ -1281,6 +1292,8 @@ void GEOMToolsGUI::OnIsosWidth() { if ( !vtkVW ) return; + int aMgrId = window->getViewManager()->getGlobalId(); + SALOME_View* view = GEOM_Displayer::GetActiveView(); vtkActorCollection* aCollection = vtkActorCollection::New(); @@ -1325,8 +1338,7 @@ void GEOMToolsGUI::OnIsosWidth() { if(GEOM_Actor* anActor = GEOM_Actor::SafeDownCast(anAct)) { // There are no casting to needed actor. anActor->SetIsosWidth(aWidth); - int aMgrId = window->getViewManager()->getGlobalId(); - aStudy->setObjectProperty(aMgrId ,anActor->getIO()->getEntry(), ISOS_WIDTH_PROP, aWidth); + aStudy->setObjectProperty(aMgrId ,anActor->getIO()->getEntry(), GEOM::propertyName( GEOM::IsosWidth ), aWidth); } anAct = aCollection->GetNextActor(); } @@ -1377,15 +1389,15 @@ void GEOMToolsGUI::OnBringToFront() { if ( isOCC ) { GEOMBase* gb = new GEOMBase(); Handle(GEOM_AISShape) aisShape; + int aMgrId = window->getViewManager()->getGlobalId(); Handle(AIS_InteractiveContext) ic = vm->getAISContext(); SALOME_ListIO anIOlst; for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) { aisShape = gb->ConvertIOinGEOMAISShape( It.Value(), true ); if ( !aisShape.IsNull() ) { + appStudy->setObjectProperty( aMgrId, aisShape->getIO()->getEntry(), GEOM::propertyName( GEOM::TopLevel ), checked ); aisShape->setTopLevel(checked); - int aMgrId = window->getViewManager()->getGlobalId(); - appStudy->setObjectProperty( aMgrId, aisShape->getIO()->getEntry(), TOP_LEVEL_PROP, checked ); anIOlst.Append(aisShape->getIO()); } } // for... @@ -1422,6 +1434,7 @@ void GEOMToolsGUI::OnClsBringToFront() { OCCViewer_Viewer* vm = dynamic_cast( window->getViewManager()->getViewModel() ); Handle (AIS_InteractiveContext) ic = vm->getAISContext(); + int aMgrId = window->getViewManager()->getGlobalId(); SALOME_ListIO anIOlst; AIS_ListOfInteractive aList; @@ -1433,10 +1446,8 @@ void GEOMToolsGUI::OnClsBringToFront() { if(CurObject.IsNull()) continue; + appStudy->setObjectProperty( aMgrId, QString(CurObject->getIO()->getEntry()), GEOM::propertyName( GEOM::TopLevel ), Standard_False ); CurObject->setTopLevel(Standard_False); - - int aMgrId = window->getViewManager()->getGlobalId(); - appStudy->setObjectProperty( aMgrId, QString(CurObject->getIO()->getEntry()), TOP_LEVEL_PROP, Standard_False ); anIOlst.Append(CurObject->getIO()); } disp->Redisplay(anIOlst); @@ -1444,3 +1455,40 @@ void GEOMToolsGUI::OnClsBringToFront() { } } +void GEOMToolsGUI::OnSetMaterial( const QVariant& theParam ) +{ + if ( !theParam.canConvert() ) return; + + QString theName = theParam.toString(); + + SalomeApp_Application* app = dynamic_cast( SUIT_Session::session()->activeApplication() ); + if ( !app ) return; + + SalomeApp_Study* study = dynamic_cast( app->activeStudy() ); + if ( !study ) return; + + LightApp_SelectionMgr* selMgr = app->selectionMgr(); + + SALOME_ListIO selected; + selMgr->selectedObjects( selected ); + + if ( selected.IsEmpty() ) return; + + GEOM_Displayer displayer( study ); + + SALOME_View* window = displayer.GetActiveView(); + if ( !window ) return; + + int mgrId = dynamic_cast( window )->getViewManager()->getGlobalId(); + + Material_Model aModel; + aModel.fromResources( theName ); + QString prop = aModel.toProperties(); + + for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) { + Handle(SALOME_InteractiveObject) io = It.Value(); + study->setObjectProperty( mgrId, io->getEntry(), GEOM::propertyName( GEOM::Material ), prop ); + if ( window->isVisible( io ) ) displayer.Redisplay( io, false ); + } + displayer.UpdateViewer(); +} diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_DeflectionDlg.cxx b/src/GEOMToolsGUI/GEOMToolsGUI_DeflectionDlg.cxx index 428c91c47..48cfb2b0b 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI_DeflectionDlg.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI_DeflectionDlg.cxx @@ -78,7 +78,7 @@ GEOMToolsGUI_DeflectionDlg::GEOMToolsGUI_DeflectionDlg (QWidget* parent) SpinBox->setAcceptNames( false ); SpinBox->setPrecision( aPrecision ); SpinBox->setDecimals( aPrecision ); - SpinBox->setRange( DEFLECTION_MIN, 1.0 ); + SpinBox->setRange( GEOM::minDeflection(), 1.0 ); SpinBox->setSingleStep( 1.0e-04 ); // Add a hint for the user saying how to tune precision QString userPropName = QObject::tr( QString( "GEOM_PREF_%1" ).arg( quantity ).toLatin1().constData() ); diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_MarkerDlg.cxx b/src/GEOMToolsGUI/GEOMToolsGUI_MarkerDlg.cxx index 4ba147b78..7a1952ad6 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI_MarkerDlg.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI_MarkerDlg.cxx @@ -228,13 +228,13 @@ void GEOMToolsGUI_MarkerDlg::accept() anObject->SetMarkerStd( getMarkerType(), getStandardMarkerScale() ); QString aMarker = "%1%2%3"; aMarker = aMarker.arg(getMarkerType()); - aMarker = aMarker.arg(DIGIT_SEPARATOR); + aMarker = aMarker.arg(GEOM::subSectionSeparator()); aMarker = aMarker.arg(getStandardMarkerScale()); - getStudy()->setObjectProperty(mgrId ,it.Value()->getEntry(),MARKER_TYPE_PROP, aMarker); + getStudy()->setObjectProperty(mgrId ,it.Value()->getEntry(),GEOM::propertyName( GEOM::PointMarker ), aMarker); } else if ( getCustomMarkerID() > 0 ) { anObject->SetMarkerTexture( getCustomMarkerID() ); - getStudy()->setObjectProperty(mgrId ,it.Value()->getEntry(),MARKER_TYPE_PROP, QString::number(getCustomMarkerID())); + getStudy()->setObjectProperty(mgrId ,it.Value()->getEntry(),GEOM::propertyName( GEOM::PointMarker ), QString::number(getCustomMarkerID())); } } } diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_MaterialPropertiesDlg.cxx b/src/GEOMToolsGUI/GEOMToolsGUI_MaterialPropertiesDlg.cxx index ca92d6f08..61c7c763d 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI_MaterialPropertiesDlg.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI_MaterialPropertiesDlg.cxx @@ -26,6 +26,7 @@ #include "GEOM_Constants.h" #include "GEOM_VTKPropertyMaterial.hxx" #include "GEOMBase.h" +#include "GEOM_Displayer.h" #include #include @@ -50,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -89,13 +91,17 @@ void GEOMToolsGUI_MaterialList::contextMenuEvent( QContextMenuEvent* e ) /*! \brief Constructor \param parent parent widget + \param showSelWidget if \c true then objects can be selected by user + \param modal if \c true dialog box is modal + \param f specified control buttons for dialog box (QtxDialog::ButtonFlags) */ -GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget* parent ) - : QtxDialog( parent, true, true, OK | Close | Apply | Help ) +GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget* parent,bool showSelWidget, bool modal,const int f ) + : QtxDialog( parent, modal, true, f ) { + myShowSelWidget = showSelWidget; // Set title setWindowTitle( tr( "MATERIAL_PROPERTIES_TLT" ) ); - + // main layout QVBoxLayout* main = new QVBoxLayout( mainFrame() ); main->setMargin( 0 ); @@ -105,6 +111,11 @@ GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget* QFrame* fr = new QFrame( mainFrame() ); fr->setFrameStyle( QFrame::Box | QFrame::Sunken ); main->addWidget( fr ); + // selection widget + myLineEditCurArg = new QLineEdit(fr); + myLineEditCurArg->setReadOnly(true); + myPushBtn = new QPushButton(fr); + QLabel* PushBtnLab = new QLabel( tr( "GEOM_OBJECTS" ), fr ); // materials list widget myMaterials = new GEOMToolsGUI_MaterialList( fr ); @@ -130,41 +141,64 @@ GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget* // "physical" material type widgets myPhysical = new QCheckBox( tr( "PHYSICAL" ), propWidget ); + // Labels for front and back reflection components + QLabel* aFrontLabel = new QLabel( tr( "FRONT_FACE" ), propWidget ); + QLabel* aBackLabel = new QLabel( tr( "BACK_FACE" ), propWidget ); + // reflection components widgets for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ ) { Reflection refl; + + refl.enabled = new QCheckBox( propWidget ); refl.label = new QLabel( tr( QString( "REFLECTION_%1" ).arg( i ).toLatin1().data() ), propWidget ); refl.color = new QtxColorButton( propWidget ); //refl.color->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - refl.coef = new QtxDoubleSpinBox( propWidget ); - refl.coef->setPrecision( 4 ); - refl.coef->setDecimals( 4 ); - refl.coef->setRange( 0., 1. ); - refl.coef->setSingleStep( 0.05 ); - refl.coef->setMinimumWidth( 80 ); - - refl.enabled = new QCheckBox( tr( "ENABLED" ), propWidget ); + refl.front_coef = new QtxDoubleSpinBox( propWidget ); + refl.front_coef->setPrecision( 4 ); + refl.front_coef->setDecimals( 4 ); + refl.front_coef->setRange( 0., 1. ); + refl.front_coef->setSingleStep( 0.05 ); + refl.front_coef->setMinimumWidth( 80 ); + + refl.back_coef = new QtxDoubleSpinBox( propWidget ); + refl.back_coef->setPrecision( 4 ); + refl.back_coef->setDecimals( 4 ); + refl.back_coef->setRange( 0., 1. ); + refl.back_coef->setSingleStep( 0.05 ); + refl.back_coef->setMinimumWidth( 80 ); myReflection << refl; } // shininess widgets QLabel* shininessLab = new QLabel( tr( "SHININESS" ), propWidget ); - myShininess = new QtxDoubleSpinBox( propWidget ); - myShininess->setPrecision( 4 ); - myShininess->setDecimals( 4 ); - myShininess->setRange( 0., 1. ); - myShininess->setSingleStep( 0.05 ); + myFrontShininess = new QtxDoubleSpinBox( propWidget ); + myFrontShininess->setPrecision( 4 ); + myFrontShininess->setDecimals( 4 ); + myFrontShininess->setRange( 0., 1. ); + myFrontShininess->setSingleStep( 0.05 ); + + myBackShininess = new QtxDoubleSpinBox( propWidget ); + myBackShininess->setPrecision( 4 ); + myBackShininess->setDecimals( 4 ); + myBackShininess->setRange( 0., 1. ); + myBackShininess->setSingleStep( 0.05 ); // separator widgets QFrame* line1 = new QFrame( propWidget ); line1->setFrameStyle( QFrame::HLine | QFrame::Sunken ); QFrame* line2 = new QFrame( propWidget ); line2->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + QFrame* line3 = new QFrame( propWidget ); + line3->setFrameStyle( QFrame::VLine | QFrame::Sunken ); + QFrame* line4 = new QFrame( propWidget ); + line4->setFrameStyle( QFrame::VLine | QFrame::Sunken ); + QFrame* line5 = new QFrame( propWidget ); + line5->setFrameStyle( QFrame::HLine | QFrame::Sunken ); // add / remove material buttons myAddButton = new QPushButton( tr( "ADD_MATERIAL" ), propWidget ); @@ -178,21 +212,42 @@ GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget* btnLayout->addWidget( myDelButton ); // layout all properties widgets together - propLayout->addWidget( myColorLab, 0, 0 ); - propLayout->addWidget( myColor, 0, 1 ); - propLayout->addWidget( line1, 1, 0, 1, 4 ); - propLayout->addWidget( myPhysical, 2, 0, 1, 2 ); + propLayout->addWidget( PushBtnLab,0,0); + propLayout->addWidget( myPushBtn,0,1); + propLayout->addWidget( myLineEditCurArg, 0, 2, 1, 5 ); + propLayout->addWidget( line1, 1, 0, 1, 7 ); + propLayout->addWidget( myColorLab, 2, 1 ); + propLayout->addWidget( myColor, 2, 2 ); + propLayout->addWidget( myPhysical, 2, 0 ); + propLayout->addWidget( line2, 3, 0, 1, 7 ); + propLayout->addWidget( aFrontLabel, 4, 4); + propLayout->addWidget( aBackLabel, 4, 6); + + propLayout->addWidget( line3, 4, 3, 6, 1 ); + propLayout->addWidget( line4, 4, 5, 6, 1 ); + + if( !myShowSelWidget ) { + myColorLab->hide(); + myColor->hide(); + line1->hide(); + myLineEditCurArg->hide(); + myPushBtn->hide(); + PushBtnLab->hide(); + } for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ ) { - propLayout->addWidget( myReflection[i].label, i+3, 0 ); - propLayout->addWidget( myReflection[i].color, i+3, 1 ); - propLayout->addWidget( myReflection[i].coef, i+3, 2 ); - propLayout->addWidget( myReflection[i].enabled, i+3, 3 ); + propLayout->addWidget( myReflection[i].enabled, i+5, 0 ); + propLayout->addWidget( myReflection[i].label, i+5, 1 ); + propLayout->addWidget( myReflection[i].color, i+5, 2 ); + propLayout->addWidget( myReflection[i].front_coef, i+5, 4 ); + propLayout->addWidget( myReflection[i].back_coef, i+5, 6 ); } - propLayout->addWidget( shininessLab, 7, 0 ); - propLayout->addWidget( myShininess, 7, 2 ); - propLayout->addWidget( line2, 8, 0, 1, 4 ); - propLayout->setRowStretch( 9, 5 ); - propLayout->addLayout( btnLayout, 10, 0, 1, 4 ); + + propLayout->addWidget( shininessLab, 9, 0 ); + propLayout->addWidget( myFrontShininess, 9, 4 ); + propLayout->addWidget( myBackShininess, 9, 6 ); + propLayout->addWidget( line5, 10, 0, 1, 7 ); + propLayout->setRowStretch( 11, 5 ); + propLayout->addLayout( btnLayout, 12, 0, 1, 7 ); // initialize dialog box setButtonPosition( Right, Close ); @@ -227,6 +282,9 @@ GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget* // install event filter to the materials list to process key press events myMaterials->installEventFilter( this ); + //Set image + myPushBtn->setIcon(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT"))); + // connect signals // note: all widgets, that change material properties, are connected to the common signal // changed(), instead of connecting directly to the slot - this allows easy temporary blocking @@ -234,10 +292,12 @@ GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget* connect( myPhysical, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) ); for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ ) { connect( myReflection[i].color, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) ); - connect( myReflection[i].coef, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) ); + connect( myReflection[i].front_coef, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) ); + connect( myReflection[i].back_coef, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) ); connect( myReflection[i].enabled, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) ); } - connect( myShininess, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) ); + connect( myFrontShininess, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) ); + connect( myBackShininess, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) ); connect( myMaterials, SIGNAL( itemSelectionChanged() ), this, SLOT( onMaterialChanged() ) ); connect( myMaterials, SIGNAL( itemChanged( QListWidgetItem* ) ), @@ -249,6 +309,9 @@ GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget* connect( this, SIGNAL( dlgApply() ), this, SLOT( onApply() ) ); connect( this, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) ); connect( this, SIGNAL( changed() ), this, SLOT( onChanged() ) ); + connect(myPushBtn, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), + SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); // initialize current material model according to the selection myColor->setColor( SUIT_Session::session()->resourceMgr()->colorValue( "Geometry", "shading_color", QColor( 255, 0, 0 ) ) ); @@ -266,17 +329,20 @@ GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget* if ( window ) { int mgrId = window->getViewManager()->getGlobalId(); PropMap propMap = study->getObjectPropMap( mgrId, io->getEntry() ); - QString matProp = propMap.value(MATERIAL_PROP).toString(); + QString matProp = propMap.value(GEOM::propertyName( GEOM::Material )).toString(); if ( !matProp.isEmpty() ) myCurrentModel.fromProperties( matProp ); - QColor c = propMap.value(COLOR_PROP).value(); + QColor c = propMap.value(GEOM::propertyName( GEOM::Color )).value(); if ( c.isValid() ) myColor->setColor( c ); } } } } - + myLineEditCurArg->setText(""); + myPushBtn->click(); + SelectionIntoArgument(); + // finally activate current material properties myMaterials->setCurrentRow( 0 ); } @@ -324,12 +390,14 @@ void GEOMToolsGUI_MaterialPropertiesDlg::fromModel( const Material_Model& model for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ ) { myReflection[i].color->setColor( model.color( (Material_Model::ReflectionType)i ) ); - myReflection[i].coef->setValue( model.reflection( (Material_Model::ReflectionType)i ) ); + myReflection[i].front_coef->setValue( model.reflection( (Material_Model::ReflectionType)i, true ) ); + myReflection[i].back_coef->setValue( model.reflection( (Material_Model::ReflectionType)i, false ) ); myReflection[i].enabled->setChecked( model.hasReflection( (Material_Model::ReflectionType)i ) ); } // shininess - myShininess->setValue( model.shininess() ); + myFrontShininess->setValue( model.shininess( true ) ); + myBackShininess->setValue( model.shininess( false ) ); // type (physical or no) myPhysical->setChecked( model.isPhysical() ); @@ -345,13 +413,15 @@ void GEOMToolsGUI_MaterialPropertiesDlg::toModel( Material_Model& model ) const model.setPhysical( myPhysical->isChecked() ); // shininess - model.setShininess( myShininess->value() ); + model.setShininess( myFrontShininess->value(), true ); + model.setShininess( myBackShininess->value(), false ); // reflection components for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ ) { model.setColor ( (Material_Model::ReflectionType)i, myReflection[i].color->color() ); - model.setReflection( (Material_Model::ReflectionType)i, myReflection[i].coef->value() ); + model.setReflection( (Material_Model::ReflectionType)i, myReflection[i].front_coef->value(), true ); + model.setReflection( (Material_Model::ReflectionType)i, myReflection[i].back_coef->value(), false ); model.setReflection( (Material_Model::ReflectionType)i, myReflection[i].enabled->isChecked() ); } } @@ -391,7 +461,7 @@ void GEOMToolsGUI_MaterialPropertiesDlg::onApply() { // save user materials myResourceMgr.save(); - + if( !myShowSelWidget ) return; // store selected material properties in the current model toModel( myCurrentModel ); @@ -421,19 +491,20 @@ void GEOMToolsGUI_MaterialPropertiesDlg::onApply() SVTK_View* aView = vtkVW->getView(); // get VTK material properties from the current model - GEOM_VTKPropertyMaterial* vtkProp = myCurrentModel.getMaterialVTKProperty(); + GEOM_VTKPropertyMaterial* vtkPropF = myCurrentModel.getMaterialVTKProperty(); + GEOM_VTKPropertyMaterial* vtkPropB = myCurrentModel.getMaterialVTKProperty( false ); SUIT_OverrideCursor wc(); for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) { // set material property to the presentation - aView->SetMaterial( It.Value(), vtkProp ); + aView->SetMaterial( It.Value(), vtkPropF, vtkPropB ); // store chosen material in the property map - study->setObjectProperty( mgrId, It.Value()->getEntry(), MATERIAL_PROP, prop ); + study->setObjectProperty( mgrId, It.Value()->getEntry(), GEOM::propertyName( GEOM::Material ), prop ); // set correct color for the non-physical material if ( !myCurrentModel.isPhysical() ) { aView->SetColor( It.Value(), myColor->color() ); - study->setObjectProperty( mgrId, It.Value()->getEntry(), COLOR_PROP, myColor->color() ); + study->setObjectProperty( mgrId, It.Value()->getEntry(), GEOM::propertyName( GEOM::Color ), myColor->color() ); } } aView->Repaint(); @@ -448,25 +519,32 @@ void GEOMToolsGUI_MaterialPropertiesDlg::onApply() Handle(AIS_InteractiveContext) ic = vm->getAISContext(); // get OCC material aspect from the current model - Graphic3d_MaterialAspect occAspect = myCurrentModel.getMaterialOCCAspect(); + Graphic3d_MaterialAspect front_occAspect = myCurrentModel.getMaterialOCCAspect( true ); + Graphic3d_MaterialAspect back_occAspect = myCurrentModel.getMaterialOCCAspect( false ); SUIT_OverrideCursor wc(); for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) { Handle(GEOM_AISShape) aisShape = GEOMBase::ConvertIOinGEOMAISShape( It.Value(), true ); if ( !aisShape.IsNull() ) { - // set material property to the presentation - aisShape->SetMaterial( occAspect ); - // store chosen material in the property map - study->setObjectProperty( mgrId, It.Value()->getEntry(), MATERIAL_PROP, prop ); - // set correct color for the non-physical material - if ( !myCurrentModel.isPhysical() ) { - aisShape->SetShadingColor( SalomeApp_Tools::color( myColor->color() ) ); - study->setObjectProperty( mgrId, It.Value()->getEntry(), COLOR_PROP, myColor->color() ); - ic->RecomputePrsOnly( aisShape, Standard_False ); - } - //if ( aisShape->DisplayMode() != AIS_Shaded/*aisShape->DisplayMode() == GEOM_AISShape::ShadingWithEdges*/) - ic->Redisplay( aisShape, Standard_False ); + // Set front material for the selected shape + aisShape->SetCurrentFacingModel(Aspect_TOFM_FRONT_SIDE); + aisShape->SetMaterial(front_occAspect); + // Set back material for the selected shape + aisShape->SetCurrentFacingModel(Aspect_TOFM_BACK_SIDE); + aisShape->SetMaterial(back_occAspect); + // Return to the default facing mode + aisShape->SetCurrentFacingModel(Aspect_TOFM_BOTH_SIDE); + // store chosen material in the property map + study->setObjectProperty( mgrId, It.Value()->getEntry(), GEOM::propertyName( GEOM::Material ), prop ); + // set correct color for the non-physical material + if ( !myCurrentModel.isPhysical() ) { + aisShape->SetShadingColor( SalomeApp_Tools::color( myColor->color() ) ); + study->setObjectProperty( mgrId, It.Value()->getEntry(), GEOM::propertyName( GEOM::Color ), myColor->color() ); + ic->RecomputePrsOnly( aisShape, Standard_False ); + } + //if ( aisShape->DisplayMode() != AIS_Shaded/*aisShape->DisplayMode() == GEOM_AISShape::ShadingWithEdges*/) + ic->Redisplay( aisShape, Standard_False ); } } ic->UpdateCurrentViewer(); @@ -670,3 +748,37 @@ void GEOMToolsGUI_MaterialPropertiesDlg::updateState() myColor->setEnabled( !myPhysical->isChecked() ); myReflection[0].color->setEnabled( myPhysical->isChecked() ); } + + +void GEOMToolsGUI_MaterialPropertiesDlg::SetEditCurrentArgument() +{ + QPushButton* send = (QPushButton*)sender(); + + if (send == myPushBtn) { + // enable line edit + myLineEditCurArg->setEnabled(true); + myLineEditCurArg->setFocus(); + SelectionIntoArgument(); + // after setFocus(), because it will be setDown(false) when loses focus + send->setDown(true); + } +} + +/*! + \brief Called when selection as changed or other case +*/ +void GEOMToolsGUI_MaterialPropertiesDlg::SelectionIntoArgument() +{ + myLineEditCurArg->setText( "" ); + QString aString = ""; + + SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() ); + SalomeApp_Study* study = dynamic_cast( app->activeStudy() ); + LightApp_SelectionMgr* aSelMgr = app->selectionMgr(); + if ( study ) { + SALOME_ListIO aSelList; + aSelMgr->selectedObjects(aSelList); + int nbSel = GEOMBase::GetNameOfSelectedIObjects(aSelList, aString, true); + } + myLineEditCurArg->setText( aString ); +} diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_MaterialPropertiesDlg.h b/src/GEOMToolsGUI/GEOMToolsGUI_MaterialPropertiesDlg.h index 1e2a7c6f7..c9f20598e 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI_MaterialPropertiesDlg.h +++ b/src/GEOMToolsGUI/GEOMToolsGUI_MaterialPropertiesDlg.h @@ -45,7 +45,7 @@ class GEOMTOOLSGUI_EXPORT GEOMToolsGUI_MaterialPropertiesDlg : public QtxDialog enum { TypeRole = Qt::UserRole + 123, NameRole }; public: - GEOMToolsGUI_MaterialPropertiesDlg( QWidget* = 0 ); + GEOMToolsGUI_MaterialPropertiesDlg( QWidget* = 0 , bool = true, bool = false,const int = Standard ); ~GEOMToolsGUI_MaterialPropertiesDlg(); void accept(); @@ -72,26 +72,33 @@ private slots: void onAddMaterial(); void onApply(); void onHelp(); + void SetEditCurrentArgument(); + void SelectionIntoArgument(); private: typedef struct { + QCheckBox* enabled; QLabel* label; QtxColorButton* color; - QtxDoubleSpinBox* coef; - QCheckBox* enabled; + QtxDoubleSpinBox* front_coef; + QtxDoubleSpinBox* back_coef; } Reflection; GEOMToolsGUI_MaterialList* myMaterials; QCheckBox* myPhysical; QList myReflection; - QtxDoubleSpinBox* myShininess; + QtxDoubleSpinBox* myFrontShininess; + QtxDoubleSpinBox* myBackShininess; QLabel* myColorLab; QtxColorButton* myColor; QPushButton* myAddButton; QPushButton* myDelButton; Material_ResourceMgr myResourceMgr; Material_Model myCurrentModel; + bool myShowSelWidget; + QLineEdit* myLineEditCurArg; + QPushButton* myPushBtn; }; class GEOMToolsGUI_MaterialList : public QListWidget diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_TransparencyDlg.cxx b/src/GEOMToolsGUI/GEOMToolsGUI_TransparencyDlg.cxx index 3bcbc16ea..55f7c92d2 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI_TransparencyDlg.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI_TransparencyDlg.cxx @@ -286,7 +286,7 @@ void GEOMToolsGUI_TransparencyDlg::SetTransparency() SUIT_OverrideCursor(); for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) { aView->SetTransparency( It.Value(), newValue ); - aStudy->setObjectProperty( aMgrId , It.Value()->getEntry(), TRANSPARENCY_PROP , newValue ); + aStudy->setObjectProperty( aMgrId , It.Value()->getEntry(), GEOM::propertyName( GEOM::Transparency ) , newValue ); } GeometryGUI::Modified(); aView->Repaint(); @@ -317,7 +317,7 @@ void GEOMToolsGUI_TransparencyDlg::SetTransparency() if ( !aisShape.IsNull() ) { ic->SetTransparency( aisShape, newValue, false ); ic->Redisplay( aisShape, Standard_False, Standard_True ); - aStudy->setObjectProperty( aMgrId , It.Value()->getEntry(), TRANSPARENCY_PROP , newValue ); + aStudy->setObjectProperty( aMgrId , It.Value()->getEntry(), GEOM::propertyName( GEOM::Transparency ) , newValue ); } } // for... ic->UpdateCurrentViewer(); diff --git a/src/GEOMUtils/GEOMUtils.cxx b/src/GEOMUtils/GEOMUtils.cxx new file mode 100644 index 000000000..292ab5c44 --- /dev/null +++ b/src/GEOMUtils/GEOMUtils.cxx @@ -0,0 +1,499 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com + +#include + +#include + +#include + +#include +#include +#include + +// OCCT Includes +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include +#include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC + +#define STD_SORT_ALGO 1 + +//======================================================================= +//function : GetPosition +//purpose : +//======================================================================= +gp_Ax3 GEOMUtils::GetPosition (const TopoDS_Shape& theShape) +{ + gp_Ax3 aResult; + + if (theShape.IsNull()) + return aResult; + + // Axes + aResult.Transform(theShape.Location().Transformation()); + if (theShape.ShapeType() == TopAbs_FACE) { + Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(theShape)); + if (!aGS.IsNull() && aGS->IsKind(STANDARD_TYPE(Geom_Plane))) { + Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast(aGS); + gp_Pln aPln = aGPlane->Pln(); + aResult = aPln.Position(); + // In case of reverse orinetation of the face invert the plane normal + // (the face's normal does not mathc the plane's normal in this case) + if(theShape.Orientation() == TopAbs_REVERSED) + { + gp_Dir Vx = aResult.XDirection(); + gp_Dir N = aResult.Direction().Mirrored(Vx); + gp_Pnt P = aResult.Location(); + aResult = gp_Ax3(P, N, Vx); + } + } + } + + // Origin + gp_Pnt aPnt; + + TopAbs_ShapeEnum aShType = theShape.ShapeType(); + + if (aShType == TopAbs_VERTEX) { + aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape)); + } + else { + if (aShType == TopAbs_COMPOUND) { + aShType = GetTypeOfSimplePart(theShape); + } + + GProp_GProps aSystem; + if (aShType == TopAbs_EDGE || aShType == TopAbs_WIRE) + BRepGProp::LinearProperties(theShape, aSystem); + else if (aShType == TopAbs_FACE || aShType == TopAbs_SHELL) + BRepGProp::SurfaceProperties(theShape, aSystem); + else + BRepGProp::VolumeProperties(theShape, aSystem); + + aPnt = aSystem.CentreOfMass(); + } + + aResult.SetLocation(aPnt); + + return aResult; +} + +//======================================================================= +//function : GetVector +//purpose : +//======================================================================= +gp_Vec GEOMUtils::GetVector (const TopoDS_Shape& theShape) +{ + if (theShape.IsNull()) + Standard_NullObject::Raise("Null shape is given for a vector"); + + if (theShape.ShapeType() != TopAbs_EDGE) + Standard_TypeMismatch::Raise("Invalid shape is given, must be a vector or an edge"); + + TopoDS_Edge anE = TopoDS::Edge(theShape); + + TopoDS_Vertex V1, V2; + TopExp::Vertices(anE, V1, V2, Standard_True); + + if (V1.IsNull() || V2.IsNull()) + Standard_NullObject::Raise("Invalid edge is given, it must have two points"); + + gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2)); + if (aV.Magnitude() < gp::Resolution()) { + Standard_ConstructionError::Raise("Vector of zero length is given"); + } + + return aV; +} + +//======================================================================= +//function : ShapeToDouble +//purpose : used by CompareShapes::operator() +//======================================================================= +std::pair ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting) +{ + // Computing of CentreOfMass + gp_Pnt GPoint; + double Len; + + if (S.ShapeType() == TopAbs_VERTEX) { + GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S)); + Len = (double)S.Orientation(); + } + else { + GProp_GProps GPr; + // BEGIN: fix for Mantis issue 0020842 + if (isOldSorting) { + BRepGProp::LinearProperties(S, GPr); + } + else { + if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) { + BRepGProp::LinearProperties(S, GPr); + } + else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) { + BRepGProp::SurfaceProperties(S, GPr); + } + else { + BRepGProp::VolumeProperties(S, GPr); + } + } + // END: fix for Mantis issue 0020842 + GPoint = GPr.CentreOfMass(); + Len = GPr.Mass(); + } + + double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9; + return std::make_pair(dMidXYZ, Len); +} + +//======================================================================= +//function : CompareShapes::operator() +//purpose : used by std::sort(), called from SortShapes() +//======================================================================= +bool GEOMUtils::CompareShapes::operator() (const TopoDS_Shape& theShape1, + const TopoDS_Shape& theShape2) +{ + if (!myMap.IsBound(theShape1)) { + myMap.Bind(theShape1, ShapeToDouble(theShape1, myIsOldSorting)); + } + + if (!myMap.IsBound(theShape2)) { + myMap.Bind(theShape2, ShapeToDouble(theShape2, myIsOldSorting)); + } + + std::pair val1 = myMap.Find(theShape1); + std::pair val2 = myMap.Find(theShape2); + + double tol = Precision::Confusion(); + bool exchange = Standard_False; + + double dMidXYZ = val1.first - val2.first; + if (dMidXYZ >= tol) { + exchange = Standard_True; + } + else if (Abs(dMidXYZ) < tol) { + double dLength = val1.second - val2.second; + if (dLength >= tol) { + exchange = Standard_True; + } + else if (Abs(dLength) < tol && theShape1.ShapeType() <= TopAbs_FACE) { + // PAL17233 + // equal values possible on shapes such as two halves of a sphere and + // a membrane inside the sphere + Bnd_Box box1,box2; + BRepBndLib::Add(theShape1, box1); + if (!box1.IsVoid()) { + BRepBndLib::Add(theShape2, box2); + Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent(); + if (dSquareExtent >= tol) { + exchange = Standard_True; + } + else if (Abs(dSquareExtent) < tol) { + Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2; + box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + val1 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9; + box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + val2 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9; + if ((val1 - val2) >= tol) { + exchange = Standard_True; + } + } + } + } + } + + //return val1 < val2; + return !exchange; +} + +//======================================================================= +//function : SortShapes +//purpose : +//======================================================================= +void GEOMUtils::SortShapes (TopTools_ListOfShape& SL, + const Standard_Boolean isOldSorting) +{ +#ifdef STD_SORT_ALGO + std::vector aShapesVec; + aShapesVec.reserve(SL.Extent()); + + TopTools_ListIteratorOfListOfShape it (SL); + for (; it.More(); it.Next()) { + aShapesVec.push_back(it.Value()); + } + SL.Clear(); + + CompareShapes shComp (isOldSorting); + std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp); + //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp); + + std::vector::const_iterator anIter = aShapesVec.begin(); + for (; anIter != aShapesVec.end(); ++anIter) { + SL.Append(*anIter); + } +#else + // old implementation + Standard_Integer MaxShapes = SL.Extent(); + TopTools_Array1OfShape aShapes (1,MaxShapes); + TColStd_Array1OfInteger OrderInd(1,MaxShapes); + TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z; + TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z; + + // Computing of CentreOfMass + Standard_Integer Index; + GProp_GProps GPr; + gp_Pnt GPoint; + TopTools_ListIteratorOfListOfShape it(SL); + for (Index=1; it.More(); Index++) + { + TopoDS_Shape S = it.Value(); + SL.Remove( it ); // == it.Next() + aShapes(Index) = S; + OrderInd.SetValue (Index, Index); + if (S.ShapeType() == TopAbs_VERTEX) { + GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S )); + Length.SetValue( Index, (Standard_Real) S.Orientation()); + } + else { + // BEGIN: fix for Mantis issue 0020842 + if (isOldSorting) { + BRepGProp::LinearProperties (S, GPr); + } + else { + if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) { + BRepGProp::LinearProperties (S, GPr); + } + else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) { + BRepGProp::SurfaceProperties(S, GPr); + } + else { + BRepGProp::VolumeProperties(S, GPr); + } + } + // END: fix for Mantis issue 0020842 + GPoint = GPr.CentreOfMass(); + Length.SetValue(Index, GPr.Mass()); + } + MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9); + //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl; + } + + // Sorting + Standard_Integer aTemp; + Standard_Boolean exchange, Sort = Standard_True; + Standard_Real tol = Precision::Confusion(); + while (Sort) + { + Sort = Standard_False; + for (Index=1; Index < MaxShapes; Index++) + { + exchange = Standard_False; + Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1)); + Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1)); + if ( dMidXYZ >= tol ) { +// cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <= tol ) { +// cout << "Length: " << Length(OrderInd(Index))<< " > " <= tol ) { +// cout << "SquareExtent: " << box1.SquareExtent()<<" > "< val2; + if ((val1 - val2) >= tol) { + exchange = Standard_True; + } + //cout << "box: " << val1<<" > "< + +#include + +#include + +#include +#include + +#include + +#include + +inline Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2) +{ + return S1.IsSame(S2); +} + +class GEOMUtils { + + public: + /*! + * \brief Get Local Coordinate System, corresponding to the given shape. + * + * Origin of the LCS is situated at the shape's center of mass. + * Axes of the LCS are obtained from shape's location or, + * if the shape is a planar face, from position of its plane. + */ + Standard_EXPORT static gp_Ax3 GetPosition (const TopoDS_Shape& theShape); + + /*! + * \brief Get vector, defined by the given edge. + */ + Standard_EXPORT static gp_Vec GetVector (const TopoDS_Shape& theShape); + + /*! + * \brief Sort shapes in the list by their coordinates. + * \param SL The list of shapes to sort. + */ + struct CompareShapes : public std::binary_function + { + CompareShapes (bool isOldSorting) + : myIsOldSorting(isOldSorting) {} + + bool operator() (const TopoDS_Shape& lhs, const TopoDS_Shape& rhs); + + typedef NCollection_DataMap > GEOMUtils_DataMapOfShapeDouble; + GEOMUtils_DataMapOfShapeDouble myMap; + bool myIsOldSorting; + }; + + /*! + * \brief Sort shapes by their centers of mass, using formula X*999 + Y*99 + Z*0.9 + */ + Standard_EXPORT static void SortShapes (TopTools_ListOfShape& SL, + const Standard_Boolean isOldSorting = Standard_True); + + /*! + * \brief Convert TopoDS_COMPSOLID to TopoDS_COMPOUND. + * + * If the argument shape is not of type TopoDS_COMPSOLID, this method returns it as is. + * + * \param theCompsolid The compsolid to be converted. + * \retval TopoDS_Shape Returns the resulting compound. + */ + Standard_EXPORT static TopoDS_Shape CompsolidToCompound (const TopoDS_Shape& theCompsolid); + + /*! + * \brief Build a triangulation on \a theShape if it is absent. + * \param theShape The shape to check/build triangulation on. + * \retval bool Returns false if the shape has no faces, i.e. impossible to build triangulation. + */ + Standard_EXPORT static bool CheckTriangulation (const TopoDS_Shape& theShape); + + /*! + * \brief Return type of shape for explode. In case of compound it will be a type of its first sub shape. + * \param theShape The shape to get type of. + * \retval TopAbs_ShapeEnum Return type of shape for explode. + */ + Standard_EXPORT static TopAbs_ShapeEnum GetTypeOfSimplePart (const TopoDS_Shape& theShape); + +}; + +#endif diff --git a/src/GEOMUtils/Makefile.am b/src/GEOMUtils/Makefile.am new file mode 100644 index 000000000..844ac94f2 --- /dev/null +++ b/src/GEOMUtils/Makefile.am @@ -0,0 +1,57 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# 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. +# +# 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com + +# GEOMUtils : implementaion of some common methods for GEOMImpl package +# File : Makefile.am +# Author : Julia DOROVSKIKH + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +# Libraries targets +lib_LTLIBRARIES = libGEOMUtils.la + +# header files +salomeinclude_HEADERS = \ + GEOMUtils.hxx + +dist_libGEOMUtils_la_SOURCES = \ + GEOMUtils.cxx + +# additional information to compile and link file + +libGEOMUtils_la_CPPFLAGS = \ + $(CAS_CPPFLAGS) \ + $(KERNEL_CXXFLAGS) \ + $(BOOST_CPPFLAGS) \ + -I$(srcdir)/../ShHealOper \ + -I$(srcdir)/../NMTDS \ + -I$(srcdir)/../NMTTools \ + -I$(srcdir)/../BlockFix \ + -I$(srcdir)/../GEOMAlgo \ + -I$(srcdir)/../SKETCHER \ + -I$(srcdir)/../ARCHIMEDE + +libGEOMUtils_la_LDFLAGS = \ + ../BlockFix/libBlockFix.la \ + ../GEOMAlgo/libGEOMAlgo.la \ + ../ShHealOper/libShHealOper.la \ + ../ARCHIMEDE/libGEOMArchimede.la \ + ../SKETCHER/libGEOMSketcher.la \ + $(KERNEL_LDFLAGS) -lSALOMELocalTrace -lSALOMEBasics \ + $(CAS_LDPATH) -lTKCAF -lTKFillet -lTKOffset -lTKFeat \ + $(STDLIB) diff --git a/src/GEOM_I/GEOM_Gen_i.cc b/src/GEOM_I/GEOM_Gen_i.cc index 3dec74459..b034757f7 100644 --- a/src/GEOM_I/GEOM_Gen_i.cc +++ b/src/GEOM_I/GEOM_Gen_i.cc @@ -61,7 +61,7 @@ #include #include -#include "SALOMEDS_Tool.hxx" +#include //============================================================================ // function : GEOM_Gen_i() @@ -577,9 +577,6 @@ CORBA::Boolean GEOM_Gen_i::Load(SALOMEDS::SComponent_ptr theComponent, // Remove the created file and tmp directory if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true); - SALOMEDS::Study_var Study = theComponent->GetStudy(); - TCollection_AsciiString name (Study->Name()); - return true; } @@ -968,6 +965,9 @@ GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapes(SALOMEDS::Study_ptr theStudy, GEOM::GEOM_IGroupOperations_var aGroupOp = GetIGroupOperations(theStudy->StudyId()); GEOM::GEOM_ITransformOperations_var aTrsfOp = GetITransformOperations(theStudy->StudyId()); + PortableServer::Servant aServant = _poa->reference_to_servant(aTrsfOp.in()); + GEOM_ITransformOperations_i* aTrsfOpSv = dynamic_cast(aServant); + // Reconstruct arguments and tree of sub-shapes of the arguments CORBA::String_var anIOR; SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder(); @@ -998,7 +998,7 @@ GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapes(SALOMEDS::Study_ptr theStudy, case GEOM::FSM_MultiTransformed: { // Only for Multi-transformations - GEOM::GEOM_Object_var anArgOTrsf = aTrsfOp->TransformLikeOtherCopy(anArgO, theObject); + GEOM::GEOM_Object_var anArgOTrsf = aTrsfOpSv->TransformLikeOtherCopy(anArgO, theObject); if (!CORBA::is_nil(anArgOTrsf)) { CORBA::String_var anArgOTrsfEntry = anArgOTrsf->GetEntry(); Handle(GEOM_Object) anArgOTrsfImpl = _impl->GetObject(anArgOTrsf->GetStudyID(), anArgOTrsfEntry); @@ -1020,7 +1020,7 @@ GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapes(SALOMEDS::Study_ptr theStudy, { GEOMImpl_ITranslate aTI (anOFun); aMultiArgShape = GEOMImpl_ITransformOperations::TranslateShape1D(anArgOShape, &aTI); - //anArgOMulti = aTrsfOp->Translate1D(anArgO, , , ); + //anArgOMulti = aTrsfOpSv->Translate1D(anArgO, , , ); } break; case TRANSLATE_2D: @@ -1284,6 +1284,9 @@ GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesOneLevel (SALOMEDS::Study_ptr th GEOM::GEOM_IGroupOperations_var aGroupOp = GetIGroupOperations(theStudy->StudyId()); GEOM::GEOM_ITransformOperations_var aTrsfOp = GetITransformOperations(theStudy->StudyId()); + PortableServer::Servant aServant = _poa->reference_to_servant(aTrsfOp.in()); + GEOM_ITransformOperations_i* aTrsfOpSv = dynamic_cast(aServant); + // Reconstruct published sub-shapes SALOMEDS::ChildIterator_var it = theStudy->NewChildIterator(theOldSO); @@ -1316,7 +1319,7 @@ GEOM::ListOfGO* GEOM_Gen_i::RestoreSubShapesOneLevel (SALOMEDS::Study_ptr th case GEOM::FSM_MultiTransformed: { // Only for Multi-transformations - GEOM::GEOM_Object_var anArgOTrsf = aTrsfOp->TransformLikeOtherCopy(anOldSubO, theNewO); + GEOM::GEOM_Object_var anArgOTrsf = aTrsfOpSv->TransformLikeOtherCopy(anOldSubO, theNewO); if (!CORBA::is_nil(anArgOTrsf)) { CORBA::String_var anArgOTrsfEntry = anArgOTrsf->GetEntry(); Handle(GEOM_Object) anArgOTrsfImpl = _impl->GetObject(anArgOTrsf->GetStudyID(), anArgOTrsfEntry); @@ -1559,6 +1562,9 @@ GEOM::ListOfGO* GEOM_Gen_i::RestoreGivenSubShapes(SALOMEDS::Study_ptr theStu GEOM::GEOM_IGroupOperations_var aGroupOp = GetIGroupOperations(theStudy->StudyId()); GEOM::GEOM_ITransformOperations_var aTrsfOp = GetITransformOperations(theStudy->StudyId()); + PortableServer::Servant aServant = _poa->reference_to_servant(aTrsfOp.in()); + GEOM_ITransformOperations_i* aTrsfOpSv = dynamic_cast(aServant); + // Reconstruct arguments and tree of sub-shapes of the arguments CORBA::String_var anIOR; SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder(); @@ -1589,7 +1595,7 @@ GEOM::ListOfGO* GEOM_Gen_i::RestoreGivenSubShapes(SALOMEDS::Study_ptr theStu case GEOM::FSM_MultiTransformed: { // Only for Multi-transformations - GEOM::GEOM_Object_var anArgOTrsf = aTrsfOp->TransformLikeOtherCopy(anArgO, theObject); + GEOM::GEOM_Object_var anArgOTrsf = aTrsfOpSv->TransformLikeOtherCopy(anArgO, theObject); if (!CORBA::is_nil(anArgOTrsf)) { CORBA::String_var anArgOTrsfEntry = anArgOTrsf->GetEntry(); Handle(GEOM_Object) anArgOTrsfImpl = _impl->GetObject(anArgOTrsf->GetStudyID(), anArgOTrsfEntry); @@ -1822,6 +1828,9 @@ GEOM::ListOfGO* GEOM_Gen_i::RestoreGivenSubShapesOneLevel (SALOMEDS::Study_ptr GEOM::GEOM_IGroupOperations_var aGroupOp = GetIGroupOperations(theStudy->StudyId()); GEOM::GEOM_ITransformOperations_var aTrsfOp = GetITransformOperations(theStudy->StudyId()); + PortableServer::Servant aServant = _poa->reference_to_servant(aTrsfOp.in()); + GEOM_ITransformOperations_i* aTrsfOpSv = dynamic_cast(aServant); + // Reconstruct published sub-shapes SALOMEDS::ChildIterator_var it = theStudy->NewChildIterator(theOldSO); @@ -1862,7 +1871,7 @@ GEOM::ListOfGO* GEOM_Gen_i::RestoreGivenSubShapesOneLevel (SALOMEDS::Study_ptr case GEOM::FSM_MultiTransformed: { // Only for Multi-transformations - GEOM::GEOM_Object_var anArgOTrsf = aTrsfOp->TransformLikeOtherCopy(anOldSubO, theNewO); + GEOM::GEOM_Object_var anArgOTrsf = aTrsfOpSv->TransformLikeOtherCopy(anOldSubO, theNewO); if (!CORBA::is_nil(anArgOTrsf)) { CORBA::String_var anArgOTrsfEntry = anArgOTrsf->GetEntry(); Handle(GEOM_Object) anArgOTrsfImpl = _impl->GetObject(anArgOTrsf->GetStudyID(), anArgOTrsfEntry); diff --git a/src/GEOM_I/GEOM_ICurvesOperations_i.cc b/src/GEOM_I/GEOM_ICurvesOperations_i.cc index 3f1a67800..88e381681 100644 --- a/src/GEOM_I/GEOM_ICurvesOperations_i.cc +++ b/src/GEOM_I/GEOM_ICurvesOperations_i.cc @@ -427,6 +427,46 @@ GEOM::GEOM_Object_ptr GEOM_ICurvesOperations_i::MakeSplineInterpolation return GetObject(anObject); } +//============================================================================= +/*! + * MakeSplineInterpolWithTangents + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_ICurvesOperations_i::MakeSplineInterpolWithTangents + (const GEOM::ListOfGO& thePoints, + GEOM::GEOM_Object_ptr theFirstVec, + GEOM::GEOM_Object_ptr theLastVec) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference points + int ind = 0; + int aLen = thePoints.length(); + std::list aPoints; + for (; ind < aLen; ind++) { + Handle(GEOM_Object) aPnt = GetObjectImpl(thePoints[ind]); + if (aPnt.IsNull()) return aGEOMObject._retn(); + aPoints.push_back(aPnt); + } + + //Get the reference vectors + Handle(GEOM_Object) aVec1 = GetObjectImpl(theFirstVec); + Handle(GEOM_Object) aVec2 = GetObjectImpl(theLastVec); + + if (aVec1.IsNull() || aVec2.IsNull()) return aGEOMObject._retn(); + + // Make Polyline + Handle(GEOM_Object) anObject = + GetOperations()->MakeSplineInterpolWithTangents(aPoints, aVec1, aVec2); + if (!GetOperations()->IsDone() || anObject.IsNull()) + return aGEOMObject._retn(); + + return GetObject(anObject); +} + //============================================================================= /*! * MakeCurveParametric diff --git a/src/GEOM_I/GEOM_ICurvesOperations_i.hh b/src/GEOM_I/GEOM_ICurvesOperations_i.hh index e50ab2111..07f4ce2a0 100644 --- a/src/GEOM_I/GEOM_ICurvesOperations_i.hh +++ b/src/GEOM_I/GEOM_ICurvesOperations_i.hh @@ -85,6 +85,10 @@ class GEOM_I_EXPORT GEOM_ICurvesOperations_i : CORBA::Boolean theIsClosed, CORBA::Boolean theDoReordering); + GEOM::GEOM_Object_ptr MakeSplineInterpolWithTangents (const GEOM::ListOfGO& thePoints, + GEOM::GEOM_Object_ptr theFirstVec, + GEOM::GEOM_Object_ptr theLastVec); + GEOM::GEOM_Object_ptr MakeCurveParametric (const char* thexExpr, const char* theyExpr, const char* thezExpr, double theParamMin, double theParamMax, double theParamStep, diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.cc b/src/GEOM_I/GEOM_IMeasureOperations_i.cc index ffbdcd5d4..b6132132c 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.cc +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.cc @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -273,6 +272,31 @@ void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape, GetOperations()->GetBoundingBox(aShape, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax); } +//============================================================================= +/*! + * MakeBoundingBox + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::MakeBoundingBox + (GEOM::GEOM_Object_ptr theShape) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference shape + Handle(GEOM_Object) aShape = GetObjectImpl(theShape); + if (aShape.IsNull()) return aGEOMObject._retn(); + + // Make Box - bounding box of theShape + Handle(GEOM_Object) anObject = GetOperations()->GetBoundingBox(aShape); + if (!GetOperations()->IsDone() || anObject.IsNull()) + return aGEOMObject._retn(); + + return GetObject(anObject); +} + //============================================================================= /*! * GetTolerance @@ -494,6 +518,41 @@ CORBA::Double GEOM_IMeasureOperations_i::GetMinDistance return GetOperations()->GetMinDistance(aShape1, aShape2, X1, Y1, Z1, X2, Y2, Z2); } +//============================================================================= +/*! + * ClosestPoints + */ +//============================================================================= +CORBA::Long GEOM_IMeasureOperations_i::ClosestPoints + (GEOM::GEOM_Object_ptr theShape1, GEOM::GEOM_Object_ptr theShape2, + GEOM::ListOfDouble_out theCoords) +{ + //Set a not done flag + GetOperations()->SetNotDone(); + + // allocate the CORBA array + int nbSols = 0; + GEOM::ListOfDouble_var aDoublesArray = new GEOM::ListOfDouble(); + + //Get the reference shape + Handle(GEOM_Object) aShape1 = GetObjectImpl(theShape1); + Handle(GEOM_Object) aShape2 = GetObjectImpl(theShape2); + + if (!aShape1.IsNull() && !aShape2.IsNull()) { + Handle(TColStd_HSequenceOfReal) aDoubles = new TColStd_HSequenceOfReal; + // Get shape parameters + nbSols = GetOperations()->ClosestPoints(aShape1, aShape2, aDoubles); + int nbDbls = aDoubles->Length(); + aDoublesArray->length(nbDbls); + for (int id = 0; id < nbDbls; id++) { + aDoublesArray[id] = aDoubles->Value(id + 1); + } + } + + theCoords = aDoublesArray._retn(); + return nbSols; +} + //============================================================================= /*! * PointCoordinates diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.hh b/src/GEOM_I/GEOM_IMeasureOperations_i.hh index 4534dc45e..e8269bd22 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.hh +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.hh @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #ifndef _GEOM_IMeasureOperations_i_HeaderFile #define _GEOM_IMeasureOperations_i_HeaderFile @@ -75,6 +74,8 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i : CORBA::Double& Ymin, CORBA::Double& Ymax, CORBA::Double& Zmin, CORBA::Double& Zmax); + GEOM::GEOM_Object_ptr MakeBoundingBox (GEOM::GEOM_Object_ptr theShape); + void GetTolerance (GEOM::GEOM_Object_ptr theShape, CORBA::Double& FaceMin, CORBA::Double& FaceMax, CORBA::Double& EdgeMin, CORBA::Double& EdgeMax, @@ -102,6 +103,10 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i : CORBA::Double& X1, CORBA::Double& Y1, CORBA::Double& Z1, CORBA::Double& X2, CORBA::Double& Y2, CORBA::Double& Z2); + CORBA::Long ClosestPoints (GEOM::GEOM_Object_ptr theShape1, + GEOM::GEOM_Object_ptr theShape2, + GEOM::ListOfDouble_out theCoords); + void PointCoordinates (GEOM::GEOM_Object_ptr theShape, CORBA::Double& X, CORBA::Double& Y, CORBA::Double& Z); diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.cc b/src/GEOM_I/GEOM_IShapesOperations_i.cc index cee18553c..cd3aac8aa 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.cc +++ b/src/GEOM_I/GEOM_IShapesOperations_i.cc @@ -831,6 +831,49 @@ CORBA::Long GEOM_IShapesOperations_i::GetSubShapeIndex return anID; } +//============================================================================= +/*! + * GetSubShapesIndices + */ +//============================================================================= +GEOM::ListOfLong* GEOM_IShapesOperations_i::GetSubShapesIndices + (GEOM::GEOM_Object_ptr theMainShape, const GEOM::ListOfGO& theSubShapes) +{ + GEOM::ListOfLong_var aSeq = new GEOM::ListOfLong; + + //Get the reference main shape + Handle(GEOM_Object) aMainShapeRef = GetObjectImpl(theMainShape); + if (aMainShapeRef.IsNull()) return aSeq._retn(); + + //Get the subshapes + std::list aShapes; + int aLen = theSubShapes.length(); + for (int ind = 0; ind < aLen; ind++) { + Handle(GEOM_Object) aSh = GetObjectImpl(theSubShapes[ind]); + if (aSh.IsNull()) + { + MESSAGE("NULL shape") + return aSeq._retn(); + } + aShapes.push_back(aSh); + } + + //Get the IDs of inside + Handle(TColStd_HSequenceOfInteger) aHSeq = + GetOperations()->GetSubShapesIndices(aMainShapeRef, aShapes); + + if (!GetOperations()->IsDone() || aHSeq.IsNull()) return aSeq._retn(); + + Standard_Integer aLength = aHSeq->Length(); + aSeq->length(aLength); + + for (Standard_Integer i = 1; i <= aLength; i++) + aSeq[i-1] = aHSeq->Value(i); + + return aSeq._retn(); +} + + //============================================================================= /*! * GetTopologyIndex diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.hh b/src/GEOM_I/GEOM_IShapesOperations_i.hh index c01b6317e..41def03a9 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.hh +++ b/src/GEOM_I/GEOM_IShapesOperations_i.hh @@ -128,6 +128,9 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i : CORBA::Long GetSubShapeIndex (GEOM::GEOM_Object_ptr theMainShape, GEOM::GEOM_Object_ptr theSubShape); + + GEOM::ListOfLong* GetSubShapesIndices (GEOM::GEOM_Object_ptr theMainShape, + const GEOM::ListOfGO& theSubShapes); CORBA::Long GetTopologyIndex (GEOM::GEOM_Object_ptr theMainShape, GEOM::GEOM_Object_ptr theSubShape); diff --git a/src/GEOM_I/GEOM_ITransformOperations_i.cc b/src/GEOM_I/GEOM_ITransformOperations_i.cc index 59bc4a293..05b132959 100644 --- a/src/GEOM_I/GEOM_ITransformOperations_i.cc +++ b/src/GEOM_I/GEOM_ITransformOperations_i.cc @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -958,7 +957,7 @@ GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::MultiTranslate1D //Get the vector of translation Handle(GEOM_Object) aVector = GetObjectImpl(theVector); - if (aVector.IsNull()) return aGEOMObject._retn(); + //if (aVector.IsNull()) return aGEOMObject._retn(); // DX by default //Perform the translation Handle(GEOM_Object) anObject = @@ -992,11 +991,11 @@ GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::MultiTranslate2D (GEOM::GEOM_ //Get the vector1 of translation Handle(GEOM_Object) aVector1 = GetObjectImpl(theVector1); - if (aVector1.IsNull()) return aGEOMObject._retn(); + //if (aVector1.IsNull()) return aGEOMObject._retn(); // DX by default //Get the vector2 of translation Handle(GEOM_Object) aVector2 = GetObjectImpl(theVector2); - if (aVector2.IsNull()) return aGEOMObject._retn(); + //if (aVector2.IsNull()) return aGEOMObject._retn(); // DY by default //Perform the translation Handle(GEOM_Object) anObject = GetOperations()->Translate2D @@ -1026,7 +1025,7 @@ GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::MultiRotate1D (GEOM::GEOM_Obj //Get the a directon of rotation Handle(GEOM_Object) aVector = GetObjectImpl(theVector); - if (aVector.IsNull()) return aGEOMObject._retn(); + //if (aVector.IsNull()) return aGEOMObject._retn(); // DZ by default //Perform the rotation Handle(GEOM_Object) anObject = GetOperations()->Rotate1D(aBasicObject, aVector, theNbTimes); @@ -1035,6 +1034,101 @@ GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::MultiRotate1D (GEOM::GEOM_Obj return GetObject(anObject); } +//============================================================================= +/*! + * MultiRotate1DByStep + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::MultiRotate1DByStep (GEOM::GEOM_Object_ptr theObject, + GEOM::GEOM_Object_ptr theVector, + CORBA::Double theAngleStep, + CORBA::Long theNbSteps) +{ + //Set a not done flag + GetOperations()->SetNotDone(); + + GEOM::GEOM_Object_var aGEOMObject; + + //Get the object itself + Handle(GEOM_Object) aBasicObject = GetObjectImpl(theObject); + if (aBasicObject.IsNull()) return aGEOMObject._retn(); + + //Get the a directon of rotation + Handle(GEOM_Object) aVector = GetObjectImpl(theVector); + //if (aVector.IsNull()) return aGEOMObject._retn(); // DZ by default + + //Perform the rotation + Handle(GEOM_Object) anObject = GetOperations()->Rotate1D(aBasicObject, aVector, theAngleStep, theNbSteps); + if (!GetOperations()->IsDone() || anObject.IsNull()) return aGEOMObject._retn(); + + return GetObject(anObject); +} + +//============================================================================= +/*! + * MultiRotate2DNbTimes + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::MultiRotate2DNbTimes (GEOM::GEOM_Object_ptr theObject, + GEOM::GEOM_Object_ptr theVector, + CORBA::Long theNbObjects, + CORBA::Double theRadialStep, + CORBA::Long theNbSteps) +{ + //Set a not done flag + GetOperations()->SetNotDone(); + + GEOM::GEOM_Object_var aGEOMObject; + + //Get the object itself + Handle(GEOM_Object) aBasicObject = GetObjectImpl(theObject); + if (aBasicObject.IsNull()) return aGEOMObject._retn(); + + //Get the a directon of rotation + Handle(GEOM_Object) aVector = GetObjectImpl(theVector); + //if (aVector.IsNull()) return aGEOMObject._retn(); // DZ by default + + //Perform the rotation + Handle(GEOM_Object) anObject = GetOperations()->Rotate2D + (aBasicObject, aVector, theNbObjects, theRadialStep, theNbSteps); + if (!GetOperations()->IsDone() || anObject.IsNull()) return aGEOMObject._retn(); + + return GetObject(anObject); +} + +//============================================================================= +/*! + * MultiRotate2DByStep + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::MultiRotate2DByStep (GEOM::GEOM_Object_ptr theObject, + GEOM::GEOM_Object_ptr theVector, + CORBA::Double theAngle, + CORBA::Long theNbTimes1, + CORBA::Double theStep, + CORBA::Long theNbTimes2) +{ + //Set a not done flag + GetOperations()->SetNotDone(); + + GEOM::GEOM_Object_var aGEOMObject; + + //Get the object itself + Handle(GEOM_Object) aBasicObject = GetObjectImpl(theObject); + if (aBasicObject.IsNull()) return aGEOMObject._retn(); + + //Get the a directon of rotation + Handle(GEOM_Object) aVector = GetObjectImpl(theVector); + //if (aVector.IsNull()) return aGEOMObject._retn(); // DZ by default + + //Perform the rotation + Handle(GEOM_Object) anObject = GetOperations()->Rotate2D + (aBasicObject, aVector, theAngle, theNbTimes1, theStep, theNbTimes2); + if (!GetOperations()->IsDone() || anObject.IsNull()) return aGEOMObject._retn(); + + return GetObject(anObject); +} + //============================================================================= /*! * MultiRotate2D @@ -1058,11 +1152,13 @@ GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::MultiRotate2D (GEOM::GEOM_Obj //Get the a directon of rotation Handle(GEOM_Object) aVector = GetObjectImpl(theVector); - if (aVector.IsNull()) return aGEOMObject._retn(); + //if (aVector.IsNull()) return aGEOMObject._retn(); // DZ by default + + double anAngle = M_PI * theAngle / 180.; //Perform the rotation Handle(GEOM_Object) anObject = GetOperations()->Rotate2D - (aBasicObject, aVector, theAngle, theNbTimes1, theStep, theNbTimes2); + (aBasicObject, aVector, anAngle, theNbTimes1, theStep, theNbTimes2); if (!GetOperations()->IsDone() || anObject.IsNull()) return aGEOMObject._retn(); return GetObject(anObject); diff --git a/src/GEOM_I/GEOM_ITransformOperations_i.hh b/src/GEOM_I/GEOM_ITransformOperations_i.hh index f01f08c22..7f7964ce4 100644 --- a/src/GEOM_I/GEOM_ITransformOperations_i.hh +++ b/src/GEOM_I/GEOM_ITransformOperations_i.hh @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #ifndef _GEOM_ITransformOperations_i_HeaderFile #define _GEOM_ITransformOperations_i_HeaderFile @@ -39,17 +38,17 @@ class GEOM_I_EXPORT GEOM_ITransformOperations_i : { public: GEOM_ITransformOperations_i (PortableServer::POA_ptr thePOA, - GEOM::GEOM_Gen_ptr theEngine, - ::GEOMImpl_ITransformOperations* theImpl); + GEOM::GEOM_Gen_ptr theEngine, + ::GEOMImpl_ITransformOperations* theImpl); ~GEOM_ITransformOperations_i(); GEOM::GEOM_Object_ptr TranslateTwoPoints (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr thePoint1, - GEOM::GEOM_Object_ptr thePoint2); + GEOM::GEOM_Object_ptr thePoint1, + GEOM::GEOM_Object_ptr thePoint2); GEOM::GEOM_Object_ptr TranslateTwoPointsCopy (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr thePoint1, - GEOM::GEOM_Object_ptr thePoint2); + GEOM::GEOM_Object_ptr thePoint1, + GEOM::GEOM_Object_ptr thePoint2); GEOM::GEOM_Object_ptr TranslateDXDYDZ (GEOM::GEOM_Object_ptr theObject, CORBA::Double theDX, CORBA::Double theDY, CORBA::Double theDZ); @@ -59,15 +58,15 @@ class GEOM_I_EXPORT GEOM_ITransformOperations_i : CORBA::Double theDX, CORBA::Double theDY, CORBA::Double theDZ); GEOM::GEOM_Object_ptr TranslateVector (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr theVector); + GEOM::GEOM_Object_ptr theVector); GEOM::GEOM_Object_ptr TranslateVectorCopy (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr theVector); + GEOM::GEOM_Object_ptr theVector); GEOM::GEOM_Object_ptr TranslateVectorDistance (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr theVector, - CORBA::Double theDistance, - CORBA::Boolean theCopy); + GEOM::GEOM_Object_ptr theVector, + CORBA::Double theDistance, + CORBA::Boolean theCopy); GEOM::GEOM_Object_ptr MultiTranslate1D (GEOM::GEOM_Object_ptr theObject, GEOM::GEOM_Object_ptr theVector, @@ -81,93 +80,111 @@ class GEOM_I_EXPORT GEOM_ITransformOperations_i : GEOM::GEOM_Object_ptr Rotate (GEOM::GEOM_Object_ptr theObject, GEOM::GEOM_Object_ptr theAxis, - CORBA::Double theAngle); + CORBA::Double theAngle); GEOM::GEOM_Object_ptr MultiRotate1D (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr theVector, - CORBA::Long theNbTimes); - + GEOM::GEOM_Object_ptr theVector, + CORBA::Long theNbTimes); + + GEOM::GEOM_Object_ptr MultiRotate1DByStep (GEOM::GEOM_Object_ptr theObject, + GEOM::GEOM_Object_ptr theAxis, + CORBA::Double theAngleStep, + CORBA::Long theNbSteps); + + GEOM::GEOM_Object_ptr MultiRotate2DNbTimes (GEOM::GEOM_Object_ptr theObject, + GEOM::GEOM_Object_ptr theAxis, + CORBA::Long theNbObjects, + CORBA::Double theRadialStep, + CORBA::Long theNbSteps); + + GEOM::GEOM_Object_ptr MultiRotate2DByStep (GEOM::GEOM_Object_ptr theObject, + GEOM::GEOM_Object_ptr theVector, + CORBA::Double theAngle, + CORBA::Long theNbTimes1, + CORBA::Double theStep, + CORBA::Long theNbTimes2); + GEOM::GEOM_Object_ptr MultiRotate2D (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr theVector, - CORBA::Double theAngle, - CORBA::Long theNbTimes1, - CORBA::Double theStep, - CORBA::Long theNbTimes2); - + GEOM::GEOM_Object_ptr theVector, + CORBA::Double theAngle, + CORBA::Long theNbTimes1, + CORBA::Double theStep, + CORBA::Long theNbTimes2); + GEOM::GEOM_Object_ptr RotateCopy (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr theAxis, - CORBA::Double theAngle); + GEOM::GEOM_Object_ptr theAxis, + CORBA::Double theAngle); GEOM::GEOM_Object_ptr MirrorPlane (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr thePlane); + GEOM::GEOM_Object_ptr thePlane); GEOM::GEOM_Object_ptr MirrorPlaneCopy (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr thePlane); + GEOM::GEOM_Object_ptr thePlane); GEOM::GEOM_Object_ptr MirrorAxis (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr theAxis); + GEOM::GEOM_Object_ptr theAxis); GEOM::GEOM_Object_ptr MirrorAxisCopy (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr theAxis); + GEOM::GEOM_Object_ptr theAxis); GEOM::GEOM_Object_ptr MirrorPoint (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr thePoint); + GEOM::GEOM_Object_ptr thePoint); GEOM::GEOM_Object_ptr MirrorPointCopy (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr thePoint); + GEOM::GEOM_Object_ptr thePoint); GEOM::GEOM_Object_ptr OffsetShape (GEOM::GEOM_Object_ptr theObject, - CORBA::Double theOffset); + CORBA::Double theOffset); GEOM::GEOM_Object_ptr OffsetShapeCopy (GEOM::GEOM_Object_ptr theObject, - CORBA::Double theOffset); + CORBA::Double theOffset); GEOM::GEOM_Object_ptr ProjectShapeCopy (GEOM::GEOM_Object_ptr theSource, GEOM::GEOM_Object_ptr theTarget); GEOM::GEOM_Object_ptr ScaleShape (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr thePoint, - CORBA::Double theFactor); + GEOM::GEOM_Object_ptr thePoint, + CORBA::Double theFactor); GEOM::GEOM_Object_ptr ScaleShapeCopy (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr thePoint, - CORBA::Double theFactor); + GEOM::GEOM_Object_ptr thePoint, + CORBA::Double theFactor); GEOM::GEOM_Object_ptr ScaleShapeAlongAxes (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr thePoint, - CORBA::Double theFactorX, - CORBA::Double theFactorY, - CORBA::Double theFactorZ); + GEOM::GEOM_Object_ptr thePoint, + CORBA::Double theFactorX, + CORBA::Double theFactorY, + CORBA::Double theFactorZ); GEOM::GEOM_Object_ptr ScaleShapeAlongAxesCopy (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr thePoint, - CORBA::Double theFactorX, - CORBA::Double theFactorY, - CORBA::Double theFactorZ); + GEOM::GEOM_Object_ptr thePoint, + CORBA::Double theFactorX, + CORBA::Double theFactorY, + CORBA::Double theFactorZ); GEOM::GEOM_Object_ptr PositionShape (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr theStartLCS, - GEOM::GEOM_Object_ptr theEndLCS); + GEOM::GEOM_Object_ptr theStartLCS, + GEOM::GEOM_Object_ptr theEndLCS); GEOM::GEOM_Object_ptr PositionShapeCopy (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr theStartLCS, - GEOM::GEOM_Object_ptr theEndLCS); + GEOM::GEOM_Object_ptr theStartLCS, + GEOM::GEOM_Object_ptr theEndLCS); GEOM::GEOM_Object_ptr PositionAlongPath (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr thePath, - CORBA::Double theDistance, - CORBA::Boolean theCopy, - CORBA::Boolean theReverse); + GEOM::GEOM_Object_ptr thePath, + CORBA::Double theDistance, + CORBA::Boolean theCopy, + CORBA::Boolean theReverse); GEOM::GEOM_Object_ptr RotateThreePoints (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr theCentPoint, - GEOM::GEOM_Object_ptr thePoint1, - GEOM::GEOM_Object_ptr thePoint2); + GEOM::GEOM_Object_ptr theCentPoint, + GEOM::GEOM_Object_ptr thePoint1, + GEOM::GEOM_Object_ptr thePoint2); GEOM::GEOM_Object_ptr RotateThreePointsCopy (GEOM::GEOM_Object_ptr theObject, - GEOM::GEOM_Object_ptr theCentPoint, - GEOM::GEOM_Object_ptr thePoint1, - GEOM::GEOM_Object_ptr thePoint2); + GEOM::GEOM_Object_ptr theCentPoint, + GEOM::GEOM_Object_ptr thePoint1, + GEOM::GEOM_Object_ptr thePoint2); GEOM::GEOM_Object_ptr TransformLikeOtherCopy (GEOM::GEOM_Object_ptr theObject, GEOM::GEOM_Object_ptr theSample); diff --git a/src/GEOM_I/GEOM_Object_i.cc b/src/GEOM_I/GEOM_Object_i.cc index bc8afb0f9..649e2fa2e 100644 --- a/src/GEOM_I/GEOM_Object_i.cc +++ b/src/GEOM_I/GEOM_Object_i.cc @@ -206,7 +206,7 @@ char* GEOM_Object_i::GetName() char* aName = _impl->GetName(); if (aName) return aName; // this is already copy of pointer (see implementation of _impl) - return strdup(""); + return CORBA::string_dup(""); } //============================================================================= diff --git a/src/GEOM_I/GEOM_wrap.hxx b/src/GEOM_I/GEOM_wrap.hxx new file mode 100644 index 000000000..71fbbf773 --- /dev/null +++ b/src/GEOM_I/GEOM_wrap.hxx @@ -0,0 +1,59 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : GEOM_wrap.hxx +// Created : Mon Dec 24 14:39:49 2012 +// Author : Edward AGAPOV (eap) + + +#ifndef __GEOM_wrap_HXX__ +#define __GEOM_wrap_HXX__ + +#include + +namespace GEOM +{ + // Declare a type GEOM::GEOM_Object_wrap to replace GEOM::GEOM_Object_var, + // to be used in the case if a new GEOM_Object is received, in which case + // obj->UnRegister() must be called to avoid a memory leak. + // The GEOM::GEOM_Object_wrap object calls UnRegister() at destruction. + // A simple rule: use GEOM::GEOM_Object_wrap if an object is returned by a + // GEOM operation (GEOM::GEOM_IBasicOperations etc). + // + typedef SALOME::GenericObj_wrap< GEOM_Object > GEOM_Object_wrap; + // + // wrappers of operations + typedef SALOME::GenericObj_wrap< GEOM_IBasicOperations > GEOM_IBasicOperations_wrap; + typedef SALOME::GenericObj_wrap< GEOM_ITransformOperations> GEOM_ITransformOperations_wrap; + typedef SALOME::GenericObj_wrap< GEOM_I3DPrimOperations > GEOM_I3DPrimOperations_wrap; + typedef SALOME::GenericObj_wrap< GEOM_IShapesOperations > GEOM_IShapesOperations_wrap; + typedef SALOME::GenericObj_wrap< GEOM_IBlocksOperations > GEOM_IBlocksOperations_wrap; + typedef SALOME::GenericObj_wrap< GEOM_IBooleanOperations > GEOM_IBooleanOperations_wrap; + typedef SALOME::GenericObj_wrap< GEOM_ICurvesOperations > GEOM_ICurvesOperations_wrap; + typedef SALOME::GenericObj_wrap< GEOM_ILocalOperations > GEOM_ILocalOperations_wrap; + typedef SALOME::GenericObj_wrap< GEOM_IHealingOperations > GEOM_IHealingOperations_wrap; + typedef SALOME::GenericObj_wrap< GEOM_IInsertOperations > GEOM_IInsertOperations_wrap; + typedef SALOME::GenericObj_wrap< GEOM_IMeasureOperations > GEOM_IMeasureOperations_wrap; + typedef SALOME::GenericObj_wrap< GEOM_IGroupOperations > GEOM_IGroupOperations_wrap; + typedef SALOME::GenericObj_wrap< GEOM_IAdvancedOperations > GEOM_IAdvancedOperations_wrap; +} + +#endif diff --git a/src/GEOM_I/Makefile.am b/src/GEOM_I/Makefile.am index b5cd51165..16383a10c 100644 --- a/src/GEOM_I/Makefile.am +++ b/src/GEOM_I/Makefile.am @@ -22,7 +22,6 @@ # Author : Patrick GOLDBRONN (CEA) # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : GEOM -# $Header$ include $(top_srcdir)/adm_local/unix/make_common_starter.am @@ -47,7 +46,8 @@ salomeinclude_HEADERS = \ GEOM_IGroupOperations_i.hh \ GEOM_IAdvancedOperations_i.hh \ GEOM_Gen_i.hh \ - GEOM_GEOM_I.hxx + GEOM_GEOM_I.hxx \ + GEOM_wrap.hxx dist_libGEOMEngine_la_SOURCES = \ GEOM_Object_i.cc \ diff --git a/src/GEOM_I_Superv/Makefile.am b/src/GEOM_I_Superv/Makefile.am index e24863482..ef8ef7aff 100644 --- a/src/GEOM_I_Superv/Makefile.am +++ b/src/GEOM_I_Superv/Makefile.am @@ -22,7 +22,6 @@ # Author : Patrick GOLDBRONN (CEA) # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : GEOM -# $Header$ # Libraries targets include $(top_srcdir)/adm_local/unix/make_common_starter.am diff --git a/src/GEOM_SWIG/GEOM_ObjectInfo.py b/src/GEOM_SWIG/GEOM_ObjectInfo.py index 8678a9de6..fb2ab3e15 100644 --- a/src/GEOM_SWIG/GEOM_ObjectInfo.py +++ b/src/GEOM_SWIG/GEOM_ObjectInfo.py @@ -22,7 +22,6 @@ # File : GEOM_ObjectInfo.py # Author : Michael ZORIN # Module : GEOM -# $Header: # import salome import geompy diff --git a/src/GEOM_SWIG/GEOM_Sketcher.py b/src/GEOM_SWIG/GEOM_Sketcher.py index e67172c27..ade5407af 100644 --- a/src/GEOM_SWIG/GEOM_Sketcher.py +++ b/src/GEOM_SWIG/GEOM_Sketcher.py @@ -25,7 +25,6 @@ # File : GEOM_Sketcher.py # Author : Damien COQUERET, Open CASCADE # Module : GEOM -# $Header$ # import geompy diff --git a/src/GEOM_SWIG/GEOM_TestAll.py b/src/GEOM_SWIG/GEOM_TestAll.py index 3b9381772..467463400 100644 --- a/src/GEOM_SWIG/GEOM_TestAll.py +++ b/src/GEOM_SWIG/GEOM_TestAll.py @@ -102,6 +102,8 @@ def TestAll (geompy, math): Polyline = geompy.MakePolyline([p0, pz, py, p200]) #(List of GEOM_Object)->GEOM_Object Bezier = geompy.MakeBezier([p0, pz, p200, px]) #(List of GEOM_Object)->GEOM_Object Interpol = geompy.MakeInterpol([px, py, p200, pxyz], True) #(List of GEOM_Object,Boolean)->GEOM_Object + InterpT1 = geompy.MakeInterpolWithTangents([px, py, pxyz], vx, vz) #(List of GO, GO, GO)->GEOM_Object + InterpT2 = geompy.MakeInterpolWithTangents([px, py, pxyz], vxy, vxyz) #(List of GO, GO, GO)->GEOM_Object Sketcher = geompy.MakeSketcher("Sketcher:F -100 -100:TT 250 -100:R 0:C 100 150:R 0:L 300:WW", [100,0,0, 1,1,1, -1,1,0]) #(String, List of Doubles)->GEOM_Object @@ -288,9 +290,10 @@ def TestAll (geompy, math): #Create Patterns MultiTrans1D = geompy.MakeMultiTranslation1D(Fillet, vz, step1, nbtimes1) MultiTrans2D = geompy.MakeMultiTranslation2D(Fillet, vz, step1, nbtimes1, vy, step2, nbtimes2) - #!!!!Angle In Degree!!!! - MultiRot1D = geompy.MultiRotate1D(Chamfer, vx, nbtimes1) - MultiRot2D = geompy.MultiRotate2D(Chamfer, vx, angle, nbtimes1, step1, nbtimes2) + MultiRot1Dt = geompy.MultiRotate1DNbTimes(Chamfer, vx, nbtimes1) + MultiRot1Ds = geompy.MultiRotate1DByStep(Chamfer, vx, math.pi/4., nbtimes1) + MultiRot2Dt = geompy.MultiRotate2DNbTimes(Chamfer, vx, nbtimes1, step1, nbtimes2) + MultiRot2Ds = geompy.MultiRotate2DByStep(Chamfer, vx, angle1, nbtimes1, step1, nbtimes2) #Create Informations objects CDG = geompy.MakeCDG(Prism) #(GEOM_Object)->GEOM_Object @@ -343,6 +346,8 @@ def TestAll (geompy, math): id_Polyline = geompy.addToStudy(Polyline, "Polyline") id_Bezier = geompy.addToStudy(Bezier, "Bezier") id_Interpol = geompy.addToStudy(Interpol, "Interpol") + id_InterpT1 = geompy.addToStudy(InterpT1, "InterpT1") + id_InterpT2 = geompy.addToStudy(InterpT2, "InterpT2") id_Sketcher = geompy.addToStudy(Sketcher, "Sketcher") id_Sketcher3d_1 = geompy.addToStudy(Sketcher3d_1, "Sketcher 3D by interface") @@ -462,8 +467,10 @@ def TestAll (geompy, math): id_MultiTrans1D = geompy.addToStudy(MultiTrans1D, "MultiTrans1D") id_MultiTrans2D = geompy.addToStudy(MultiTrans2D, "MultiTrans2D") - id_MultiRot1D = geompy.addToStudy(MultiRot1D, "MultiRot1D") - id_MultiRot2D = geompy.addToStudy(MultiRot2D, "MultiRot2D") + id_MultiRot1Dt = geompy.addToStudy(MultiRot1Dt, "MultiRot1D NbTimes") + id_MultiRot1Ds = geompy.addToStudy(MultiRot1Ds, "MultiRot1D ByStep") + id_MultiRot2Dt = geompy.addToStudy(MultiRot2Dt, "MultiRot2D NbTimes") + id_MultiRot2Ds = geompy.addToStudy(MultiRot2Ds, "MultiRot2D ByStep") id_CDG = geompy.addToStudy(CDG, "CDG") id_Archimede = geompy.addToStudy(Archimede, "Archimede") diff --git a/src/GEOM_SWIG/GEOM_TestMeasures.py b/src/GEOM_SWIG/GEOM_TestMeasures.py index 1621f2bf4..cd9c07dd0 100644 --- a/src/GEOM_SWIG/GEOM_TestMeasures.py +++ b/src/GEOM_SWIG/GEOM_TestMeasures.py @@ -19,7 +19,6 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# def TestMeasureOperations (geompy, math): @@ -98,6 +97,8 @@ def TestMeasureOperations (geompy, math): print " Xmin = ", BB[0], ", Xmax = ", BB[1] print " Ymin = ", BB[2], ", Ymax = ", BB[3] print " Zmin = ", BB[4], ", Zmax = ", BB[5] + BB = geompy.MakeBoundingBox(box) + geompy.addToStudy(BB, "BoundingBox") ####### Inertia ####### @@ -163,6 +164,16 @@ def TestMeasureOperations (geompy, math): print "\nMinimal distance between Box and Cube = ", MinDistComps[0] print "Its components are (", MinDistComps[1], ", ", MinDistComps[2], ", ", MinDistComps[3], ")" + # Get all closest points + [nbSols, listCoords] = geompy.ClosestPoints(box, cube) + for i in range(nbSols): + v1 = geompy.MakeVertex(listCoords[i*6 + 0], listCoords[i*6 + 1], listCoords[i*6 + 2]) + v2 = geompy.MakeVertex(listCoords[i*6 + 3], listCoords[i*6 + 4], listCoords[i*6 + 5]) + + geompy.addToStudy(v1, 'MinDist_%d_on_Box'%(i+1)) + geompy.addToStudy(v2, 'MinDist_%d_on_Cube'%(i+1)) + pass + ####### Angle ####### OX = geompy.MakeVectorDXDYDZ(10, 0,0) diff --git a/src/GEOM_SWIG/GEOM_TestOthers.py b/src/GEOM_SWIG/GEOM_TestOthers.py index 4f85d8183..5ed4cbaab 100644 --- a/src/GEOM_SWIG/GEOM_TestOthers.py +++ b/src/GEOM_SWIG/GEOM_TestOthers.py @@ -23,7 +23,6 @@ # File : GEOM_TestOthers.py # Author : Julia DOROVSKIKH # Module : GEOM -# $Header$ # # ! Please, if you edit this example file, update also # ! GEOM_SRC/doc/salome/gui/GEOM/input/tui_test_others.doc @@ -187,11 +186,16 @@ def TestOtherOperations (geompy, math): pz = geompy.MakeVertex(0, 0, 100) vy = geompy.MakeVectorDXDYDZ(0, 100, 0) - MultiRot1D = geompy.MakeMultiRotation1D(f12, vy, pz, 6) - MultiRot2D = geompy.MakeMultiRotation2D(f12, vy, pz, 45, 6, 30, 3) + MultiRot1Dt = geompy.MakeMultiRotation1DNbTimes(f12, vy, pz, 6) + MultiRot1Ds = geompy.MakeMultiRotation1DByStep(f12, vy, pz, math.pi/5., 6) - id_MultiRot1D = geompy.addToStudy(MultiRot1D, "MakeMultiRotation1D") - id_MultiRot2D = geompy.addToStudy(MultiRot2D, "MakeMultiRotation2D") + MultiRot2Dt = geompy.MakeMultiRotation2DNbTimes(f12, vy, pz, 5, 30, 3) + MultiRot2Ds = geompy.MakeMultiRotation2DByStep(f12, vy, pz, math.pi/4., 6, 30, 3) + + geompy.addToStudy(MultiRot1Dt, "MakeMultiRotation1DNbTimes") + geompy.addToStudy(MultiRot1Ds, "MakeMultiRotation1DByStep") + geompy.addToStudy(MultiRot2Dt, "MakeMultiRotation2DNbTimes") + geompy.addToStudy(MultiRot2Ds, "MakeMultiRotation2DByStep") # MakeFilletAll radius_fillet = 10. diff --git a/src/GEOM_SWIG/GEOM_blocks.py b/src/GEOM_SWIG/GEOM_blocks.py index 3acf5f5fa..6ad689eb0 100644 --- a/src/GEOM_SWIG/GEOM_blocks.py +++ b/src/GEOM_SWIG/GEOM_blocks.py @@ -25,7 +25,6 @@ # File : GEOM_blocks.py # Author : Julia DOROVSKIKH # Module : GEOM -# $Header$ # import salome import geompy diff --git a/src/GEOM_SWIG/GEOM_example.py b/src/GEOM_SWIG/GEOM_example.py index 4e7e6bd97..b4b66046e 100644 --- a/src/GEOM_SWIG/GEOM_example.py +++ b/src/GEOM_SWIG/GEOM_example.py @@ -25,7 +25,6 @@ # File : GEOM_example.py # Author : Paul RASCLE, EDF # Module : GEOM -# $Header$ # import salome import geompy diff --git a/src/GEOM_SWIG/GEOM_example2.py b/src/GEOM_SWIG/GEOM_example2.py index 9c18c56cf..accb3eb6d 100644 --- a/src/GEOM_SWIG/GEOM_example2.py +++ b/src/GEOM_SWIG/GEOM_example2.py @@ -25,7 +25,6 @@ # File : GEOM_example2.py # Author : Paul RASCLE, EDF # Module : GEOM -# $Header$ # import salome import geompy diff --git a/src/GEOM_SWIG/GEOM_example3.py b/src/GEOM_SWIG/GEOM_example3.py index 8e8c4b40b..2537a9fe5 100644 --- a/src/GEOM_SWIG/GEOM_example3.py +++ b/src/GEOM_SWIG/GEOM_example3.py @@ -25,7 +25,6 @@ # File : GEOM_example3.py # Author : Paul RASCLE, EDF # Module : GEOM -# $Header$ # import salome import geompy diff --git a/src/GEOM_SWIG/GEOM_example5.py b/src/GEOM_SWIG/GEOM_example5.py index 4caaeb7ac..767596185 100644 --- a/src/GEOM_SWIG/GEOM_example5.py +++ b/src/GEOM_SWIG/GEOM_example5.py @@ -25,7 +25,6 @@ # File : GEOM_example5.py # Author : Damien COQUERET, Open CASCADE # Module : GEOM -# $Header$ # import salome import geompy diff --git a/src/GEOM_SWIG/GEOM_example6.py b/src/GEOM_SWIG/GEOM_example6.py index 0041e1c4a..e168d341c 100755 --- a/src/GEOM_SWIG/GEOM_example6.py +++ b/src/GEOM_SWIG/GEOM_example6.py @@ -22,7 +22,6 @@ # File : GEOM_example6.py # Author : Dmitry MATVEITChEV # Module : GEOM -# $Header$ # import salome import geompy diff --git a/src/GEOM_SWIG/GEOM_moteur.py b/src/GEOM_SWIG/GEOM_moteur.py index b39172c3a..436030004 100644 --- a/src/GEOM_SWIG/GEOM_moteur.py +++ b/src/GEOM_SWIG/GEOM_moteur.py @@ -25,7 +25,6 @@ # File : GEOM_moteur.py # Author : Damien COQUERET, Open CASCADE # Module : GEOM -# $Header$ # import salome import geompy diff --git a/src/GEOM_SWIG/GEOM_usinggeom.py b/src/GEOM_SWIG/GEOM_usinggeom.py index 5093069d5..b62e7ce75 100644 --- a/src/GEOM_SWIG/GEOM_usinggeom.py +++ b/src/GEOM_SWIG/GEOM_usinggeom.py @@ -25,7 +25,6 @@ # File : GEOM_usinggeom.py # Author : Damien COQUERET, Open CASCADE # Module : GEOM -# $Header$ # import geompy import math diff --git a/src/GEOM_SWIG/batchmode_geompy.py b/src/GEOM_SWIG/batchmode_geompy.py index 9d45b34ac..0dfacfaaf 100644 --- a/src/GEOM_SWIG/batchmode_geompy.py +++ b/src/GEOM_SWIG/batchmode_geompy.py @@ -21,11 +21,10 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -# GEOM GEOM_SWIG : binding of C++ omplementaion with Python +# GEOM GEOM_SWIG : binding of C++ implementaion with Python # File : batchmode_geompy.py # Author : Paul RASCLE, EDF # Module : GEOM -# $Header$ -# From Salome version 3.2.0 geompy package suits for work in batch mode +# From Salome version 3.2.0 geompy package suits for work in batch mode # from geompy import * diff --git a/src/GEOM_SWIG/geompy.py b/src/GEOM_SWIG/geompy.py index f715dc8a4..5b7926670 100644 --- a/src/GEOM_SWIG/geompy.py +++ b/src/GEOM_SWIG/geompy.py @@ -25,7 +25,6 @@ # File : geompy.py # Author : Paul RASCLE, EDF # Module : GEOM -# $Header$ # import salome import geompyDC diff --git a/src/GEOM_SWIG/geompyDC.py b/src/GEOM_SWIG/geompyDC.py index 40a7dd53a..bf66f2e21 100644 --- a/src/GEOM_SWIG/geompyDC.py +++ b/src/GEOM_SWIG/geompyDC.py @@ -26,6 +26,112 @@ \brief Module geompy """ +## +## @defgroup l1_publish_data Publishing results in SALOME study +## @{ +## +## @details +## +## By default, all functions of geompy.py Python interface do not publish +## resulting geometrical objects. This can be done in the Python script +## by means of geompy.addToStudy() or geompy.addToStudyInFather() +## functions. +## +## However, it is possible to publish result data in the study +## automatically. For this, almost each function of geompy.py module has +## an additional @a theName parameter (@c None by default). +## As soon as non-empty string value is passed to this parameter, +## the result object is published in the study automatically. +## +## For example, +## +## @code +## box = geompy.MakeBoxDXDYDZ(100, 100, 100) # box is not published in the study yet +## geompy.addToStudy(box, "box") # explicit publishing +## @endcode +## +## can be replaced by one-line instruction +## +## @code +## box = geompy.MakeBoxDXDYDZ(100, 100, 100, theName="box") # box is published in the study with "box" name +## @endcode +## +## ... or simply +## +## @code +## box = geompy.MakeBoxDXDYDZ(100, 100, 100, "box") # box is published in the study with "box" name +## @endcode +## +## Note, that some functions produce more than one geometrical objects. For example, +## geompy.GetNonBlocks() function returns two objects: group of all non-hexa solids and group of +## all non-quad faces. For such functions it is possible to specify separate names for results. +## +## For example +## +## @code +## # create and publish cylinder +## cyl = geompy.MakeCylinderRH(100, 100, "cylinder") +## # get non blocks from cylinder +## g1, g2 = geompy.GetNonBlocks(cyl, "nonblock") +## @endcode +## +## Above example will publish both result compounds (first with non-hexa solids and +## second with non-quad faces) as two items, both named "nonblock". +## However, if second command is invoked as +## +## @code +## g1, g2 = geompy.GetNonBlocks(cyl, ("nonhexa", "nonquad")) +## @endcode +## +## ... the first compound will be published with "nonhexa" name, and second will be named "nonquad". +## +## Automatic publication of all results can be also enabled/disabled by means of the function +## geompy.addToStudyAuto(). The automatic publishing is managed by the numeric parameter passed +## to this function: +## - if @a maxNbSubShapes = 0, automatic publishing is disabled. +## - if @a maxNbSubShapes = -1 (default), automatic publishing is enabled and +## maximum number of sub-shapes allowed for publishing is unlimited; any negative +## value passed as parameter has the same effect. +## - if @a maxNbSubShapes is any positive value, automatic publishing is enabled and +## maximum number of sub-shapes allowed for publishing is set to specified value. +## +## When automatic publishing is enabled, you even do not need to pass @a theName parameter +## to the functions creating objects, instead default names will be used. However, you +## can always change the behavior, by passing explicit name to the @a theName parameter +## and it will be used instead default one. +## The publishing of the collections of objects will be done according to the above +## mentioned rules (maximum allowed number of sub-shapes). +## +## For example: +## +## @code +## geompy.addToStudyAuto() # enable automatic publication +## box = geompy.MakeBoxDXDYDZ(100, 100, 100) +## # the box is created and published in the study with default name +## geompy.addToStudyAuto(5) # set max allowed number of sub-shapes to 5 +## vertices = geompy.SubShapeAll(box, geompy.ShapeType['VERTEX']) +## # only 5 first vertices will be published, with default names +## print len(vertices) +## # note, that result value still containes all 8 vertices +## geompy.addToStudyAuto(-1) # disable automatic publication +## @endcode +## +## This feature can be used, for example, for debugging purposes. +## +## @note +## - Use automatic publication feature with caution. When it is enabled, any function of geompy.py module +## publishes the results in the study, that can lead to the huge size of the study data tree. +## For example, repeating call of geompy.SubShapeAll() command on the same main shape each time will +## publish all child objects, that will lead to a lot of duplicated items in the study. +## - Sub-shapes are automatically published as child items of the parent main shape in the study if main +## shape was also published before. Otherwise, sub-shapes are published as top-level objects. +## - Not that some functions of geompy.py module do not have @theName parameter (and, thus, do not support +## automatic publication). For example, some transformation operations like geompy.TranslateDXDYDZ(). +## Refer to the documentation to check if some function has such possibility. +## +## @} + + ## @defgroup l1_geompy_auxiliary Auxiliary data structures and methods ## @defgroup l1_geompy_purpose All package methods, grouped by their purpose @@ -63,6 +169,7 @@ ## @defgroup l3_basic_op Basic Operations ## @defgroup l3_boolean Boolean Operations ## @defgroup l3_transform Transformation Operations +## @defgroup l3_transform_d Transformation Operations deprecated methods ## @defgroup l3_local Local Operations (Fillet, Chamfer and other Features) ## @defgroup l3_blocks_op Blocks Operations ## @defgroup l3_healing Repairing Operations @@ -95,6 +202,18 @@ from gsketcher import Sketcher3D # @ingroup l1_geompy_auxiliary ShapeType = {"AUTO":-1, "COMPOUND":0, "COMPSOLID":1, "SOLID":2, "SHELL":3, "FACE":4, "WIRE":5, "EDGE":6, "VERTEX":7, "SHAPE":8} +# service function +def _toListOfNames(_names, _size=-1): + l = [] + import types + if type(_names) in [types.ListType, types.TupleType]: + for i in _names: l.append(i) + elif _names: + l.append(_names) + if l and len(l) < _size: + for i in range(len(l), _size): l.append("%s_%d"%(l[0],i)) + return l + ## Raise an Error, containing the Method_name, if Operation is Failed ## @ingroup l1_geompy_auxiliary def RaiseIfFailed (Method_name, Operation): @@ -376,6 +495,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): def __init__(self): GEOM._objref_GEOM_Gen.__init__(self) + self.myMaxNbSubShapesAllowed = 0 # auto-publishing is disabled by default self.myBuilder = None self.myStudyId = 0 self.father = None @@ -395,6 +515,82 @@ class geompyDC(GEOM._objref_GEOM_Gen): self.AdvOp = None pass + ## Process object publication in the study, as follows: + # - if @a theName is specified (not None), the object is published in the study + # with this name, not taking into account "auto-publishing" option; + # - if @a theName is NOT specified, the object is published in the study + # (using default name, which can be customized using @a theDefaultName parameter) + # only if auto-publishing is switched on. + # + # @param theObj object, a subject for publishing + # @param theName object name for study + # @param theDefaultName default name for the auto-publishing + # + # @sa addToStudyAuto() + def _autoPublish(self, theObj, theName, theDefaultName="noname"): + # --- + def _item_name(_names, _defname, _idx=-1): + if not _names: _names = _defname + if type(_names) in [types.ListType, types.TupleType]: + if _idx >= 0: + if _idx >= len(_names) or not _names[_idx]: + if type(_defname) not in [types.ListType, types.TupleType]: + _name = "%s_%d"%(_defname, _idx+1) + elif len(_defname) > 0 and _idx >= 0 and _idx < len(_defname): + _name = _defname[_idx] + else: + _name = "%noname_%d"%(dn, _idx+1) + pass + else: + _name = _names[_idx] + pass + else: + # must be wrong usage + _name = _names[0] + pass + else: + if _idx >= 0: + _name = "%s_%d"%(_names, _idx+1) + else: + _name = _names + pass + return _name + # --- + if not theObj: + return # null object + if not theName and not self.myMaxNbSubShapesAllowed: + return # nothing to do: auto-publishing is disabled + if not theName and not theDefaultName: + return # neither theName nor theDefaultName is given + import types + if type(theObj) in [types.ListType, types.TupleType]: + # list of objects is being published + idx = 0 + for obj in theObj: + if not obj: continue # bad object + ###if obj.GetStudyEntry(): continue # already published + name = _item_name(theName, theDefaultName, idx) + if obj.IsMainShape() or not obj.GetMainShape().GetStudyEntry(): + self.addToStudy(obj, name) # "%s_%d"%(aName, idx) + else: + self.addToStudyInFather(obj.GetMainShape(), obj, name) # "%s_%d"%(aName, idx) + pass + idx = idx+1 + if not theName and idx == self.myMaxNbSubShapesAllowed: break + pass + pass + else: + # single object is published + ###if theObj.GetStudyEntry(): return # already published + name = _item_name(theName, theDefaultName) + if theObj.IsMainShape(): + self.addToStudy(theObj, name) + else: + self.addToStudyInFather(theObj.GetMainShape(), theObj, name) + pass + pass + pass + ## @addtogroup l1_geompy_auxiliary ## @{ def init_geom(self,theStudy): @@ -427,6 +623,41 @@ class geompyDC(GEOM._objref_GEOM_Gen): self.AdvOp = self.GetIAdvancedOperations (self.myStudyId) pass + ## Enable / disable results auto-publishing + # + # The automatic publishing is managed in the following way: + # - if @a maxNbSubShapes = 0, automatic publishing is disabled. + # - if @a maxNbSubShapes = -1 (default), automatic publishing is enabled and + # maximum number of sub-shapes allowed for publishing is unlimited; any negative + # value passed as parameter has the same effect. + # - if @a maxNbSubShapes is any positive value, automatic publishing is enabled and + # maximum number of sub-shapes allowed for publishing is set to specified value. + # + # @param maxNbSubShapes maximum number of sub-shapes allowed for publishing. + # @ingroup l1_publish_data + def addToStudyAuto(self, maxNbSubShapes=-1): + """ + Enable / disable results auto-publishing + + The automatic publishing is managed in the following way: + - if @a maxNbSubShapes = 0, automatic publishing is disabled; + - if @a maxNbSubShapes = -1 (default), automatic publishing is enabled and + maximum number of sub-shapes allowed for publishing is unlimited; any negative + value passed as parameter has the same effect. + - if @a maxNbSubShapes is any positive value, automatic publishing is enabled and + maximum number of sub-shapes allowed for publishing is set to this value. + + Parameters: + maxNbSubShapes maximum number of sub-shapes allowed for publishing. + + Example of usage: + geompy.addToStudyAuto() # enable auto-publishing + geompy.MakeBoxDXDYDZ(100) # box is created and published with default name + geompy.addToStudyAuto(0) # disable auto-publishing + """ + self.myMaxNbSubShapesAllowed = max(-1, maxNbSubShapes) + pass + ## Dump component to the Python script # This method overrides IDL function to allow default values for the parameters. def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True): @@ -464,6 +695,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # these arguments description # \return study entry of the published shape in form of string # + # @ingroup l1_publish_data # @ref swig_all_addtostudy "Example" def addToStudy(self, aShape, aName, doRestoreSubShapes=False, theArgs=[], theFindMethod=GEOM.FSM_GetInPlace, theInheritFirstArg=False): @@ -503,6 +735,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): # \param aName the name for the shape # # \return study entry of the published shape in form of string + # + # @ingroup l1_publish_data # @ref swig_all_addtostudyInFather "Example" def addToStudyInFather(self, aFather, aShape, aName): """ @@ -662,10 +896,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theX The X coordinate of the point. # @param theY The Y coordinate of the point. # @param theZ The Z coordinate of the point. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created point. # # @ref tui_creation_point "Example" - def MakeVertex(self, theX, theY, theZ): + def MakeVertex(self, theX, theY, theZ, theName=None): """ Create point by three coordinates. @@ -673,6 +911,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theX The X coordinate of the point. theY The Y coordinate of the point. theZ The Z coordinate of the point. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created point. @@ -682,6 +923,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakePointXYZ(theX, theY, theZ) RaiseIfFailed("MakePointXYZ", self.BasicOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "vertex") return anObj ## Create a point, distant from the referenced point @@ -690,10 +932,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theX Displacement from the referenced point along OX axis. # @param theY Displacement from the referenced point along OY axis. # @param theZ Displacement from the referenced point along OZ axis. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created point. # # @ref tui_creation_point "Example" - def MakeVertexWithRef(self,theReference, theX, theY, theZ): + def MakeVertexWithRef(self, theReference, theX, theY, theZ, theName=None): """ Create a point, distant from the referenced point on the given distances along the coordinate axes. @@ -703,6 +949,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theX Displacement from the referenced point along OX axis. theY Displacement from the referenced point along OY axis. theZ Displacement from the referenced point along OZ axis. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created point. @@ -712,21 +961,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakePointWithReference(theReference, theX, theY, theZ) RaiseIfFailed("MakePointWithReference", self.BasicOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "vertex") return anObj ## Create a point, corresponding to the given parameter on the given curve. # @param theRefCurve The referenced curve. # @param theParameter Value of parameter on the referenced curve. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created point. # # @ref tui_creation_point "Example" - def MakeVertexOnCurve(self,theRefCurve, theParameter): + def MakeVertexOnCurve(self, theRefCurve, theParameter, theName=None): """ Create a point, corresponding to the given parameter on the given curve. Parameters: theRefCurve The referenced curve. theParameter Value of parameter on the referenced curve. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created point. @@ -739,6 +996,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakePointOnCurve(theRefCurve, theParameter) RaiseIfFailed("MakePointOnCurve", self.BasicOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "vertex") return anObj ## Create a point by projection give coordinates on the given curve @@ -746,10 +1004,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theX X-coordinate in 3D space # @param theY Y-coordinate in 3D space # @param theZ Z-coordinate in 3D space + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created point. # # @ref tui_creation_point "Example" - def MakeVertexOnCurveByCoord(self,theRefCurve, theX, theY, theZ): + def MakeVertexOnCurveByCoord(self, theRefCurve, theX, theY, theZ, theName=None): """ Create a point by projection give coordinates on the given curve @@ -758,6 +1020,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theX X-coordinate in 3D space theY Y-coordinate in 3D space theZ Z-coordinate in 3D space + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created point. @@ -770,6 +1035,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakePointOnCurveByCoord(theRefCurve, theX, theY, theZ) RaiseIfFailed("MakeVertexOnCurveByCoord", self.BasicOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "vertex") return anObj ## Create a point, corresponding to the given length on the given curve. @@ -777,10 +1043,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theLength Length on the referenced curve. It can be negative. # @param theStartPoint Point allowing to choose the direction for the calculation # of the length. If None, start from the first point of theRefCurve. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created point. # # @ref tui_creation_point "Example" - def MakeVertexOnCurveByLength(self, theRefCurve, theLength, theStartPoint = None): + def MakeVertexOnCurveByLength(self, theRefCurve, theLength, theStartPoint = None, theName=None): """ Create a point, corresponding to the given length on the given curve. @@ -789,6 +1059,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theLength Length on the referenced curve. It can be negative. theStartPoint Point allowing to choose the direction for the calculation of the length. If None, start from the first point of theRefCurve. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created point. @@ -798,6 +1071,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakePointOnCurveByLength(theRefCurve, theLength, theStartPoint) RaiseIfFailed("MakePointOnCurveByLength", self.BasicOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "vertex") return anObj ## Create a point, corresponding to the given parameters on the @@ -805,10 +1079,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theRefSurf The referenced surface. # @param theUParameter Value of U-parameter on the referenced surface. # @param theVParameter Value of V-parameter on the referenced surface. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created point. # # @ref swig_MakeVertexOnSurface "Example" - def MakeVertexOnSurface(self, theRefSurf, theUParameter, theVParameter): + def MakeVertexOnSurface(self, theRefSurf, theUParameter, theVParameter, theName=None): """ Create a point, corresponding to the given parameters on the given surface. @@ -817,6 +1095,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theRefSurf The referenced surface. theUParameter Value of U-parameter on the referenced surface. theVParameter Value of V-parameter on the referenced surface. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created point. @@ -829,6 +1110,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakePointOnSurface(theRefSurf, theUParameter, theVParameter) RaiseIfFailed("MakePointOnSurface", self.BasicOp) anObj.SetParameters(Parameters); + self._autoPublish(anObj, theName, "vertex") return anObj ## Create a point by projection give coordinates on the given surface @@ -836,10 +1118,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theX X-coordinate in 3D space # @param theY Y-coordinate in 3D space # @param theZ Z-coordinate in 3D space + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created point. # # @ref swig_MakeVertexOnSurfaceByCoord "Example" - def MakeVertexOnSurfaceByCoord(self, theRefSurf, theX, theY, theZ): + def MakeVertexOnSurfaceByCoord(self, theRefSurf, theX, theY, theZ, theName=None): """ Create a point by projection give coordinates on the given surface @@ -848,6 +1134,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theX X-coordinate in 3D space theY Y-coordinate in 3D space theZ Z-coordinate in 3D space + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created point. @@ -860,6 +1149,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakePointOnSurfaceByCoord(theRefSurf, theX, theY, theZ) RaiseIfFailed("MakeVertexOnSurfaceByCoord", self.BasicOp) anObj.SetParameters(Parameters); + self._autoPublish(anObj, theName, "vertex") return anObj ## Create a point, which lays on the given face. @@ -868,10 +1158,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Such point can be used to uniquely identify the face inside any # shape in case, when the shape does not contain overlapped faces. # @param theFace The referenced face. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created point. # # @ref swig_MakeVertexInsideFace "Example" - def MakeVertexInsideFace (self, theFace): + def MakeVertexInsideFace (self, theFace, theName=None): """ Create a point, which lays on the given face. The point will lay in arbitrary place of the face. @@ -881,6 +1175,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theFace The referenced face. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created point. @@ -891,19 +1188,27 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.BasicOp.MakePointOnFace(theFace) RaiseIfFailed("MakeVertexInsideFace", self.BasicOp) + self._autoPublish(anObj, theName, "vertex") return anObj ## Create a point on intersection of two lines. # @param theRefLine1, theRefLine2 The referenced lines. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created point. # # @ref swig_MakeVertexOnLinesIntersection "Example" - def MakeVertexOnLinesIntersection(self, theRefLine1, theRefLine2): + def MakeVertexOnLinesIntersection(self, theRefLine1, theRefLine2, theName=None): """ Create a point on intersection of two lines. Parameters: theRefLine1, theRefLine2 The referenced lines. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created point. @@ -911,21 +1216,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.BasicOp.MakePointOnLinesIntersection(theRefLine1, theRefLine2) RaiseIfFailed("MakePointOnLinesIntersection", self.BasicOp) + self._autoPublish(anObj, theName, "vertex") return anObj ## Create a tangent, corresponding to the given parameter on the given curve. # @param theRefCurve The referenced curve. # @param theParameter Value of parameter on the referenced curve. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created tangent. # # @ref swig_MakeTangentOnCurve "Example" - def MakeTangentOnCurve(self, theRefCurve, theParameter): + def MakeTangentOnCurve(self, theRefCurve, theParameter, theName=None): """ Create a tangent, corresponding to the given parameter on the given curve. Parameters: theRefCurve The referenced curve. theParameter Value of parameter on the referenced curve. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created tangent. @@ -935,6 +1248,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): """ anObj = self.BasicOp.MakeTangentOnCurve(theRefCurve, theParameter) RaiseIfFailed("MakeTangentOnCurve", self.BasicOp) + self._autoPublish(anObj, theName, "tangent") return anObj ## Create a tangent plane, corresponding to the given parameter on the given face. @@ -942,10 +1256,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theParameterV vertical value of the center point (0.0 - 1.0). # @param theParameterU horisontal value of the center point (0.0 - 1.0). # @param theTrimSize the size of plane. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created tangent. # # @ref swig_MakeTangentPlaneOnFace "Example" - def MakeTangentPlaneOnFace(self, theFace, theParameterU, theParameterV, theTrimSize): + def MakeTangentPlaneOnFace(self, theFace, theParameterU, theParameterV, theTrimSize, theName=None): """ Create a tangent plane, corresponding to the given parameter on the given face. @@ -954,6 +1272,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theParameterV vertical value of the center point (0.0 - 1.0). theParameterU horisontal value of the center point (0.0 - 1.0). theTrimSize the size of plane. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created tangent. @@ -963,16 +1284,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): """ anObj = self.BasicOp.MakeTangentPlaneOnFace(theFace, theParameterU, theParameterV, theTrimSize) RaiseIfFailed("MakeTangentPlaneOnFace", self.BasicOp) + self._autoPublish(anObj, theName, "tangent") return anObj ## Create a vector with the given components. # @param theDX X component of the vector. # @param theDY Y component of the vector. # @param theDZ Z component of the vector. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created vector. # # @ref tui_creation_vector "Example" - def MakeVectorDXDYDZ(self,theDX, theDY, theDZ): + def MakeVectorDXDYDZ(self, theDX, theDY, theDZ, theName=None): """ Create a vector with the given components. @@ -980,6 +1306,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theDX X component of the vector. theDY Y component of the vector. theDZ Z component of the vector. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created vector. @@ -989,21 +1318,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakeVectorDXDYDZ(theDX, theDY, theDZ) RaiseIfFailed("MakeVectorDXDYDZ", self.BasicOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "vector") return anObj ## Create a vector between two points. # @param thePnt1 Start point for the vector. # @param thePnt2 End point for the vector. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created vector. # # @ref tui_creation_vector "Example" - def MakeVector(self,thePnt1, thePnt2): + def MakeVector(self, thePnt1, thePnt2, theName=None): """ Create a vector between two points. Parameters: thePnt1 Start point for the vector. thePnt2 End point for the vector. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created vector. @@ -1011,16 +1348,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.BasicOp.MakeVectorTwoPnt(thePnt1, thePnt2) RaiseIfFailed("MakeVectorTwoPnt", self.BasicOp) + self._autoPublish(anObj, theName, "vector") return anObj ## Create a line, passing through the given point # and parrallel to the given direction # @param thePnt Point. The resulting line will pass through it. # @param theDir Direction. The resulting line will be parallel to it. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created line. # # @ref tui_creation_line "Example" - def MakeLine(self,thePnt, theDir): + def MakeLine(self, thePnt, theDir, theName=None): """ Create a line, passing through the given point and parrallel to the given direction @@ -1028,6 +1370,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: thePnt Point. The resulting line will pass through it. theDir Direction. The resulting line will be parallel to it. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created line. @@ -1035,21 +1380,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.BasicOp.MakeLine(thePnt, theDir) RaiseIfFailed("MakeLine", self.BasicOp) + self._autoPublish(anObj, theName, "line") return anObj ## Create a line, passing through the given points # @param thePnt1 First of two points, defining the line. # @param thePnt2 Second of two points, defining the line. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created line. # # @ref tui_creation_line "Example" - def MakeLineTwoPnt(self,thePnt1, thePnt2): + def MakeLineTwoPnt(self, thePnt1, thePnt2, theName=None): """ Create a line, passing through the given points Parameters: thePnt1 First of two points, defining the line. thePnt2 Second of two points, defining the line. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created line. @@ -1057,21 +1410,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.BasicOp.MakeLineTwoPnt(thePnt1, thePnt2) RaiseIfFailed("MakeLineTwoPnt", self.BasicOp) + self._autoPublish(anObj, theName, "line") return anObj ## Create a line on two faces intersection. # @param theFace1 First of two faces, defining the line. # @param theFace2 Second of two faces, defining the line. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created line. # # @ref swig_MakeLineTwoFaces "Example" - def MakeLineTwoFaces(self, theFace1, theFace2): + def MakeLineTwoFaces(self, theFace1, theFace2, theName=None): """ Create a line on two faces intersection. Parameters: theFace1 First of two faces, defining the line. theFace2 Second of two faces, defining the line. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created line. @@ -1079,6 +1440,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.BasicOp.MakeLineTwoFaces(theFace1, theFace2) RaiseIfFailed("MakeLineTwoFaces", self.BasicOp) + self._autoPublish(anObj, theName, "line") return anObj ## Create a plane, passing through the given point @@ -1086,10 +1448,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param thePnt Point, the plane has to pass through. # @param theVec Vector, defining the plane normal direction. # @param theTrimSize Half size of a side of quadrangle face, representing the plane. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created plane. # # @ref tui_creation_plane "Example" - def MakePlane(self,thePnt, theVec, theTrimSize): + def MakePlane(self, thePnt, theVec, theTrimSize, theName=None): """ Create a plane, passing through the given point and normal to the given vector. @@ -1098,6 +1464,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): thePnt Point, the plane has to pass through. theVec Vector, defining the plane normal direction. theTrimSize Half size of a side of quadrangle face, representing the plane. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created plane. @@ -1107,6 +1476,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakePlanePntVec(thePnt, theVec, theTrimSize) RaiseIfFailed("MakePlanePntVec", self.BasicOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "plane") return anObj ## Create a plane, passing through the three given points @@ -1114,10 +1484,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param thePnt2 Second of three points, defining the plane. # @param thePnt3 Fird of three points, defining the plane. # @param theTrimSize Half size of a side of quadrangle face, representing the plane. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created plane. # # @ref tui_creation_plane "Example" - def MakePlaneThreePnt(self,thePnt1, thePnt2, thePnt3, theTrimSize): + def MakePlaneThreePnt(self, thePnt1, thePnt2, thePnt3, theTrimSize, theName=None): """ Create a plane, passing through the three given points @@ -1126,6 +1500,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): thePnt2 Second of three points, defining the plane. thePnt3 Fird of three points, defining the plane. theTrimSize Half size of a side of quadrangle face, representing the plane. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created plane. @@ -1135,21 +1512,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakePlaneThreePnt(thePnt1, thePnt2, thePnt3, theTrimSize) RaiseIfFailed("MakePlaneThreePnt", self.BasicOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "plane") return anObj ## Create a plane, similar to the existing one, but with another size of representing face. # @param theFace Referenced plane or LCS(Marker). # @param theTrimSize New half size of a side of quadrangle face, representing the plane. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created plane. # # @ref tui_creation_plane "Example" - def MakePlaneFace(self,theFace, theTrimSize): + def MakePlaneFace(self, theFace, theTrimSize, theName=None): """ Create a plane, similar to the existing one, but with another size of representing face. Parameters: theFace Referenced plane or LCS(Marker). theTrimSize New half size of a side of quadrangle face, representing the plane. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created plane. @@ -1159,6 +1544,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakePlaneFace(theFace, theTrimSize) RaiseIfFailed("MakePlaneFace", self.BasicOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "plane") return anObj ## Create a plane, passing through the 2 vectors @@ -1166,10 +1552,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theVec1 Vector, defining center point and plane direction. # @param theVec2 Vector, defining the plane normal direction. # @param theTrimSize Half size of a side of quadrangle face, representing the plane. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created plane. # # @ref tui_creation_plane "Example" - def MakePlane2Vec(self,theVec1, theVec2, theTrimSize): + def MakePlane2Vec(self, theVec1, theVec2, theTrimSize, theName=None): """ Create a plane, passing through the 2 vectors with center in a start point of the first vector. @@ -1178,6 +1568,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theVec1 Vector, defining center point and plane direction. theVec2 Vector, defining the plane normal direction. theTrimSize Half size of a side of quadrangle face, representing the plane. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created plane. @@ -1187,16 +1580,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakePlane2Vec(theVec1, theVec2, theTrimSize) RaiseIfFailed("MakePlane2Vec", self.BasicOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "plane") return anObj ## Create a plane, based on a Local coordinate system. # @param theLCS coordinate system, defining plane. # @param theTrimSize Half size of a side of quadrangle face, representing the plane. # @param theOrientation OXY, OYZ or OZX orientation - (1, 2 or 3) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created plane. # # @ref tui_creation_plane "Example" - def MakePlaneLCS(self,theLCS, theTrimSize, theOrientation): + def MakePlaneLCS(self, theLCS, theTrimSize, theOrientation, theName=None): """ Create a plane, based on a Local coordinate system. @@ -1204,6 +1602,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theLCS coordinate system, defining plane. theTrimSize Half size of a side of quadrangle face, representing the plane. theOrientation OXY, OYZ or OZX orientation - (1, 2 or 3) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created plane. @@ -1213,16 +1614,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakePlaneLCS(theLCS, theTrimSize, theOrientation) RaiseIfFailed("MakePlaneLCS", self.BasicOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "plane") return anObj ## Create a local coordinate system. # @param OX,OY,OZ Three coordinates of coordinate system origin. # @param XDX,XDY,XDZ Three components of OX direction # @param YDX,YDY,YDZ Three components of OY direction + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created coordinate system. # # @ref swig_MakeMarker "Example" - def MakeMarker(self, OX,OY,OZ, XDX,XDY,XDZ, YDX,YDY,YDZ): + def MakeMarker(self, OX,OY,OZ, XDX,XDY,XDZ, YDX,YDY,YDZ, theName=None): """ Create a local coordinate system. @@ -1230,6 +1636,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): OX,OY,OZ Three coordinates of coordinate system origin. XDX,XDY,XDZ Three components of OX direction YDX,YDY,YDZ Three components of OY direction + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created coordinate system. @@ -1239,35 +1648,48 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BasicOp.MakeMarker(OX,OY,OZ, XDX,XDY,XDZ, YDX,YDY,YDZ) RaiseIfFailed("MakeMarker", self.BasicOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "lcs") return anObj ## Create a local coordinate system from shape. # @param theShape The initial shape to detect the coordinate system. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created coordinate system. # # @ref tui_creation_lcs "Example" - def MakeMarkerFromShape(self, theShape): + def MakeMarkerFromShape(self, theShape, theName=None): """ Create a local coordinate system from shape. Parameters: theShape The initial shape to detect the coordinate system. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created coordinate system. """ anObj = self.BasicOp.MakeMarkerFromShape(theShape) RaiseIfFailed("MakeMarkerFromShape", self.BasicOp) + self._autoPublish(anObj, theName, "lcs") return anObj ## Create a local coordinate system from point and two vectors. # @param theOrigin Point of coordinate system origin. # @param theXVec Vector of X direction # @param theYVec Vector of Y direction + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created coordinate system. # # @ref tui_creation_lcs "Example" - def MakeMarkerPntTwoVec(self, theOrigin, theXVec, theYVec): + def MakeMarkerPntTwoVec(self, theOrigin, theXVec, theYVec, theName=None): """ Create a local coordinate system from point and two vectors. @@ -1275,6 +1697,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theOrigin Point of coordinate system origin. theXVec Vector of X direction theYVec Vector of Y direction + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created coordinate system. @@ -1282,6 +1707,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): """ anObj = self.BasicOp.MakeMarkerPntTwoVec(theOrigin, theXVec, theYVec) RaiseIfFailed("MakeMarkerPntTwoVec", self.BasicOp) + self._autoPublish(anObj, theName, "lcs") return anObj # end of l3_basic_go @@ -1294,10 +1720,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param thePnt1 Start point of the arc. # @param thePnt2 Middle point of the arc. # @param thePnt3 End point of the arc. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created arc. # # @ref swig_MakeArc "Example" - def MakeArc(self,thePnt1, thePnt2, thePnt3): + def MakeArc(self, thePnt1, thePnt2, thePnt3, theName=None): """ Create an arc of circle, passing through three given points. @@ -1305,6 +1735,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): thePnt1 Start point of the arc. thePnt2 Middle point of the arc. thePnt3 End point of the arc. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created arc. @@ -1312,6 +1745,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.CurvesOp.MakeArc(thePnt1, thePnt2, thePnt3) RaiseIfFailed("MakeArc", self.CurvesOp) + self._autoPublish(anObj, theName, "arc") return anObj ## Create an arc of circle from a center and 2 points. @@ -1319,10 +1753,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param thePnt2 Start point of the arc. (Gives also the radius of the arc) # @param thePnt3 End point of the arc (Gives also a direction) # @param theSense Orientation of the arc + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created arc. # # @ref swig_MakeArc "Example" - def MakeArcCenter(self, thePnt1, thePnt2, thePnt3, theSense=False): + def MakeArcCenter(self, thePnt1, thePnt2, thePnt3, theSense=False, theName=None): """ Create an arc of circle from a center and 2 points. @@ -1331,6 +1769,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): thePnt2 Start point of the arc. (Gives also the radius of the arc) thePnt3 End point of the arc (Gives also a direction) theSense Orientation of the arc + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created arc. @@ -1338,16 +1779,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.CurvesOp.MakeArcCenter(thePnt1, thePnt2, thePnt3, theSense) RaiseIfFailed("MakeArcCenter", self.CurvesOp) + self._autoPublish(anObj, theName, "arc") return anObj ## Create an arc of ellipse, of center and two points. # @param theCenter Center of the arc. # @param thePnt1 defines major radius of the arc by distance from Pnt1 to Pnt2. # @param thePnt2 defines plane of ellipse and minor radius as distance from Pnt3 to line from Pnt1 to Pnt2. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created arc. # # @ref swig_MakeArc "Example" - def MakeArcOfEllipse(self,theCenter, thePnt1, thePnt2): + def MakeArcOfEllipse(self, theCenter, thePnt1, thePnt2, theName=None): """ Create an arc of ellipse, of center and two points. @@ -1355,6 +1801,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theCenter Center of the arc. thePnt1 defines major radius of the arc by distance from Pnt1 to Pnt2. thePnt2 defines plane of ellipse and minor radius as distance from Pnt3 to line from Pnt1 to Pnt2. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created arc. @@ -1362,16 +1811,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.CurvesOp.MakeArcOfEllipse(theCenter, thePnt1, thePnt2) RaiseIfFailed("MakeArcOfEllipse", self.CurvesOp) + self._autoPublish(anObj, theName, "arc") return anObj ## Create a circle with given center, normal vector and radius. # @param thePnt Circle center. # @param theVec Vector, normal to the plane of the circle. # @param theR Circle radius. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created circle. # # @ref tui_creation_circle "Example" - def MakeCircle(self, thePnt, theVec, theR): + def MakeCircle(self, thePnt, theVec, theR, theName=None): """ Create a circle with given center, normal vector and radius. @@ -1379,6 +1833,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): thePnt Circle center. theVec Vector, normal to the plane of the circle. theR Circle radius. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created circle. @@ -1388,14 +1845,19 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.CurvesOp.MakeCirclePntVecR(thePnt, theVec, theR) RaiseIfFailed("MakeCirclePntVecR", self.CurvesOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "circle") return anObj ## Create a circle with given radius. # Center of the circle will be in the origin of global # coordinate system and normal vector will be codirected with Z axis # @param theR Circle radius. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created circle. - def MakeCircleR(self, theR): + def MakeCircleR(self, theR, theName=None): """ Create a circle with given radius. Center of the circle will be in the origin of global @@ -1403,25 +1865,36 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theR Circle radius. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created circle. """ anObj = self.CurvesOp.MakeCirclePntVecR(None, None, theR) RaiseIfFailed("MakeCirclePntVecR", self.CurvesOp) + self._autoPublish(anObj, theName, "circle") return anObj ## Create a circle, passing through three given points # @param thePnt1,thePnt2,thePnt3 Points, defining the circle. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created circle. # # @ref tui_creation_circle "Example" - def MakeCircleThreePnt(self,thePnt1, thePnt2, thePnt3): + def MakeCircleThreePnt(self, thePnt1, thePnt2, thePnt3, theName=None): """ Create a circle, passing through three given points Parameters: thePnt1,thePnt2,thePnt3 Points, defining the circle. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created circle. @@ -1429,16 +1902,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.CurvesOp.MakeCircleThreePnt(thePnt1, thePnt2, thePnt3) RaiseIfFailed("MakeCircleThreePnt", self.CurvesOp) + self._autoPublish(anObj, theName, "circle") return anObj ## Create a circle, with given point1 as center, # passing through the point2 as radius and laying in the plane, # defined by all three given points. # @param thePnt1,thePnt2,thePnt3 Points, defining the circle. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created circle. # # @ref swig_MakeCircle "Example" - def MakeCircleCenter2Pnt(self,thePnt1, thePnt2, thePnt3): + def MakeCircleCenter2Pnt(self, thePnt1, thePnt2, thePnt3, theName=None): """ Create a circle, with given point1 as center, passing through the point2 as radius and laying in the plane, @@ -1446,6 +1924,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: thePnt1,thePnt2,thePnt3 Points, defining the circle. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created circle. @@ -1453,6 +1934,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_example6.py anObj = self.CurvesOp.MakeCircleCenter2Pnt(thePnt1, thePnt2, thePnt3) RaiseIfFailed("MakeCircleCenter2Pnt", self.CurvesOp) + self._autoPublish(anObj, theName, "circle") return anObj ## Create an ellipse with given center, normal vector and radiuses. @@ -1461,10 +1943,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theRMajor Major ellipse radius. # @param theRMinor Minor ellipse radius. # @param theVecMaj Vector, direction of the ellipse's main axis. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created ellipse. # # @ref tui_creation_ellipse "Example" - def MakeEllipse(self, thePnt, theVec, theRMajor, theRMinor, theVecMaj=None): + def MakeEllipse(self, thePnt, theVec, theRMajor, theRMinor, theVecMaj=None, theName=None): """ Create an ellipse with given center, normal vector and radiuses. @@ -1474,6 +1960,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theRMajor Major ellipse radius. theRMinor Minor ellipse radius. theVecMaj Vector, direction of the ellipse's main axis. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created ellipse. @@ -1487,6 +1976,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): pass RaiseIfFailed("MakeEllipse", self.CurvesOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "ellipse") return anObj ## Create an ellipse with given radiuses. @@ -1494,8 +1984,12 @@ class geompyDC(GEOM._objref_GEOM_Gen): # coordinate system and normal vector will be codirected with Z axis # @param theRMajor Major ellipse radius. # @param theRMinor Minor ellipse radius. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created ellipse. - def MakeEllipseRR(self, theRMajor, theRMinor): + def MakeEllipseRR(self, theRMajor, theRMinor, theName=None): """ Create an ellipse with given radiuses. Center of the ellipse will be in the origin of global @@ -1504,27 +1998,38 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theRMajor Major ellipse radius. theRMinor Minor ellipse radius. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: - New GEOM.GEOM_Object, containing the created ellipse. + New GEOM.GEOM_Object, containing the created ellipse. """ anObj = self.CurvesOp.MakeEllipse(None, None, theRMajor, theRMinor) RaiseIfFailed("MakeEllipse", self.CurvesOp) + self._autoPublish(anObj, theName, "ellipse") return anObj ## Create a polyline on the set of points. # @param thePoints Sequence of points for the polyline. # @param theIsClosed If True, build a closed wire. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created polyline. # # @ref tui_creation_curve "Example" - def MakePolyline(self, thePoints, theIsClosed=False): + def MakePolyline(self, thePoints, theIsClosed=False, theName=None): """ Create a polyline on the set of points. Parameters: thePoints Sequence of points for the polyline. theIsClosed If True, build a closed wire. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created polyline. @@ -1532,21 +2037,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.CurvesOp.MakePolyline(thePoints, theIsClosed) RaiseIfFailed("MakePolyline", self.CurvesOp) + self._autoPublish(anObj, theName, "polyline") return anObj ## Create bezier curve on the set of points. # @param thePoints Sequence of points for the bezier curve. # @param theIsClosed If True, build a closed curve. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created bezier curve. # # @ref tui_creation_curve "Example" - def MakeBezier(self, thePoints, theIsClosed=False): + def MakeBezier(self, thePoints, theIsClosed=False, theName=None): """ Create bezier curve on the set of points. Parameters: thePoints Sequence of points for the bezier curve. theIsClosed If True, build a closed curve. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created bezier curve. @@ -1554,6 +2067,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.CurvesOp.MakeSplineBezier(thePoints, theIsClosed) RaiseIfFailed("MakeSplineBezier", self.CurvesOp) + self._autoPublish(anObj, theName, "bezier") return anObj ## Create B-Spline curve on the set of points. @@ -1561,10 +2075,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theIsClosed If True, build a closed curve. # @param theDoReordering If TRUE, the algo does not follow the order of # \a thePoints but searches for the closest vertex. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created B-Spline curve. # # @ref tui_creation_curve "Example" - def MakeInterpol(self, thePoints, theIsClosed=False, theDoReordering=False): + def MakeInterpol(self, thePoints, theIsClosed=False, theDoReordering=False, theName=None): """ Create B-Spline curve on the set of points. @@ -1573,15 +2091,50 @@ class geompyDC(GEOM._objref_GEOM_Gen): theIsClosed If True, build a closed curve. theDoReordering If True, the algo does not follow the order of thePoints but searches for the closest vertex. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created B-Spline curve. """ # Example: see GEOM_TestAll.py anObj = self.CurvesOp.MakeSplineInterpolation(thePoints, theIsClosed, theDoReordering) - RaiseIfFailed("MakeSplineInterpolation", self.CurvesOp) + RaiseIfFailed("MakeInterpol", self.CurvesOp) + self._autoPublish(anObj, theName, "bspline") return anObj + ## Create B-Spline curve on the set of points. + # @param thePoints Sequence of points for the B-Spline curve. + # @param theFirstVec Vector object, defining the curve direction at its first point. + # @param theLastVec Vector object, defining the curve direction at its last point. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @return New GEOM.GEOM_Object, containing the created B-Spline curve. + # + # @ref tui_creation_curve "Example" + def MakeInterpolWithTangents(self, thePoints, theFirstVec, theLastVec, theName=None): + """ + Create B-Spline curve on the set of points. + + Parameters: + thePoints Sequence of points for the B-Spline curve. + theFirstVec Vector object, defining the curve direction at its first point. + theLastVec Vector object, defining the curve direction at its last point. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + New GEOM.GEOM_Object, containing the created B-Spline curve. + """ + # Example: see GEOM_TestAll.py + anObj = self.CurvesOp.MakeSplineInterpolWithTangents(thePoints, theFirstVec, theLastVec) + RaiseIfFailed("MakeInterpolWithTangents", self.CurvesOp) + self._autoPublish(anObj, theName, "bspline") + return anObj ## Creates a curve using the parametric definition of the basic points. # @param thexExpr parametric equation of the coordinates X. @@ -1592,11 +2145,15 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theParamStep the number of steps if theNewMethod = True, else step value of the parameter. # @param theCurveType the type of the curve. # @param theNewMethod flag for switching to the new method if the flag is set to false a deprecated method is used which can lead to a bug. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created curve. # # @ref tui_creation_curve "Example" def MakeCurveParametric(self, thexExpr, theyExpr, thezExpr, - theParamMin, theParamMax, theParamStep, theCurveType, theNewMethod=False ): + theParamMin, theParamMax, theParamStep, theCurveType, theNewMethod=False, theName=None ): """ Creates a curve using the parametric definition of the basic points. @@ -1610,6 +2167,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theCurveType the type of the curve. theNewMethod flag for switching to the new method if the flag is set to false a deprecated method is used which can lead to a bug. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created curve. @@ -1621,9 +2181,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.CurvesOp.MakeCurveParametric(thexExpr,theyExpr,thezExpr,theParamMin,theParamMax,theParamStep,theCurveType) RaiseIfFailed("MakeSplineInterpolation", self.CurvesOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "curve") return anObj - - # end of l4_curves ## @} @@ -1679,10 +2238,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # coordinates of the working plane. # @param theWorkingPlane Nine double values, defining origin, # OZ and OX directions of the working plane. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created wire. # # @ref tui_sketcher_page "Example" - def MakeSketcher(self, theCommand, theWorkingPlane = [0,0,0, 0,0,1, 1,0,0]): + def MakeSketcher(self, theCommand, theWorkingPlane = [0,0,0, 0,0,1, 1,0,0], theName=None): """ Create a sketcher (wire or face), following the textual description, passed through theCommand argument. @@ -1726,6 +2289,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): coordinates of the working plane. theWorkingPlane Nine double values, defining origin, OZ and OX directions of the working plane. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created wire. @@ -1735,6 +2301,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.CurvesOp.MakeSketcher(theCommand, theWorkingPlane) RaiseIfFailed("MakeSketcher", self.CurvesOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "wire") return anObj ## Create a sketcher (wire or face), following the textual description, @@ -1743,10 +2310,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theCommand String, defining the sketcher in local # coordinates of the working plane. # @param theWorkingPlane Planar Face or LCS(Marker) of the working plane. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created wire. # # @ref tui_sketcher_page "Example" - def MakeSketcherOnPlane(self, theCommand, theWorkingPlane): + def MakeSketcherOnPlane(self, theCommand, theWorkingPlane, theName=None): """ Create a sketcher (wire or face), following the textual description, passed through theCommand argument. @@ -1756,6 +2327,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theCommand String, defining the sketcher in local coordinates of the working plane. theWorkingPlane Planar Face or LCS(Marker) of the working plane. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created wire. @@ -1764,16 +2338,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.CurvesOp.MakeSketcherOnPlane(theCommand, theWorkingPlane) RaiseIfFailed("MakeSketcherOnPlane", self.CurvesOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "wire") return anObj ## Create a sketcher wire, following the numerical description, # passed through theCoordinates argument. \n # @param theCoordinates double values, defining points to create a wire, # passing from it. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created wire. # # @ref tui_3dsketcher_page "Example" - def Make3DSketcher(self, theCoordinates): + def Make3DSketcher(self, theCoordinates, theName=None): """ Create a sketcher wire, following the numerical description, passed through theCoordinates argument. @@ -1781,6 +2360,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theCoordinates double values, defining points to create a wire, passing from it. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM_Object, containing the created wire. @@ -1789,6 +2371,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.CurvesOp.Make3DSketcher(theCoordinates) RaiseIfFailed("Make3DSketcher", self.CurvesOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "wire") return anObj ## Obtain a 3D sketcher interface @@ -1821,16 +2404,23 @@ class geompyDC(GEOM._objref_GEOM_Gen): # # @param x1,y1,z1 double values, defining first point it. # @param x2,y2,z2 double values, defining first point it. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. # # @return New GEOM.GEOM_Object, containing the created box. + # # @ref tui_creation_box "Example" - def MakeBox (self, x1,y1,z1, x2,y2,z2): + def MakeBox(self, x1, y1, z1, x2, y2, z2, theName=None): """ Create a box by coordinates of two opposite vertices. Parameters: x1,y1,z1 double values, defining first point. x2,y2,z2 double values, defining second point. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created box. @@ -1838,7 +2428,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py pnt1 = self.MakeVertex(x1,y1,z1) pnt2 = self.MakeVertex(x2,y2,z2) - return self.MakeBoxTwoPnt(pnt1,pnt2) + # note: auto-publishing is done in self.MakeBoxTwoPnt() + return self.MakeBoxTwoPnt(pnt1, pnt2, theName) ## Create a box with specified dimensions along the coordinate axes # and with edges, parallel to the coordinate axes. @@ -1846,10 +2437,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theDX Length of Box edges, parallel to OX axis. # @param theDY Length of Box edges, parallel to OY axis. # @param theDZ Length of Box edges, parallel to OZ axis. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created box. # # @ref tui_creation_box "Example" - def MakeBoxDXDYDZ(self,theDX, theDY, theDZ): + def MakeBoxDXDYDZ(self, theDX, theDY, theDZ, theName=None): """ Create a box with specified dimensions along the coordinate axes and with edges, parallel to the coordinate axes. @@ -1859,6 +2454,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theDX Length of Box edges, parallel to OX axis. theDY Length of Box edges, parallel to OY axis. theDZ Length of Box edges, parallel to OZ axis. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created box. @@ -1868,16 +2466,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeBoxDXDYDZ(theDX, theDY, theDZ) RaiseIfFailed("MakeBoxDXDYDZ", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "box") return anObj ## Create a box with two specified opposite vertices, # and with edges, parallel to the coordinate axes # @param thePnt1 First of two opposite vertices. # @param thePnt2 Second of two opposite vertices. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created box. # # @ref tui_creation_box "Example" - def MakeBoxTwoPnt(self,thePnt1, thePnt2): + def MakeBoxTwoPnt(self, thePnt1, thePnt2, theName=None): """ Create a box with two specified opposite vertices, and with edges, parallel to the coordinate axes @@ -1885,6 +2488,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: thePnt1 First of two opposite vertices. thePnt2 Second of two opposite vertices. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created box. @@ -1892,16 +2498,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.PrimOp.MakeBoxTwoPnt(thePnt1, thePnt2) RaiseIfFailed("MakeBoxTwoPnt", self.PrimOp) + self._autoPublish(anObj, theName, "box") return anObj ## Create a face with specified dimensions with edges parallel to coordinate axes. # @param theH height of Face. # @param theW width of Face. # @param theOrientation face orientation: 1-OXY, 2-OYZ, 3-OZX + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created face. # # @ref tui_creation_face "Example" - def MakeFaceHW(self,theH, theW, theOrientation): + def MakeFaceHW(self, theH, theW, theOrientation, theName=None): """ Create a face with specified dimensions with edges parallel to coordinate axes. @@ -1909,6 +2520,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theH height of Face. theW width of Face. theOrientation face orientation: 1-OXY, 2-OYZ, 3-OZX + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created face. @@ -1918,6 +2532,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeFaceHW(theH, theW, theOrientation) RaiseIfFailed("MakeFaceHW", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "rectangle") return anObj ## Create a face from another plane and two sizes, @@ -1926,10 +2541,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # the face object. # @param theH Height (vertical size). # @param theW Width (horisontal size). + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created face. # # @ref tui_creation_face "Example" - def MakeFaceObjHW(self, theObj, theH, theW): + def MakeFaceObjHW(self, theObj, theH, theW, theName=None): """ Create a face from another plane and two sizes, vertical size and horisontal size. @@ -1939,6 +2558,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): the face object. theH Height (vertical size). theW Width (horisontal size). + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM_Object, containing the created face. @@ -1948,16 +2570,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeFaceObjHW(theObj, theH, theW) RaiseIfFailed("MakeFaceObjHW", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "rectangle") return anObj ## Create a disk with given center, normal vector and radius. # @param thePnt Disk center. # @param theVec Vector, normal to the plane of the disk. # @param theR Disk radius. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created disk. # # @ref tui_creation_disk "Example" - def MakeDiskPntVecR(self,thePnt, theVec, theR): + def MakeDiskPntVecR(self, thePnt, theVec, theR, theName=None): """ Create a disk with given center, normal vector and radius. @@ -1965,6 +2592,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): thePnt Disk center. theVec Vector, normal to the plane of the disk. theR Disk radius. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created disk. @@ -1974,19 +2604,27 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeDiskPntVecR(thePnt, theVec, theR) RaiseIfFailed("MakeDiskPntVecR", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "disk") return anObj ## Create a disk, passing through three given points # @param thePnt1,thePnt2,thePnt3 Points, defining the disk. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created disk. # # @ref tui_creation_disk "Example" - def MakeDiskThreePnt(self,thePnt1, thePnt2, thePnt3): + def MakeDiskThreePnt(self, thePnt1, thePnt2, thePnt3, theName=None): """ Create a disk, passing through three given points Parameters: thePnt1,thePnt2,thePnt3 Points, defining the disk. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created disk. @@ -1994,21 +2632,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.PrimOp.MakeDiskThreePnt(thePnt1, thePnt2, thePnt3) RaiseIfFailed("MakeDiskThreePnt", self.PrimOp) + self._autoPublish(anObj, theName, "disk") return anObj ## Create a disk with specified dimensions along OX-OY coordinate axes. # @param theR Radius of Face. # @param theOrientation set the orientation belong axis OXY or OYZ or OZX + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created disk. # # @ref tui_creation_face "Example" - def MakeDiskR(self,theR, theOrientation): + def MakeDiskR(self, theR, theOrientation, theName=None): """ Create a disk with specified dimensions along OX-OY coordinate axes. Parameters: theR Radius of Face. theOrientation set the orientation belong axis OXY or OYZ or OZX + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created disk. @@ -2021,6 +2667,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeDiskR(theR, theOrientation) RaiseIfFailed("MakeDiskR", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "disk") return anObj ## Create a cylinder with given base point, axis, radius and height. @@ -2028,10 +2675,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theAxis Cylinder axis. # @param theR Cylinder radius. # @param theH Cylinder height. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created cylinder. # # @ref tui_creation_cylinder "Example" - def MakeCylinder(self,thePnt, theAxis, theR, theH): + def MakeCylinder(self, thePnt, theAxis, theR, theH, theName=None): """ Create a cylinder with given base point, axis, radius and height. @@ -2040,6 +2691,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theAxis Cylinder axis. theR Cylinder radius. theH Cylinder height. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created cylinder. @@ -2049,6 +2703,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeCylinderPntVecRH(thePnt, theAxis, theR, theH) RaiseIfFailed("MakeCylinderPntVecRH", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "cylinder") return anObj ## Create a cylinder with given radius and height at @@ -2056,10 +2711,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # will be collinear to the OZ axis of the coordinate system. # @param theR Cylinder radius. # @param theH Cylinder height. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created cylinder. # # @ref tui_creation_cylinder "Example" - def MakeCylinderRH(self,theR, theH): + def MakeCylinderRH(self, theR, theH, theName=None): """ Create a cylinder with given radius and height at the origin of coordinate system. Axis of the cylinder @@ -2068,6 +2727,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theR Cylinder radius. theH Cylinder height. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created cylinder. @@ -2077,21 +2739,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeCylinderRH(theR, theH) RaiseIfFailed("MakeCylinderRH", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "cylinder") return anObj ## Create a sphere with given center and radius. # @param thePnt Sphere center. # @param theR Sphere radius. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created sphere. # # @ref tui_creation_sphere "Example" - def MakeSpherePntR(self, thePnt, theR): + def MakeSpherePntR(self, thePnt, theR, theName=None): """ Create a sphere with given center and radius. Parameters: thePnt Sphere center. theR Sphere radius. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created sphere. @@ -2101,41 +2771,57 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeSpherePntR(thePnt, theR) RaiseIfFailed("MakeSpherePntR", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "sphere") return anObj ## Create a sphere with given center and radius. # @param x,y,z Coordinates of sphere center. # @param theR Sphere radius. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created sphere. # # @ref tui_creation_sphere "Example" - def MakeSphere(self, x, y, z, theR): + def MakeSphere(self, x, y, z, theR, theName=None): """ Create a sphere with given center and radius. Parameters: x,y,z Coordinates of sphere center. theR Sphere radius. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created sphere. """ # Example: see GEOM_TestAll.py point = self.MakeVertex(x, y, z) - anObj = self.MakeSpherePntR(point, theR) + # note: auto-publishing is done in self.MakeSpherePntR() + anObj = self.MakeSpherePntR(point, theR, theName) return anObj ## Create a sphere with given radius at the origin of coordinate system. # @param theR Sphere radius. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created sphere. # # @ref tui_creation_sphere "Example" - def MakeSphereR(self, theR): + def MakeSphereR(self, theR, theName=None): """ Create a sphere with given radius at the origin of coordinate system. Parameters: theR Sphere radius. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created sphere. @@ -2145,6 +2831,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeSphereR(theR) RaiseIfFailed("MakeSphereR", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "sphere") return anObj ## Create a cone with given base point, axis, height and radiuses. @@ -2155,10 +2842,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # \note If both radiuses are non-zero, the cone will be truncated. # \note If the radiuses are equal, a cylinder will be created instead. # @param theH Cone height. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created cone. # # @ref tui_creation_cone "Example" - def MakeCone(self,thePnt, theAxis, theR1, theR2, theH): + def MakeCone(self, thePnt, theAxis, theR1, theR2, theH, theName=None): """ Create a cone with given base point, axis, height and radiuses. @@ -2168,6 +2859,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theR1 Radius of the first cone base. theR2 Radius of the second cone base. theH Cone height. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Note: If both radiuses are non-zero, the cone will be truncated. @@ -2181,6 +2875,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeConePntVecR1R2H(thePnt, theAxis, theR1, theR2, theH) RaiseIfFailed("MakeConePntVecR1R2H", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "cone") return anObj ## Create a cone with given height and radiuses at @@ -2191,10 +2886,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # \note If both radiuses are non-zero, the cone will be truncated. # \note If the radiuses are equal, a cylinder will be created instead. # @param theH Cone height. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created cone. # # @ref tui_creation_cone "Example" - def MakeConeR1R2H(self,theR1, theR2, theH): + def MakeConeR1R2H(self, theR1, theR2, theH, theName=None): """ Create a cone with given height and radiuses at the origin of coordinate system. Axis of the cone will @@ -2204,6 +2903,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theR1 Radius of the first cone base. theR2 Radius of the second cone base. theH Cone height. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Note: If both radiuses are non-zero, the cone will be truncated. @@ -2217,6 +2919,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeConeR1R2H(theR1, theR2, theH) RaiseIfFailed("MakeConeR1R2H", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "cone") return anObj ## Create a torus with given center, normal vector and radiuses. @@ -2224,10 +2927,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theVec Torus axis of symmetry. # @param theRMajor Torus major radius. # @param theRMinor Torus minor radius. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created torus. # # @ref tui_creation_torus "Example" - def MakeTorus(self, thePnt, theVec, theRMajor, theRMinor): + def MakeTorus(self, thePnt, theVec, theRMajor, theRMinor, theName=None): """ Create a torus with given center, normal vector and radiuses. @@ -2236,6 +2943,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theVec Torus axis of symmetry. theRMajor Torus major radius. theRMinor Torus minor radius. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created torus. @@ -2245,21 +2955,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeTorusPntVecRR(thePnt, theVec, theRMajor, theRMinor) RaiseIfFailed("MakeTorusPntVecRR", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "torus") return anObj ## Create a torus with given radiuses at the origin of coordinate system. # @param theRMajor Torus major radius. # @param theRMinor Torus minor radius. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created torus. # # @ref tui_creation_torus "Example" - def MakeTorusRR(self, theRMajor, theRMinor): + def MakeTorusRR(self, theRMajor, theRMinor, theName=None): """ Create a torus with given radiuses at the origin of coordinate system. Parameters: theRMajor Torus major radius. theRMinor Torus minor radius. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created torus. @@ -2269,6 +2987,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeTorusRR(theRMajor, theRMinor) RaiseIfFailed("MakeTorusRR", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "torus") return anObj # end of l3_3d_primitives @@ -2283,10 +3002,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param thePoint2 Second end of extrusion vector. # @param theScaleFactor Use it to make prism with scaled second base. # Nagative value means not scaled second base. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created prism. # # @ref tui_creation_prism "Example" - def MakePrism(self, theBase, thePoint1, thePoint2, theScaleFactor = -1.0): + def MakePrism(self, theBase, thePoint1, thePoint2, theScaleFactor = -1.0, theName=None): """ Create a shape by extrusion of the base shape along a vector, defined by two points. @@ -2296,6 +3019,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): thePoint2 Second end of extrusion vector. theScaleFactor Use it to make prism with scaled second base. Nagative value means not scaled second base. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created prism. @@ -2310,6 +3036,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakePrismTwoPnt(theBase, thePoint1, thePoint2) RaiseIfFailed("MakePrismTwoPnt", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "prism") return anObj ## Create a shape by extrusion of the base shape along a @@ -2317,10 +3044,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theBase Base shape to be extruded. # @param thePoint1 First end of extrusion vector. # @param thePoint2 Second end of extrusion vector. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created prism. # # @ref tui_creation_prism "Example" - def MakePrism2Ways(self, theBase, thePoint1, thePoint2): + def MakePrism2Ways(self, theBase, thePoint1, thePoint2, theName=None): """ Create a shape by extrusion of the base shape along a vector, defined by two points, in 2 Ways (forward/backward). @@ -2329,6 +3060,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theBase Base shape to be extruded. thePoint1 First end of extrusion vector. thePoint2 Second end of extrusion vector. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created prism. @@ -2336,6 +3070,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.PrimOp.MakePrismTwoPnt2Ways(theBase, thePoint1, thePoint2) RaiseIfFailed("MakePrismTwoPnt", self.PrimOp) + self._autoPublish(anObj, theName, "prism") return anObj ## Create a shape by extrusion of the base shape along the vector, @@ -2346,10 +3081,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theH Prism dimension along theVec. # @param theScaleFactor Use it to make prism with scaled second base. # Negative value means not scaled second base. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created prism. # # @ref tui_creation_prism "Example" - def MakePrismVecH(self, theBase, theVec, theH, theScaleFactor = -1.0): + def MakePrismVecH(self, theBase, theVec, theH, theScaleFactor = -1.0, theName=None): """ Create a shape by extrusion of the base shape along the vector, i.e. all the space, transfixed by the base shape during its translation @@ -2361,6 +3100,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theH Prism dimension along theVec. theScaleFactor Use it to make prism with scaled second base. Negative value means not scaled second base. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created prism. @@ -2376,6 +3118,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakePrismVecH(theBase, theVec, theH) RaiseIfFailed("MakePrismVecH", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "prism") return anObj ## Create a shape by extrusion of the base shape along the vector, @@ -2384,10 +3127,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theBase Base shape to be extruded. # @param theVec Direction of extrusion. # @param theH Prism dimension along theVec in forward direction. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created prism. # # @ref tui_creation_prism "Example" - def MakePrismVecH2Ways(self, theBase, theVec, theH): + def MakePrismVecH2Ways(self, theBase, theVec, theH, theName=None): """ Create a shape by extrusion of the base shape along the vector, i.e. all the space, transfixed by the base shape during its translation @@ -2397,6 +3144,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theBase Base shape to be extruded. theVec Direction of extrusion. theH Prism dimension along theVec in forward direction. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created prism. @@ -2406,6 +3156,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakePrismVecH2Ways(theBase, theVec, theH) RaiseIfFailed("MakePrismVecH2Ways", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "prism") return anObj ## Create a shape by extrusion of the base shape along the dx, dy, dz direction @@ -2413,10 +3164,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theDX, theDY, theDZ Directions of extrusion. # @param theScaleFactor Use it to make prism with scaled second base. # Nagative value means not scaled second base. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created prism. # # @ref tui_creation_prism "Example" - def MakePrismDXDYDZ(self, theBase, theDX, theDY, theDZ, theScaleFactor = -1.0): + def MakePrismDXDYDZ(self, theBase, theDX, theDY, theDZ, theScaleFactor = -1.0, theName=None): """ Create a shape by extrusion of the base shape along the dx, dy, dz direction @@ -2425,6 +3180,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theDX, theDY, theDZ Directions of extrusion. theScaleFactor Use it to make prism with scaled second base. Nagative value means not scaled second base. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created prism. @@ -2440,6 +3198,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakePrismDXDYDZ(theBase, theDX, theDY, theDZ) RaiseIfFailed("MakePrismDXDYDZ", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "prism") return anObj ## Create a shape by extrusion of the base shape along the dx, dy, dz direction @@ -2447,10 +3206,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # along the vector on the given distance in 2 Ways (forward/backward). # @param theBase Base shape to be extruded. # @param theDX, theDY, theDZ Directions of extrusion. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created prism. # # @ref tui_creation_prism "Example" - def MakePrismDXDYDZ2Ways(self, theBase, theDX, theDY, theDZ): + def MakePrismDXDYDZ2Ways(self, theBase, theDX, theDY, theDZ, theName=None): """ Create a shape by extrusion of the base shape along the dx, dy, dz direction i.e. all the space, transfixed by the base shape during its translation @@ -2459,6 +3222,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theBase Base shape to be extruded. theDX, theDY, theDZ Directions of extrusion. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created prism. @@ -2468,6 +3234,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakePrismDXDYDZ2Ways(theBase, theDX, theDY, theDZ) RaiseIfFailed("MakePrismDXDYDZ2Ways", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "prism") return anObj ## Create a shape by revolution of the base shape around the axis @@ -2476,10 +3243,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theBase Base shape to be rotated. # @param theAxis Rotation axis. # @param theAngle Rotation angle in radians. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created revolution. # # @ref tui_creation_revolution "Example" - def MakeRevolution(self, theBase, theAxis, theAngle): + def MakeRevolution(self, theBase, theAxis, theAngle, theName=None): """ Create a shape by revolution of the base shape around the axis on the given angle, i.e. all the space, transfixed by the base @@ -2489,6 +3260,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theBase Base shape to be rotated. theAxis Rotation axis. theAngle Rotation angle in radians. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created revolution. @@ -2498,6 +3272,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeRevolutionAxisAngle(theBase, theAxis, theAngle) RaiseIfFailed("MakeRevolutionAxisAngle", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "revolution") return anObj ## Create a shape by revolution of the base shape around the axis @@ -2507,10 +3282,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theBase Base shape to be rotated. # @param theAxis Rotation axis. # @param theAngle Rotation angle in radians. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created revolution. # # @ref tui_creation_revolution "Example" - def MakeRevolution2Ways(self, theBase, theAxis, theAngle): + def MakeRevolution2Ways(self, theBase, theAxis, theAngle, theName=None): """ Create a shape by revolution of the base shape around the axis on the given angle, i.e. all the space, transfixed by the base @@ -2521,6 +3300,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theBase Base shape to be rotated. theAxis Rotation axis. theAngle Rotation angle in radians. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created revolution. @@ -2529,6 +3311,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeRevolutionAxisAngle2Ways(theBase, theAxis, theAngle) RaiseIfFailed("MakeRevolutionAxisAngle2Ways", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "revolution") return anObj ## Create a filling from the given compound of contours. @@ -2544,11 +3327,15 @@ class geompyDC(GEOM._objref_GEOM_Gen): # the surface is created using given curves. The usage of # Approximation makes the algorithm work slower, but allows # building the surface for rather complex cases. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created filling surface. # # @ref tui_creation_filling "Example" def MakeFilling(self, theShape, theMinDeg=2, theMaxDeg=5, theTol2D=0.0001, - theTol3D=0.0001, theNbIter=0, theMethod=GEOM.FOM_Default, isApprox=0): + theTol3D=0.0001, theNbIter=0, theMethod=GEOM.FOM_Default, isApprox=0, theName=None): """ Create a filling from the given compound of contours. @@ -2565,6 +3352,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): the surface is created using given curves. The usage of Approximation makes the algorithm work slower, but allows building the surface for rather complex cases + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created filling surface. @@ -2579,6 +3369,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): theMethod, isApprox) RaiseIfFailed("MakeFilling", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "filling") return anObj @@ -2588,10 +3379,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theMinDeg a minimal degree of BSpline surface to create # @param theMaxDeg a maximal degree of BSpline surface to create # @param theTol3D a 3d tolerance to be reached + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created filling surface. # # @ref tui_creation_filling "Example" - def MakeFillingNew(self, theShape, theMinDeg=2, theMaxDeg=5, theTol3D=0.0001): + def MakeFillingNew(self, theShape, theMinDeg=2, theMaxDeg=5, theTol3D=0.0001, theName=None): """ Create a filling from the given compound of contours. This method corresponds to MakeFilling with isApprox=True @@ -2601,6 +3396,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theMinDeg a minimal degree of BSpline surface to create theMaxDeg a maximal degree of BSpline surface to create theTol3D a 3d tolerance to be reached + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created filling surface. @@ -2614,6 +3412,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): 0, theTol3D, 0, GEOM.FOM_Default, True) RaiseIfFailed("MakeFillingNew", self.PrimOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "filling") return anObj ## Create a shell or solid passing through set of sections.Sections should be wires,edges or vertices. @@ -2621,10 +3420,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theModeSolid - mode defining building solid or shell # @param thePreci - precision 3D used for smoothing # @param theRuled - mode defining type of the result surfaces (ruled or smoothed). + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created shell or solid. # # @ref swig_todo "Example" - def MakeThruSections(self,theSeqSections,theModeSolid,thePreci,theRuled): + def MakeThruSections(self, theSeqSections, theModeSolid, thePreci, theRuled, theName=None): """ Create a shell or solid passing through set of sections.Sections should be wires,edges or vertices. @@ -2633,6 +3436,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theModeSolid - mode defining building solid or shell thePreci - precision 3D used for smoothing theRuled - mode defining type of the result surfaces (ruled or smoothed). + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created shell or solid. @@ -2640,16 +3446,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.PrimOp.MakeThruSections(theSeqSections,theModeSolid,thePreci,theRuled) RaiseIfFailed("MakeThruSections", self.PrimOp) + self._autoPublish(anObj, theName, "filling") return anObj ## Create a shape by extrusion of the base shape along # the path shape. The path shape can be a wire or an edge. # @param theBase Base shape to be extruded. # @param thePath Path shape to extrude the base shape along it. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created pipe. # # @ref tui_creation_pipe "Example" - def MakePipe(self,theBase, thePath): + def MakePipe(self, theBase, thePath, theName=None): """ Create a shape by extrusion of the base shape along the path shape. The path shape can be a wire or an edge. @@ -2657,6 +3468,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theBase Base shape to be extruded. thePath Path shape to extrude the base shape along it. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created pipe. @@ -2664,6 +3478,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.PrimOp.MakePipe(theBase, thePath) RaiseIfFailed("MakePipe", self.PrimOp) + self._autoPublish(anObj, theName, "pipe") return anObj ## Create a shape by extrusion of the profile shape along @@ -2678,12 +3493,16 @@ class geompyDC(GEOM._objref_GEOM_Gen): # contact with the spine. # @param theWithCorrection - defining that the section is rotated to be # orthogonal to the spine tangent in the correspondent point + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created pipe. # # @ref tui_creation_pipe_with_diff_sec "Example" def MakePipeWithDifferentSections(self, theSeqBases, theLocations, thePath, - theWithContact, theWithCorrection): + theWithContact, theWithCorrection, theName=None): """ Create a shape by extrusion of the profile shape along the path shape. The path shape can be a wire or an edge. @@ -2699,6 +3518,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): contact with the spine(0/1) theWithCorrection - defining that the section is rotated to be orthogonal to the spine tangent in the correspondent point (0/1) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created pipe. @@ -2707,6 +3529,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): theLocations, thePath, theWithContact, theWithCorrection) RaiseIfFailed("MakePipeWithDifferentSections", self.PrimOp) + self._autoPublish(anObj, theName, "pipe") return anObj ## Create a shape by extrusion of the profile shape along @@ -2730,12 +3553,16 @@ class geompyDC(GEOM._objref_GEOM_Gen): # contact with the spine. # @param theWithCorrection - defining that the section is rotated to be # orthogonal to the spine tangent in the correspondent point + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created solids. # # @ref tui_creation_pipe_with_shell_sec "Example" - def MakePipeWithShellSections(self,theSeqBases, theSeqSubBases, + def MakePipeWithShellSections(self, theSeqBases, theSeqSubBases, theLocations, thePath, - theWithContact, theWithCorrection): + theWithContact, theWithCorrection, theName=None): """ Create a shape by extrusion of the profile shape along the path shape. The path shape can be a wire or a edge. @@ -2760,6 +3587,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): contact with the spine (0/1) theWithCorrection - defining that the section is rotated to be orthogonal to the spine tangent in the correspondent point (0/1) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created solids. @@ -2768,6 +3598,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): theLocations, thePath, theWithContact, theWithCorrection) RaiseIfFailed("MakePipeWithShellSections", self.PrimOp) + self._autoPublish(anObj, theName, "pipe") return anObj ## Create a shape by extrusion of the profile shape along @@ -2777,7 +3608,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # creating pipe between each pair of sections step by step. def MakePipeWithShellSectionsBySteps(self, theSeqBases, theSeqSubBases, theLocations, thePath, - theWithContact, theWithCorrection): + theWithContact, theWithCorrection, theName=None): """ Create a shape by extrusion of the profile shape along the path shape. This function is used only for debug pipe @@ -2812,27 +3643,36 @@ class geompyDC(GEOM._objref_GEOM_Gen): resc = self.MakeCompound(res) #resc = self.MakeSewing(res, 0.001) #print "resc: ",resc + self._autoPublish(resc, theName, "pipe") return resc ## Create solids between given sections # @param theSeqBases - list of sections (shell or face). # @param theLocations - list of corresponding vertexes + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created solids. # # @ref tui_creation_pipe_without_path "Example" - def MakePipeShellsWithoutPath(self, theSeqBases, theLocations): + def MakePipeShellsWithoutPath(self, theSeqBases, theLocations, theName=None): """ Create solids between given sections Parameters: theSeqBases - list of sections (shell or face). theLocations - list of corresponding vertexes + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created solids. """ anObj = self.PrimOp.MakePipeShellsWithoutPath(theSeqBases, theLocations) RaiseIfFailed("MakePipeShellsWithoutPath", self.PrimOp) + self._autoPublish(anObj, theName, "pipe") return anObj ## Create a shape by extrusion of the base shape along @@ -2843,10 +3683,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theVec Vector defines a constant binormal direction to keep the # same angle beetween the direction and the sections # along the sweep surface. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created pipe. # # @ref tui_creation_pipe "Example" - def MakePipeBiNormalAlongVector(self,theBase, thePath, theVec): + def MakePipeBiNormalAlongVector(self, theBase, thePath, theVec, theName=None): """ Create a shape by extrusion of the base shape along the path shape with constant bi-normal direction along the given vector. @@ -2858,6 +3702,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theVec Vector defines a constant binormal direction to keep the same angle beetween the direction and the sections along the sweep surface. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created pipe. @@ -2865,6 +3712,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.PrimOp.MakePipeBiNormalAlongVector(theBase, thePath, theVec) RaiseIfFailed("MakePipeBiNormalAlongVector", self.PrimOp) + self._autoPublish(anObj, theName, "pipe") return anObj ## Build a middle path of a pipe-like shape. @@ -2873,17 +3721,22 @@ class geompyDC(GEOM._objref_GEOM_Gen): # or a pipe-like solid. # @param theBase1, theBase2 Two bases of the supposed pipe. This # should be wires or faces of theShape. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @note It is not assumed that exact or approximate copy of theShape # can be obtained by applying existing Pipe operation on the # resulting "Path" wire taking theBase1 as the base - it is not # always possible; though in some particular cases it might work # it is not guaranteed. Thus, RestorePath function should not be # considered as an exact reverse operation of the Pipe. + # # @return New GEOM.GEOM_Object, containing an edge or wire that represent # source pipe's "path". # # @ref tui_creation_pipe_path "Example" - def RestorePath (self, theShape, theBase1, theBase2): + def RestorePath (self, theShape, theBase1, theBase2, theName=None): """ Build a middle path of a pipe-like shape. The path shape can be a wire or an edge. @@ -2893,6 +3746,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): or a pipe-like solid. theBase1, theBase2 Two bases of the supposed pipe. This should be wires or faces of theShape. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM_Object, containing an edge or wire that represent @@ -2900,6 +3756,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): """ anObj = self.PrimOp.RestorePath(theShape, theBase1, theBase2) RaiseIfFailed("RestorePath", self.PrimOp) + self._autoPublish(anObj, theName, "path") return anObj ## Build a middle path of a pipe-like shape. @@ -2908,17 +3765,22 @@ class geompyDC(GEOM._objref_GEOM_Gen): # or a pipe-like solid. # @param listEdges1, listEdges2 Two bases of the supposed pipe. This # should be lists of edges of theShape. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @note It is not assumed that exact or approximate copy of theShape # can be obtained by applying existing Pipe operation on the # resulting "Path" wire taking theBase1 as the base - it is not # always possible; though in some particular cases it might work # it is not guaranteed. Thus, RestorePath function should not be # considered as an exact reverse operation of the Pipe. + # # @return New GEOM.GEOM_Object, containing an edge or wire that represent # source pipe's "path". # # @ref tui_creation_pipe_path "Example" - def RestorePathEdges (self, theShape, listEdges1, listEdges2): + def RestorePathEdges (self, theShape, listEdges1, listEdges2, theName=None): """ Build a middle path of a pipe-like shape. The path shape can be a wire or an edge. @@ -2928,6 +3790,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): or a pipe-like solid. listEdges1, listEdges2 Two bases of the supposed pipe. This should be lists of edges of theShape. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM_Object, containing an edge or wire that represent @@ -2935,6 +3800,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): """ anObj = self.PrimOp.RestorePathEdges(theShape, listEdges1, listEdges2) RaiseIfFailed("RestorePath", self.PrimOp) + self._autoPublish(anObj, theName, "path") return anObj # end of l3_complex @@ -2946,16 +3812,23 @@ class geompyDC(GEOM._objref_GEOM_Gen): ## Create a linear edge with specified ends. # @param thePnt1 Point for the first end of edge. # @param thePnt2 Point for the second end of edge. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created edge. # # @ref tui_creation_edge "Example" - def MakeEdge(self,thePnt1, thePnt2): + def MakeEdge(self, thePnt1, thePnt2, theName=None): """ Create a linear edge with specified ends. Parameters: thePnt1 Point for the first end of edge. thePnt2 Point for the second end of edge. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created edge. @@ -2963,6 +3836,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.ShapesOp.MakeEdge(thePnt1, thePnt2) RaiseIfFailed("MakeEdge", self.ShapesOp) + self._autoPublish(anObj, theName, "edge") return anObj ## Create a new edge, corresponding to the given length on the given curve. @@ -2971,10 +3845,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theStartPoint Any point can be selected for it, the new edge will begin # at the end of \a theRefCurve, close to the selected point. # If None, start from the first point of \a theRefCurve. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created edge. # # @ref tui_creation_edge "Example" - def MakeEdgeOnCurveByLength(self, theRefCurve, theLength, theStartPoint = None): + def MakeEdgeOnCurveByLength(self, theRefCurve, theLength, theStartPoint = None, theName=None): """ Create a new edge, corresponding to the given length on the given curve. @@ -2984,6 +3862,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theStartPoint Any point can be selected for it, the new edge will begin at the end of theRefCurve, close to the selected point. If None, start from the first point of theRefCurve. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created edge. @@ -2993,16 +3874,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.ShapesOp.MakeEdgeOnCurveByLength(theRefCurve, theLength, theStartPoint) RaiseIfFailed("MakeEdgeOnCurveByLength", self.ShapesOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "edge") return anObj ## Create an edge from specified wire. # @param theWire source Wire # @param theLinearTolerance linear tolerance value (default = 1e-07) # @param theAngularTolerance angular tolerance value (default = 1e-12) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created edge. # # @ref tui_creation_edge "Example" - def MakeEdgeWire(self, theWire, theLinearTolerance = 1e-07, theAngularTolerance = 1e-12): + def MakeEdgeWire(self, theWire, theLinearTolerance = 1e-07, theAngularTolerance = 1e-12, theName=None): """ Create an edge from specified wire. @@ -3010,6 +3896,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theWire source Wire theLinearTolerance linear tolerance value (default = 1e-07) theAngularTolerance angular tolerance value (default = 1e-12) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created edge. @@ -3017,16 +3906,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.ShapesOp.MakeEdgeWire(theWire, theLinearTolerance, theAngularTolerance) RaiseIfFailed("MakeEdgeWire", self.ShapesOp) + self._autoPublish(anObj, theName, "edge") return anObj ## Create a wire from the set of edges and wires. # @param theEdgesAndWires List of edges and/or wires. # @param theTolerance Maximum distance between vertices, that will be merged. # Values less than 1e-07 are equivalent to 1e-07 (Precision::Confusion()) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created wire. # # @ref tui_creation_wire "Example" - def MakeWire(self, theEdgesAndWires, theTolerance = 1e-07): + def MakeWire(self, theEdgesAndWires, theTolerance = 1e-07, theName=None): """ Create a wire from the set of edges and wires. @@ -3034,6 +3928,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theEdgesAndWires List of edges and/or wires. theTolerance Maximum distance between vertices, that will be merged. Values less than 1e-07 are equivalent to 1e-07 (Precision::Confusion()). + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created wire. @@ -3041,6 +3938,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.ShapesOp.MakeWire(theEdgesAndWires, theTolerance) RaiseIfFailed("MakeWire", self.ShapesOp) + self._autoPublish(anObj, theName, "wire") return anObj ## Create a face on the given wire. @@ -3050,10 +3948,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # than 1e-06, this face will be returned, otherwise the # algorithm tries to build any suitable face on the given # wire and prints a warning message. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created face. # # @ref tui_creation_face "Example" - def MakeFace(self, theWire, isPlanarWanted): + def MakeFace(self, theWire, isPlanarWanted, theName=None): """ Create a face on the given wire. @@ -3064,6 +3966,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): than 1e-06, this face will be returned, otherwise the algorithm tries to build any suitable face on the given wire and prints a warning message. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created face. @@ -3074,6 +3979,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): print "WARNING: Cannot build a planar face: required tolerance is too big. Non-planar face is built." else: RaiseIfFailed("MakeFace", self.ShapesOp) + self._autoPublish(anObj, theName, "face") return anObj ## Create a face on the given wires set. @@ -3083,10 +3989,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # than 1e-06, this face will be returned, otherwise the # algorithm tries to build any suitable face on the given # wire and prints a warning message. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created face. # # @ref tui_creation_face "Example" - def MakeFaceWires(self, theWires, isPlanarWanted): + def MakeFaceWires(self, theWires, isPlanarWanted, theName=None): """ Create a face on the given wires set. @@ -3097,6 +4007,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): than 1e-06, this face will be returned, otherwise the algorithm tries to build any suitable face on the given wire and prints a warning message. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created face. @@ -3107,31 +4020,40 @@ class geompyDC(GEOM._objref_GEOM_Gen): print "WARNING: Cannot build a planar face: required tolerance is too big. Non-planar face is built." else: RaiseIfFailed("MakeFaceWires", self.ShapesOp) + self._autoPublish(anObj, theName, "face") return anObj ## See MakeFaceWires() method for details. # # @ref tui_creation_face "Example 1" # \n @ref swig_MakeFaces "Example 2" - def MakeFaces(self, theWires, isPlanarWanted): + def MakeFaces(self, theWires, isPlanarWanted, theName=None): """ See geompy.MakeFaceWires() method for details. """ # Example: see GEOM_TestOthers.py - anObj = self.MakeFaceWires(theWires, isPlanarWanted) + # note: auto-publishing is done in self.MakeFaceWires() + anObj = self.MakeFaceWires(theWires, isPlanarWanted, theName) return anObj ## Create a shell from the set of faces and shells. # @param theFacesAndShells List of faces and/or shells. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created shell. # # @ref tui_creation_shell "Example" - def MakeShell(self,theFacesAndShells): + def MakeShell(self, theFacesAndShells, theName=None): """ Create a shell from the set of faces and shells. Parameters: theFacesAndShells List of faces and/or shells. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created shell. @@ -3139,19 +4061,27 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.ShapesOp.MakeShell(theFacesAndShells) RaiseIfFailed("MakeShell", self.ShapesOp) + self._autoPublish(anObj, theName, "shell") return anObj ## Create a solid, bounded by the given shells. # @param theShells Sequence of bounding shells. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created solid. # # @ref tui_creation_solid "Example" - def MakeSolid(self, theShells): + def MakeSolid(self, theShells, theName=None): """ Create a solid, bounded by the given shells. Parameters: theShells Sequence of bounding shells. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created solid. @@ -3165,19 +4095,27 @@ class geompyDC(GEOM._objref_GEOM_Gen): raise RuntimeError, "MakeSolidShells : Unable to create solid from unclosed shape" anObj = self.ShapesOp.MakeSolidShells(theShells) RaiseIfFailed("MakeSolidShells", self.ShapesOp) + self._autoPublish(anObj, theName, "solid") return anObj ## Create a compound of the given shapes. # @param theShapes List of shapes to put in compound. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created compound. # # @ref tui_creation_compound "Example" - def MakeCompound(self,theShapes): + def MakeCompound(self, theShapes, theName=None): """ Create a compound of the given shapes. Parameters: theShapes List of shapes to put in compound. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created compound. @@ -3185,6 +4123,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.ShapesOp.MakeCompound(theShapes) RaiseIfFailed("MakeCompound", self.ShapesOp) + self._autoPublish(anObj, theName, "compound") return anObj # end of l3_advanced @@ -3283,15 +4222,22 @@ class geompyDC(GEOM._objref_GEOM_Gen): ## Reverses an orientation the given shape. # @param theShape Shape to be reversed. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return The reversed copy of theShape. # # @ref swig_ChangeOrientation "Example" - def ChangeOrientation(self,theShape): + def ChangeOrientation(self, theShape, theName=None): """ Reverses an orientation the given shape. Parameters: theShape Shape to be reversed. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: The reversed copy of theShape. @@ -3299,17 +4245,19 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.ShapesOp.ChangeOrientation(theShape) RaiseIfFailed("ChangeOrientation", self.ShapesOp) + self._autoPublish(anObj, theName, "reversed") return anObj ## See ChangeOrientation() method for details. # # @ref swig_OrientationChange "Example" - def OrientationChange(self,theShape): + def OrientationChange(self, theShape, theName=None): """ See geompy.ChangeOrientation method for details. """ # Example: see GEOM_TestOthers.py - anObj = self.ChangeOrientation(theShape) + # note: auto-publishing is done in self.ChangeOrientation() + anObj = self.ChangeOrientation(theShape, theName) return anObj # end of l3_healing @@ -3344,10 +4292,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theShape1 Shape to find sub-shapes in. # @param theShape2 Shape to find shared sub-shapes with. # @param theShapeType Type of sub-shapes to be retrieved. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of sub-shapes of theShape1, shared with theShape2. # # @ref swig_GetSharedShapes "Example" - def GetSharedShapes(self,theShape1, theShape2, theShapeType): + def GetSharedShapes(self, theShape1, theShape2, theShapeType, theName=None): """ Get all sub-shapes of theShape1 of the given type, shared with theShape2. @@ -3355,6 +4307,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShape1 Shape to find sub-shapes in. theShape2 Shape to find shared sub-shapes with. theShapeType Type of sub-shapes to be retrieved. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of sub-shapes of theShape1, shared with theShape2. @@ -3362,21 +4317,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py aList = self.ShapesOp.GetSharedShapes(theShape1, theShape2, theShapeType) RaiseIfFailed("GetSharedShapes", self.ShapesOp) + self._autoPublish(aList, theName, "shared") return aList ## Get all sub-shapes, shared by all shapes in the list theShapes. # @param theShapes Shapes to find common sub-shapes of. # @param theShapeType Type of sub-shapes to be retrieved (see ShapeType()) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of objects, that are sub-shapes of all given shapes. # # @ref swig_GetSharedShapes "Example" - def GetSharedShapesMulti(self, theShapes, theShapeType): + def GetSharedShapesMulti(self, theShapes, theShapeType, theName=None): """ Get all sub-shapes, shared by all shapes in the list theShapes. Parameters: theShapes Shapes to find common sub-shapes of. theShapeType Type of sub-shapes to be retrieved (see geompy.ShapeType) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of GEOM.GEOM_Object, that are sub-shapes of all given shapes. @@ -3384,6 +4347,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py aList = self.ShapesOp.GetSharedShapesMulti(theShapes, theShapeType) RaiseIfFailed("GetSharedShapesMulti", self.ShapesOp) + self._autoPublish(aList, theName, "shared") return aList ## Find in theShape all sub-shapes of type theShapeType, @@ -3394,10 +4358,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theAx1 Vector (or line, or linear edge), specifying normal # direction and location of the plane to find shapes on. # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of all found sub-shapes. # # @ref swig_GetShapesOnPlane "Example" - def GetShapesOnPlane(self,theShape, theShapeType, theAx1, theState): + def GetShapesOnPlane(self, theShape, theShapeType, theAx1, theState, theName=None): """ Find in theShape all sub-shapes of type theShapeType, situated relatively the specified plane by the certain way, @@ -3409,6 +4377,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theAx1 Vector (or line, or linear edge), specifying normal direction and location of the plane to find shapes on. theState The state of the sub-shapes to find (see GEOM::shape_state) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of all found sub-shapes. @@ -3416,6 +4387,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py aList = self.ShapesOp.GetShapesOnPlane(theShape, theShapeType, theAx1, theState) RaiseIfFailed("GetShapesOnPlane", self.ShapesOp) + self._autoPublish(aList, theName, "shapeOnPlane") return aList ## Find in theShape all sub-shapes of type theShapeType, @@ -3426,10 +4398,11 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theAx1 Vector (or line, or linear edge), specifying normal # direction and location of the plane to find shapes on. # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # # @return List of all found sub-shapes indices. # # @ref swig_GetShapesOnPlaneIDs "Example" - def GetShapesOnPlaneIDs(self,theShape, theShapeType, theAx1, theState): + def GetShapesOnPlaneIDs(self, theShape, theShapeType, theAx1, theState): """ Find in theShape all sub-shapes of type theShapeType, situated relatively the specified plane by the certain way, @@ -3459,10 +4432,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # direction of the plane to find shapes on. # @param thePnt Point specifying location of the plane to find shapes on. # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of all found sub-shapes. # # @ref swig_GetShapesOnPlaneWithLocation "Example" - def GetShapesOnPlaneWithLocation(self, theShape, theShapeType, theAx1, thePnt, theState): + def GetShapesOnPlaneWithLocation(self, theShape, theShapeType, theAx1, thePnt, theState, theName=None): """ Find in theShape all sub-shapes of type theShapeType, situated relatively the specified plane by the certain way, @@ -3475,6 +4452,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): direction and location of the plane to find shapes on. thePnt Point specifying location of the plane to find shapes on. theState The state of the sub-shapes to find (see GEOM::shape_state) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of all found sub-shapes. @@ -3483,6 +4463,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): aList = self.ShapesOp.GetShapesOnPlaneWithLocation(theShape, theShapeType, theAx1, thePnt, theState) RaiseIfFailed("GetShapesOnPlaneWithLocation", self.ShapesOp) + self._autoPublish(aList, theName, "shapeOnPlane") return aList ## Find in theShape all sub-shapes of type theShapeType, @@ -3494,6 +4475,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # direction of the plane to find shapes on. # @param thePnt Point specifying location of the plane to find shapes on. # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # # @return List of all found sub-shapes indices. # # @ref swig_GetShapesOnPlaneWithLocationIDs "Example" @@ -3528,10 +4510,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # axis of the cylinder to find shapes on. # @param theRadius Radius of the cylinder to find shapes on. # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of all found sub-shapes. # # @ref swig_GetShapesOnCylinder "Example" - def GetShapesOnCylinder(self, theShape, theShapeType, theAxis, theRadius, theState): + def GetShapesOnCylinder(self, theShape, theShapeType, theAxis, theRadius, theState, theName=None): """ Find in theShape all sub-shapes of type theShapeType, situated relatively the specified cylinder by the certain way, defined through theState parameter. @@ -3543,6 +4529,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): axis of the cylinder to find shapes on. theRadius Radius of the cylinder to find shapes on. theState The state of the sub-shapes to find (see GEOM::shape_state) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of all found sub-shapes. @@ -3550,6 +4539,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py aList = self.ShapesOp.GetShapesOnCylinder(theShape, theShapeType, theAxis, theRadius, theState) RaiseIfFailed("GetShapesOnCylinder", self.ShapesOp) + self._autoPublish(aList, theName, "shapeOnCylinder") return aList ## Find in \a theShape all sub-shapes of type \a theShapeType, situated relatively @@ -3560,6 +4550,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # axis of the cylinder to find shapes on. # @param theRadius Radius of the cylinder to find shapes on. # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # # @return List of all found sub-shapes indices. # # @ref swig_GetShapesOnCylinderIDs "Example" @@ -3593,10 +4584,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param thePnt Point specifying location of the bottom of the cylinder. # @param theRadius Radius of the cylinder to find shapes on. # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of all found sub-shapes. # # @ref swig_GetShapesOnCylinderWithLocation "Example" - def GetShapesOnCylinderWithLocation(self, theShape, theShapeType, theAxis, thePnt, theRadius, theState): + def GetShapesOnCylinderWithLocation(self, theShape, theShapeType, theAxis, thePnt, theRadius, theState, theName=None): """ Find in theShape all sub-shapes of type theShapeType, situated relatively the specified cylinder by the certain way, defined through theState parameter. @@ -3608,6 +4603,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): axis of the cylinder to find shapes on. theRadius Radius of the cylinder to find shapes on. theState The state of the sub-shapes to find (see GEOM::shape_state) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of all found sub-shapes. @@ -3615,6 +4613,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py aList = self.ShapesOp.GetShapesOnCylinderWithLocation(theShape, theShapeType, theAxis, thePnt, theRadius, theState) RaiseIfFailed("GetShapesOnCylinderWithLocation", self.ShapesOp) + self._autoPublish(aList, theName, "shapeOnCylinder") return aList ## Find in \a theShape all sub-shapes of type \a theShapeType, situated relatively @@ -3626,6 +4625,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param thePnt Point specifying location of the bottom of the cylinder. # @param theRadius Radius of the cylinder to find shapes on. # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # # @return List of all found sub-shapes indices # # @ref swig_GetShapesOnCylinderWithLocationIDs "Example" @@ -3657,10 +4657,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theCenter Point, specifying center of the sphere to find shapes on. # @param theRadius Radius of the sphere to find shapes on. # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of all found sub-shapes. # # @ref swig_GetShapesOnSphere "Example" - def GetShapesOnSphere(self,theShape, theShapeType, theCenter, theRadius, theState): + def GetShapesOnSphere(self, theShape, theShapeType, theCenter, theRadius, theState, theName=None): """ Find in theShape all sub-shapes of type theShapeType, situated relatively the specified sphere by the certain way, defined through theState parameter. @@ -3671,6 +4675,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theCenter Point, specifying center of the sphere to find shapes on. theRadius Radius of the sphere to find shapes on. theState The state of the sub-shapes to find (see GEOM::shape_state) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of all found sub-shapes. @@ -3678,6 +4685,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py aList = self.ShapesOp.GetShapesOnSphere(theShape, theShapeType, theCenter, theRadius, theState) RaiseIfFailed("GetShapesOnSphere", self.ShapesOp) + self._autoPublish(aList, theName, "shapeOnSphere") return aList ## Find in \a theShape all sub-shapes of type \a theShapeType, situated relatively @@ -3687,10 +4695,11 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theCenter Point, specifying center of the sphere to find shapes on. # @param theRadius Radius of the sphere to find shapes on. # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # # @return List of all found sub-shapes indices. # # @ref swig_GetShapesOnSphereIDs "Example" - def GetShapesOnSphereIDs(self,theShape, theShapeType, theCenter, theRadius, theState): + def GetShapesOnSphereIDs(self, theShape, theShapeType, theCenter, theRadius, theState): """ Find in theShape all sub-shapes of type theShapeType, situated relatively the specified sphere by the certain way, defined through theState parameter. @@ -3719,12 +4728,16 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theBottomLeftPoint Point, specifying bottom left corner of a quadrangle # @param theBottomRigthPoint Point, specifying bottom right corner of a quadrangle # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of all found sub-shapes. # # @ref swig_GetShapesOnQuadrangle "Example" def GetShapesOnQuadrangle(self, theShape, theShapeType, theTopLeftPoint, theTopRigthPoint, - theBottomLeftPoint, theBottomRigthPoint, theState): + theBottomLeftPoint, theBottomRigthPoint, theState, theName=None): """ Find in theShape all sub-shapes of type theShapeType, situated relatively the specified quadrangle by the certain way, defined through theState parameter. @@ -3737,6 +4750,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theBottomLeftPoint Point, specifying bottom left corner of a quadrangle theBottomRigthPoint Point, specifying bottom right corner of a quadrangle theState The state of the sub-shapes to find (see GEOM::shape_state) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of all found sub-shapes. @@ -3746,6 +4762,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): theTopLeftPoint, theTopRigthPoint, theBottomLeftPoint, theBottomRigthPoint, theState) RaiseIfFailed("GetShapesOnQuadrangle", self.ShapesOp) + self._autoPublish(aList, theName, "shapeOnQuadrangle") return aList ## Find in \a theShape all sub-shapes of type \a theShapeType, situated relatively @@ -3757,6 +4774,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theBottomLeftPoint Point, specifying bottom left corner of a quadrangle # @param theBottomRigthPoint Point, specifying bottom right corner of a quadrangle # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # # @return List of all found sub-shapes indices. # # @ref swig_GetShapesOnQuadrangleIDs "Example" @@ -3793,10 +4811,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theShape Shape to find sub-shapes of. # @param theShapeType Type of sub-shapes to be retrieved (see ShapeType()) # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of all found sub-shapes. # # @ref swig_GetShapesOnBox "Example" - def GetShapesOnBox(self, theBox, theShape, theShapeType, theState): + def GetShapesOnBox(self, theBox, theShape, theShapeType, theState, theName=None): """ Find in theShape all sub-shapes of type theShapeType, situated relatively the specified theBox by the certain way, defined through theState parameter. @@ -3806,6 +4828,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShape Shape to find sub-shapes of. theShapeType Type of sub-shapes to be retrieved (see geompy.ShapeType) theState The state of the sub-shapes to find (see GEOM::shape_state) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of all found sub-shapes. @@ -3813,6 +4838,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py aList = self.ShapesOp.GetShapesOnBox(theBox, theShape, theShapeType, theState) RaiseIfFailed("GetShapesOnBox", self.ShapesOp) + self._autoPublish(aList, theName, "shapeOnBox") return aList ## Find in \a theShape all sub-shapes of type \a theShapeType, situated relatively @@ -3821,6 +4847,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theShape Shape to find sub-shapes of. # @param theShapeType Type of sub-shapes to be retrieved (see ShapeType()) # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # # @return List of all found sub-shapes indices. # # @ref swig_GetShapesOnBoxIDs "Example" @@ -3850,10 +4877,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theShape Shape to find sub-shapes of. # @param theShapeType Type of sub-shapes to be retrieved (see ShapeType()) # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of all found sub-shapes. # # @ref swig_GetShapesOnShape "Example" - def GetShapesOnShape(self, theCheckShape, theShape, theShapeType, theState): + def GetShapesOnShape(self, theCheckShape, theShape, theShapeType, theState, theName=None): """ Find in theShape all sub-shapes of type theShapeType, situated relatively the specified theCheckShape by the @@ -3864,6 +4895,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShape Shape to find sub-shapes of. theShapeType Type of sub-shapes to be retrieved (see geompy.ShapeType) theState The state of the sub-shapes to find (see GEOM::shape_state) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of all found sub-shapes. @@ -3872,6 +4906,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): aList = self.ShapesOp.GetShapesOnShape(theCheckShape, theShape, theShapeType, theState) RaiseIfFailed("GetShapesOnShape", self.ShapesOp) + self._autoPublish(aList, theName, "shapeOnShape") return aList ## Find in \a theShape all sub-shapes of type \a theShapeType, @@ -3881,10 +4916,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theShape Shape to find sub-shapes of. # @param theShapeType Type of sub-shapes to be retrieved (see ShapeType()) # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return All found sub-shapes as compound. # # @ref swig_GetShapesOnShapeAsCompound "Example" - def GetShapesOnShapeAsCompound(self, theCheckShape, theShape, theShapeType, theState): + def GetShapesOnShapeAsCompound(self, theCheckShape, theShape, theShapeType, theState, theName=None): """ Find in theShape all sub-shapes of type theShapeType, situated relatively the specified theCheckShape by the @@ -3895,6 +4934,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShape Shape to find sub-shapes of. theShapeType Type of sub-shapes to be retrieved (see geompy.ShapeType) theState The state of the sub-shapes to find (see GEOM::shape_state) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: All found sub-shapes as compound. @@ -3903,6 +4945,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.ShapesOp.GetShapesOnShapeAsCompound(theCheckShape, theShape, theShapeType, theState) RaiseIfFailed("GetShapesOnShapeAsCompound", self.ShapesOp) + self._autoPublish(anObj, theName, "shapeOnShape") return anObj ## Find in \a theShape all sub-shapes of type \a theShapeType, @@ -3912,6 +4955,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theShape Shape to find sub-shapes of. # @param theShapeType Type of sub-shapes to be retrieved (see ShapeType()) # @param theState The state of the sub-shapes to find (see GEOM::shape_state) + # # @return List of all found sub-shapes indices. # # @ref swig_GetShapesOnShapeIDs "Example" @@ -3942,6 +4986,10 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theShapeWhat Shape, specifying what to find. # @param isNewImplementation implementation of GetInPlace functionality # (default = False, old alghorithm based on shape properties) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return Group of all found sub-shapes or a single found sub-shape. # # @note This function has a restriction on argument shapes. @@ -3951,7 +4999,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @image html get_in_place_lost_part.png # # @ref swig_GetInPlace "Example" - def GetInPlace(self, theShapeWhere, theShapeWhat, isNewImplementation = False): + def GetInPlace(self, theShapeWhere, theShapeWhat, isNewImplementation = False, theName=None): """ Get sub-shape(s) of theShapeWhere, which are coincident with theShapeWhat or could be a part of it. @@ -3961,6 +5009,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShapeWhat Shape, specifying what to find. isNewImplementation Implementation of GetInPlace functionality (default = False, old alghorithm based on shape properties) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: Group of all found sub-shapes or a single found sub-shape. @@ -3980,6 +5031,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.ShapesOp.GetInPlaceOld(theShapeWhere, theShapeWhat) pass RaiseIfFailed("GetInPlace", self.ShapesOp) + self._autoPublish(anObj, theName, "inplace") return anObj ## Get sub-shape(s) of \a theShapeWhere, which are @@ -3994,10 +5046,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theShapeWhere Shape to find sub-shapes of. # @param theShapeWhat Shape, specifying what to find (must be in the # building history of the ShapeWhere). + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return Group of all found sub-shapes or a single found sub-shape. # # @ref swig_GetInPlace "Example" - def GetInPlaceByHistory(self, theShapeWhere, theShapeWhat): + def GetInPlaceByHistory(self, theShapeWhere, theShapeWhat, theName=None): """ Implementation of this method is based on a saved history of an operation, produced theShapeWhere. The theShapeWhat must be among this operation's @@ -4009,6 +5065,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShapeWhere Shape to find sub-shapes of. theShapeWhat Shape, specifying what to find (must be in the building history of the ShapeWhere). + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: Group of all found sub-shapes or a single found sub-shape. @@ -4016,16 +5075,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py anObj = self.ShapesOp.GetInPlaceByHistory(theShapeWhere, theShapeWhat) RaiseIfFailed("GetInPlaceByHistory", self.ShapesOp) + self._autoPublish(anObj, theName, "inplace") return anObj ## Get sub-shape of theShapeWhere, which is # equal to \a theShapeWhat. # @param theShapeWhere Shape to find sub-shape of. # @param theShapeWhat Shape, specifying what to find. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object for found sub-shape. # # @ref swig_GetSame "Example" - def GetSame(self,theShapeWhere, theShapeWhat): + def GetSame(self, theShapeWhere, theShapeWhat, theName=None): """ Get sub-shape of theShapeWhere, which is equal to theShapeWhat. @@ -4033,12 +5097,16 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theShapeWhere Shape to find sub-shape of. theShapeWhat Shape, specifying what to find. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object for found sub-shape. """ anObj = self.ShapesOp.GetSame(theShapeWhere, theShapeWhat) RaiseIfFailed("GetSame", self.ShapesOp) + self._autoPublish(anObj, theName, "sameShape") return anObj @@ -4049,7 +5117,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @return List of all found sub-shapes indices. # # @ref swig_GetSame "Example" - def GetSameIDs(self,theShapeWhere, theShapeWhat): + def GetSameIDs(self, theShapeWhere, theShapeWhat): """ Get sub-shape indices of theShapeWhere, which is equal to theShapeWhat. @@ -4076,23 +5144,31 @@ class geompyDC(GEOM._objref_GEOM_Gen): # of aShape, selected by their unique IDs inside aShape # @param aShape Shape to get sub-shape of. # @param ListOfID List of sub-shapes indices. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return Found sub-shape. # # @ref swig_all_decompose "Example" - def GetSubShape(self, aShape, ListOfID): + def GetSubShape(self, aShape, ListOfID, theName=None): """ Obtain a composite sub-shape of aShape, composed from sub-shapes of aShape, selected by their unique IDs inside aShape Parameters: - aShape Shape to get sub-shape of. - ListOfID List of sub-shapes indices. + aShape Shape to get sub-shape of. + ListOfID List of sub-shapes indices. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: Found sub-shape. """ # Example: see GEOM_TestAll.py anObj = self.AddSubShape(aShape,ListOfID) + self._autoPublish(anObj, theName, "subshape") return anObj ## Obtain unique ID of sub-shape aSubShape inside aShape @@ -4118,6 +5194,32 @@ class geompyDC(GEOM._objref_GEOM_Gen): anID = self.LocalOp.GetSubShapeIndex(aShape, aSubShape) RaiseIfFailed("GetSubShapeIndex", self.LocalOp) return anID + + ## Obtain unique IDs of sub-shapes aSubShapes inside aShape + # This function is provided for performance purpose. The complexity is O(n) with n + # the number of subobjects of aShape + # @param aShape Shape to get sub-shape of. + # @param aSubShapes Sub-shapes of aShape. + # @return list of IDs of found sub-shapes. + # + # @ref swig_all_decompose "Example" + def GetSubShapesIDs(self, aShape, aSubShapes): + """ + Obtain a list of IDs of sub-shapes aSubShapes inside aShape + This function is provided for performance purpose. The complexity is O(n) with n + the number of subobjects of aShape + + Parameters: + aShape Shape to get sub-shape of. + aSubShapes Sub-shapes of aShape. + + Returns: + List of IDs of found sub-shape. + """ + # Example: see GEOM_TestAll.py + anIDs = self.ShapesOp.GetSubShapesIndices(aShape, aSubShapes) + RaiseIfFailed("GetSubShapesIndices", self.ShapesOp) + return anIDs # end of l4_access ## @} @@ -4177,10 +5279,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # If the shape itself matches the type, it is also returned. # @param aShape Shape to be exploded. # @param aType Type of sub-shapes to be retrieved (see ShapeType()) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of sub-shapes of type theShapeType, contained in theShape. # # @ref swig_all_decompose "Example" - def SubShapeAll(self, aShape, aType): + def SubShapeAll(self, aShape, aType, theName=None): """ Explode a shape on sub-shapes of a given type. If the shape itself matches the type, it is also returned. @@ -4188,6 +5294,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: aShape Shape to be exploded. aType Type of sub-shapes to be retrieved (see geompy.ShapeType) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of sub-shapes of type theShapeType, contained in theShape. @@ -4195,6 +5304,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py ListObj = self.ShapesOp.MakeAllSubShapes(aShape, EnumToLong( aType ), False) RaiseIfFailed("SubShapeAll", self.ShapesOp) + self._autoPublish(ListObj, theName, "subshape") return ListObj ## Explode a shape on sub-shapes of a given type. @@ -4224,10 +5334,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param aShape Shape to get sub-shape of. # @param ListOfInd List of sub-shapes indices. # @param aType Type of sub-shapes to be retrieved (see ShapeType()) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return A compound of sub-shapes of aShape. # # @ref swig_all_decompose "Example" - def SubShape(self, aShape, aType, ListOfInd): + def SubShape(self, aShape, aType, ListOfInd, theName=None): """ Obtain a compound of sub-shapes of aShape, selected by they indices in list of all sub-shapes of type aType. @@ -4237,6 +5351,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): aShape Shape to get sub-shape of. ListOfID List of sub-shapes indices. aType Type of sub-shapes to be retrieved (see geompy.ShapeType) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: A compound of sub-shapes of aShape. @@ -4246,7 +5363,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): AllShapeIDsList = self.SubShapeAllIDs(aShape, EnumToLong( aType )) for ind in ListOfInd: ListOfIDs.append(AllShapeIDsList[ind - 1]) - anObj = self.GetSubShape(aShape, ListOfIDs) + # note: auto-publishing is done in self.GetSubShape() + anObj = self.GetSubShape(aShape, ListOfIDs, theName) return anObj ## Explode a shape on sub-shapes of a given type. @@ -4254,10 +5372,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # If the shape itself matches the type, it is also returned. # @param aShape Shape to be exploded. # @param aType Type of sub-shapes to be retrieved (see ShapeType()) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of sub-shapes of type theShapeType, contained in theShape. # # @ref swig_SubShapeAllSorted "Example" - def SubShapeAllSortedCentres(self, aShape, aType): + def SubShapeAllSortedCentres(self, aShape, aType, theName=None): """ Explode a shape on sub-shapes of a given type. Sub-shapes will be sorted by coordinates of their gravity centers. @@ -4266,6 +5388,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: aShape Shape to be exploded. aType Type of sub-shapes to be retrieved (see geompy.ShapeType) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of sub-shapes of type theShapeType, contained in theShape. @@ -4273,6 +5398,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py ListObj = self.ShapesOp.MakeAllSubShapes(aShape, EnumToLong( aType ), True) RaiseIfFailed("SubShapeAllSortedCentres", self.ShapesOp) + self._autoPublish(ListObj, theName, "subshape") return ListObj ## Explode a shape on sub-shapes of a given type. @@ -4304,10 +5430,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param aShape Shape to get sub-shape of. # @param ListOfInd List of sub-shapes indices. # @param aType Type of sub-shapes to be retrieved (see ShapeType()) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return A compound of sub-shapes of aShape. # # @ref swig_all_decompose "Example" - def SubShapeSortedCentres(self, aShape, aType, ListOfInd): + def SubShapeSortedCentres(self, aShape, aType, ListOfInd, theName=None): """ Obtain a compound of sub-shapes of aShape, selected by they indices in sorted list of all sub-shapes of type aType. @@ -4317,6 +5447,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): aShape Shape to get sub-shape of. ListOfID List of sub-shapes indices. aType Type of sub-shapes to be retrieved (see geompy.ShapeType) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: A compound of sub-shapes of aShape. @@ -4326,17 +5459,22 @@ class geompyDC(GEOM._objref_GEOM_Gen): AllShapeIDsList = self.SubShapeAllSortedCentresIDs(aShape, EnumToLong( aType )) for ind in ListOfInd: ListOfIDs.append(AllShapeIDsList[ind - 1]) - anObj = self.GetSubShape(aShape, ListOfIDs) + # note: auto-publishing is done in self.GetSubShape() + anObj = self.GetSubShape(aShape, ListOfIDs, theName) return anObj ## Extract shapes (excluding the main shape) of given type. # @param aShape The shape. # @param aType The shape type (see ShapeType()) # @param isSorted Boolean flag to switch sorting on/off. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of sub-shapes of type aType, contained in aShape. # # @ref swig_FilletChamfer "Example" - def ExtractShapes(self, aShape, aType, isSorted = False): + def ExtractShapes(self, aShape, aType, isSorted = False, theName=None): """ Extract shapes (excluding the main shape) of given type. @@ -4344,6 +5482,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): aShape The shape. aType The shape type (see geompy.ShapeType) isSorted Boolean flag to switch sorting on/off. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of sub-shapes of type aType, contained in aShape. @@ -4351,21 +5492,28 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py ListObj = self.ShapesOp.ExtractSubShapes(aShape, EnumToLong( aType ), isSorted) RaiseIfFailed("ExtractSubShapes", self.ShapesOp) + self._autoPublish(ListObj, theName, "subshape") return ListObj ## Get a set of sub-shapes defined by their unique IDs inside aShape # @param aShape Main shape. # @param anIDs List of unique IDs of sub-shapes inside aShape. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. # @return List of GEOM.GEOM_Object, corresponding to found sub-shapes. # # @ref swig_all_decompose "Example" - def SubShapes(self, aShape, anIDs): + def SubShapes(self, aShape, anIDs, theName=None): """ Get a set of sub-shapes defined by their unique IDs inside theMainShape Parameters: aShape Main shape. anIDs List of unique IDs of sub-shapes inside theMainShape. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of GEOM.GEOM_Object, corresponding to found sub-shapes. @@ -4373,6 +5521,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py ListObj = self.ShapesOp.MakeSubShapes(aShape, anIDs) RaiseIfFailed("SubShapes", self.ShapesOp) + self._autoPublish(ListObj, theName, "subshape") return ListObj # end of l4_decompose @@ -4384,7 +5533,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): ## Deprecated method # It works like SubShapeAllSortedCentres(), but wrongly # defines centres of faces, shells and solids. - def SubShapeAllSorted(self, aShape, aType): + def SubShapeAllSorted(self, aShape, aType, theName=None): """ Deprecated method It works like geompy.SubShapeAllSortedCentres, but wrongly @@ -4392,6 +5541,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): """ ListObj = self.ShapesOp.MakeExplode(aShape, EnumToLong( aType ), True) RaiseIfFailed("MakeExplode", self.ShapesOp) + self._autoPublish(ListObj, theName, "subshape") return ListObj ## Deprecated method @@ -4410,7 +5560,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): ## Deprecated method # It works like SubShapeSortedCentres(), but has a bug # (wrongly defines centres of faces, shells and solids). - def SubShapeSorted(self, aShape, aType, ListOfInd): + def SubShapeSorted(self, aShape, aType, ListOfInd, theName=None): """ Deprecated method It works like geompy.SubShapeSortedCentres, but has a bug @@ -4420,7 +5570,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): AllShapeIDsList = self.SubShapeAllSortedIDs(aShape, EnumToLong( aType )) for ind in ListOfInd: ListOfIDs.append(AllShapeIDsList[ind - 1]) - anObj = self.GetSubShape(aShape, ListOfIDs) + # note: auto-publishing is done in self.GetSubShape() + anObj = self.GetSubShape(aShape, ListOfIDs, theName) return anObj # end of l4_decompose_d @@ -4436,7 +5587,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): # ("FixShape.Tolerance3d", "SplitClosedFaces.NbSplitPoints", etc.). # @param theValues List of values of parameters, in the same order # as parameters are listed in theParameters list. - # + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. # # Operators and Parameters: \n # @@ -4508,7 +5661,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @return New GEOM.GEOM_Object, containing processed shape. # # \n @ref tui_shape_processing "Example" - def ProcessShape(self, theShape, theOperators, theParameters, theValues): + def ProcessShape(self, theShape, theOperators, theParameters, theValues, theName=None): """ Apply a sequence of Shape Healing operators to the given object. @@ -4519,7 +5672,11 @@ class geompyDC(GEOM._objref_GEOM_Gen): theOperators List of names of operators ("FixShape", "SplitClosedFaces", etc.). theParameters List of names of parameters ("FixShape.Tolerance3d", "SplitClosedFaces.NbSplitPoints", etc.). - Operators and Parameters: + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Operators and Parameters: * FixShape - corrects invalid shapes. * FixShape.Tolerance3d - work tolerance for detection of the problems and correction of them. @@ -4598,16 +5755,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters = ":" + Parameters pass anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "healed") return anObj ## Remove faces from the given object (shape). # @param theObject Shape to be processed. # @param theFaces Indices of faces to be removed, if EMPTY then the method # removes ALL faces of the given object. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing processed shape. # # @ref tui_suppress_faces "Example" - def SuppressFaces(self,theObject, theFaces): + def SuppressFaces(self, theObject, theFaces, theName=None): """ Remove faces from the given object (shape). @@ -4615,6 +5777,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theObject Shape to be processed. theFaces Indices of faces to be removed, if EMPTY then the method removes ALL faces of the given object. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing processed shape. @@ -4622,41 +5787,57 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestHealing.py anObj = self.HealOp.SuppressFaces(theObject, theFaces) RaiseIfFailed("SuppressFaces", self.HealOp) + self._autoPublish(anObj, theName, "suppressFaces") return anObj ## Sewing of some shapes into single shape. # @param ListShape Shapes to be processed. # @param theTolerance Required tolerance value. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing processed shape. # # @ref tui_sewing "Example" - def MakeSewing(self, ListShape, theTolerance): + def MakeSewing(self, ListShape, theTolerance, theName=None): """ Sewing of some shapes into single shape. Parameters: ListShape Shapes to be processed. theTolerance Required tolerance value. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing processed shape. """ # Example: see GEOM_TestHealing.py comp = self.MakeCompound(ListShape) - anObj = self.Sew(comp, theTolerance) + # note: auto-publishing is done in self.Sew() + anObj = self.Sew(comp, theTolerance, theName) return anObj ## Sewing of the given object. # @param theObject Shape to be processed. # @param theTolerance Required tolerance value. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing processed shape. - def Sew(self, theObject, theTolerance): + def Sew(self, theObject, theTolerance, theName=None): """ Sewing of the given object. Parameters: theObject Shape to be processed. theTolerance Required tolerance value. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing processed shape. @@ -4666,16 +5847,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.HealOp.Sew(theObject, theTolerance) RaiseIfFailed("Sew", self.HealOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "sewed") return anObj ## Remove internal wires and edges from the given object (face). # @param theObject Shape to be processed. # @param theWires Indices of wires to be removed, if EMPTY then the method # removes ALL internal wires of the given object. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing processed shape. # # @ref tui_suppress_internal_wires "Example" - def SuppressInternalWires(self,theObject, theWires): + def SuppressInternalWires(self, theObject, theWires, theName=None): """ Remove internal wires and edges from the given object (face). @@ -4683,6 +5869,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theObject Shape to be processed. theWires Indices of wires to be removed, if EMPTY then the method removes ALL internal wires of the given object. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing processed shape. @@ -4690,16 +5879,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestHealing.py anObj = self.HealOp.RemoveIntWires(theObject, theWires) RaiseIfFailed("RemoveIntWires", self.HealOp) + self._autoPublish(anObj, theName, "suppressWires") return anObj ## Remove internal closed contours (holes) from the given object. # @param theObject Shape to be processed. # @param theWires Indices of wires to be removed, if EMPTY then the method # removes ALL internal holes of the given object + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing processed shape. # # @ref tui_suppress_holes "Example" - def SuppressHoles(self,theObject, theWires): + def SuppressHoles(self, theObject, theWires, theName=None): """ Remove internal closed contours (holes) from the given object. @@ -4707,6 +5901,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theObject Shape to be processed. theWires Indices of wires to be removed, if EMPTY then the method removes ALL internal holes of the given object + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing processed shape. @@ -4714,6 +5911,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestHealing.py anObj = self.HealOp.FillHoles(theObject, theWires) RaiseIfFailed("FillHoles", self.HealOp) + self._autoPublish(anObj, theName, "suppressHoles") return anObj ## Close an open wire. @@ -4722,10 +5920,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # if [ ], then theObject itself is a wire. # @param isCommonVertex If True : closure by creation of a common vertex, # If False : closure by creation of an edge between ends. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing processed shape. # # @ref tui_close_contour "Example" - def CloseContour(self,theObject, theWires, isCommonVertex): + def CloseContour(self,theObject, theWires, isCommonVertex, theName=None): """ Close an open wire. @@ -4735,6 +5937,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): if [ ], then theObject itself is a wire. isCommonVertex If True : closure by creation of a common vertex, If False : closure by creation of an edge between ends. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing processed shape. @@ -4742,6 +5947,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestHealing.py anObj = self.HealOp.CloseContour(theObject, theWires, isCommonVertex) RaiseIfFailed("CloseContour", self.HealOp) + self._autoPublish(anObj, theName, "closeContour") return anObj ## Addition of a point to a given edge object. @@ -4752,10 +5958,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # depending on \a isByParameter. # @param isByParameter If TRUE : \a theValue is treated as a curve parameter [0..1], \n # if FALSE : \a theValue is treated as a length parameter [0..1] + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing processed shape. # # @ref tui_add_point_on_edge "Example" - def DivideEdge(self,theObject, theEdgeIndex, theValue, isByParameter): + def DivideEdge(self, theObject, theEdgeIndex, theValue, isByParameter, theName=None): """ Addition of a point to a given edge object. @@ -4767,6 +5977,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): depending on isByParameter. isByParameter If TRUE : theValue is treated as a curve parameter [0..1], if FALSE : theValue is treated as a length parameter [0..1] + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing processed shape. @@ -4776,16 +5989,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.HealOp.DivideEdge(theObject, theEdgeIndex, theValue, isByParameter) RaiseIfFailed("DivideEdge", self.HealOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "divideEdge") return anObj ## Suppress the vertices in the wire in case if adjacent edges are C1 continuous. # @param theWire Wire to minimize the number of C1 continuous edges in. # @param theVertices A list of vertices to suppress. If the list # is empty, all vertices in a wire will be assumed. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object with modified wire. # # @ref tui_fuse_collinear_edges "Example" - def FuseCollinearEdgesWithinWire(self, theWire, theVertices = []): + def FuseCollinearEdgesWithinWire(self, theWire, theVertices = [], theName=None): """ Suppress the vertices in the wire in case if adjacent edges are C1 continuous. @@ -4793,12 +6011,16 @@ class geompyDC(GEOM._objref_GEOM_Gen): theWire Wire to minimize the number of C1 continuous edges in. theVertices A list of vertices to suppress. If the list is empty, all vertices in a wire will be assumed. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object with modified wire. """ anObj = self.HealOp.FuseCollinearEdgesWithinWire(theWire, theVertices) RaiseIfFailed("FuseCollinearEdgesWithinWire", self.HealOp) + self._autoPublish(anObj, theName, "fuseEdges") return anObj ## Change orientation of the given object. Updates given shape. @@ -4822,60 +6044,83 @@ class geompyDC(GEOM._objref_GEOM_Gen): ## Change orientation of the given object. # @param theObject Shape to be processed. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing processed shape. # # @ref swig_todo "Example" - def ChangeOrientationShellCopy(self, theObject): + def ChangeOrientationShellCopy(self, theObject, theName=None): """ Change orientation of the given object. Parameters: theObject Shape to be processed. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing processed shape. """ anObj = self.HealOp.ChangeOrientationCopy(theObject) RaiseIfFailed("ChangeOrientationCopy", self.HealOp) + self._autoPublish(anObj, theName, "reversed") return anObj ## Try to limit tolerance of the given object by value \a theTolerance. # @param theObject Shape to be processed. # @param theTolerance Required tolerance value. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing processed shape. # # @ref tui_limit_tolerance "Example" - def LimitTolerance(self, theObject, theTolerance = 1e-07): + def LimitTolerance(self, theObject, theTolerance = 1e-07, theName=None): """ Try to limit tolerance of the given object by value theTolerance. Parameters: theObject Shape to be processed. theTolerance Required tolerance value. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing processed shape. """ anObj = self.HealOp.LimitTolerance(theObject, theTolerance) RaiseIfFailed("LimitTolerance", self.HealOp) + self._autoPublish(anObj, theName, "limitTolerance") return anObj ## Get a list of wires (wrapped in GEOM.GEOM_Object-s), # that constitute a free boundary of the given shape. # @param theObject Shape to get free boundary of. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return [\a status, \a theClosedWires, \a theOpenWires] # \n \a status: FALSE, if an error(s) occured during the method execution. # \n \a theClosedWires: Closed wires on the free boundary of the given shape. # \n \a theOpenWires: Open wires on the free boundary of the given shape. # # @ref tui_measurement_tools_page "Example" - def GetFreeBoundary(self, theObject): + def GetFreeBoundary(self, theObject, theName=None): """ Get a list of wires (wrapped in GEOM.GEOM_Object-s), that constitute a free boundary of the given shape. Parameters: theObject Shape to get free boundary of. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: [status, theClosedWires, theOpenWires] @@ -4886,6 +6131,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestHealing.py anObj = self.HealOp.GetFreeBoundary(theObject) RaiseIfFailed("GetFreeBoundary", self.HealOp) + self._autoPublish(anObj[1], theName, "closedWire") + self._autoPublish(anObj[2], theName, "openWire") return anObj ## Replace coincident faces in theShape by one face. @@ -4893,10 +6140,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theTolerance Maximum distance between faces, which can be considered as coincident. # @param doKeepNonSolids If FALSE, only solids will present in the result, # otherwise all initial shapes. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing a copy of theShape without coincident faces. # # @ref tui_glue_faces "Example" - def MakeGlueFaces(self, theShape, theTolerance, doKeepNonSolids=True): + def MakeGlueFaces(self, theShape, theTolerance, doKeepNonSolids=True, theName=None): """ Replace coincident faces in theShape by one face. @@ -4905,6 +6156,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theTolerance Maximum distance between faces, which can be considered as coincident. doKeepNonSolids If FALSE, only solids will present in the result, otherwise all initial shapes. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing a copy of theShape without coincident faces. @@ -4915,16 +6169,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): if anObj is None: raise RuntimeError, "MakeGlueFaces : " + self.ShapesOp.GetErrorCode() anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "glueFaces") return anObj ## Find coincident faces in theShape for possible gluing. # @param theShape Initial shape. # @param theTolerance Maximum distance between faces, # which can be considered as coincident. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return GEOM.ListOfGO # # @ref tui_glue_faces "Example" - def GetGlueFaces(self, theShape, theTolerance): + def GetGlueFaces(self, theShape, theTolerance, theName=None): """ Find coincident faces in theShape for possible gluing. @@ -4932,12 +6191,16 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShape Initial shape. theTolerance Maximum distance between faces, which can be considered as coincident. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: GEOM.ListOfGO """ anObj = self.ShapesOp.GetGlueFaces(theShape, theTolerance) RaiseIfFailed("GetGlueFaces", self.ShapesOp) + self._autoPublish(anObj, theName, "facesToGlue") return anObj ## Replace coincident faces in theShape by one face @@ -4951,12 +6214,16 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param doGlueAllEdges If TRUE, all coincident edges of theShape # will be glued, otherwise only the edges, # belonging to theFaces. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing a copy of theShape # without some faces. # # @ref tui_glue_faces "Example" def MakeGlueFacesByList(self, theShape, theTolerance, theFaces, - doKeepNonSolids=True, doGlueAllEdges=True): + doKeepNonSolids=True, doGlueAllEdges=True, theName=None): """ Replace coincident faces in theShape by one face in compliance with given list of faces @@ -4971,6 +6238,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): doGlueAllEdges If TRUE, all coincident edges of theShape will be glued, otherwise only the edges, belonging to theFaces. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing a copy of theShape @@ -4980,21 +6250,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): doKeepNonSolids, doGlueAllEdges) if anObj is None: raise RuntimeError, "MakeGlueFacesByList : " + self.ShapesOp.GetErrorCode() + self._autoPublish(anObj, theName, "glueFaces") return anObj ## Replace coincident edges in theShape by one edge. # @param theShape Initial shape. # @param theTolerance Maximum distance between edges, which can be considered as coincident. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing a copy of theShape without coincident edges. # # @ref tui_glue_edges "Example" - def MakeGlueEdges(self, theShape, theTolerance): + def MakeGlueEdges(self, theShape, theTolerance, theName=None): """ Replace coincident edges in theShape by one edge. Parameters: theShape Initial shape. theTolerance Maximum distance between edges, which can be considered as coincident. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing a copy of theShape without coincident edges. @@ -5004,16 +6282,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): if anObj is None: raise RuntimeError, "MakeGlueEdges : " + self.ShapesOp.GetErrorCode() anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "glueEdges") return anObj ## Find coincident edges in theShape for possible gluing. # @param theShape Initial shape. # @param theTolerance Maximum distance between edges, # which can be considered as coincident. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return GEOM.ListOfGO # # @ref tui_glue_edges "Example" - def GetGlueEdges(self, theShape, theTolerance): + def GetGlueEdges(self, theShape, theTolerance, theName=None): """ Find coincident edges in theShape for possible gluing. @@ -5021,12 +6304,16 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShape Initial shape. theTolerance Maximum distance between edges, which can be considered as coincident. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: GEOM.ListOfGO """ anObj = self.ShapesOp.GetGlueEdges(theShape, theTolerance) RaiseIfFailed("GetGlueEdges", self.ShapesOp) + self._autoPublish(anObj, theName, "edgesToGlue") return anObj ## Replace coincident edges in theShape by one edge @@ -5035,11 +6322,15 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theTolerance Maximum distance between edges, # which can be considered as coincident. # @param theEdges List of edges for gluing. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing a copy of theShape # without some edges. # # @ref tui_glue_edges "Example" - def MakeGlueEdgesByList(self, theShape, theTolerance, theEdges): + def MakeGlueEdgesByList(self, theShape, theTolerance, theEdges, theName=None): """ Replace coincident edges in theShape by one edge in compliance with given list of edges. @@ -5049,6 +6340,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theTolerance Maximum distance between edges, which can be considered as coincident. theEdges List of edges for gluing. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing a copy of theShape @@ -5057,6 +6351,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.ShapesOp.MakeGlueEdgesByList(theShape, theTolerance, theEdges) if anObj is None: raise RuntimeError, "MakeGlueEdgesByList : " + self.ShapesOp.GetErrorCode() + self._autoPublish(anObj, theName, "glueEdges") return anObj # end of l3_healing @@ -5074,10 +6369,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theShape2 Second argument for boolean operation. # @param theOperation Indicates the operation to be done:\n # 1 - Common, 2 - Cut, 3 - Fuse, 4 - Section. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_fuse "Example" - def MakeBoolean(self,theShape1, theShape2, theOperation): + def MakeBoolean(self, theShape1, theShape2, theOperation, theName=None): """ Perform one of boolean operations on two given shapes. @@ -5086,6 +6385,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShape2 Second argument for boolean operation. theOperation Indicates the operation to be done: 1 - Common, 2 - Cut, 3 - Fuse, 4 - Section. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the result shape. @@ -5093,94 +6395,128 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.BoolOp.MakeBoolean(theShape1, theShape2, theOperation) RaiseIfFailed("MakeBoolean", self.BoolOp) + def_names = { 1: "common", 2: "cut", 3: "fuse", 4: "section" } + self._autoPublish(anObj, theName, def_names[theOperation]) return anObj ## Perform Common boolean operation on two given shapes. # @param theShape1 First argument for boolean operation. # @param theShape2 Second argument for boolean operation. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_common "Example 1" # \n @ref swig_MakeCommon "Example 2" - def MakeCommon(self, theShape1, theShape2): + def MakeCommon(self, theShape1, theShape2, theName=None): """ Perform Common boolean operation on two given shapes. Parameters: theShape1 First argument for boolean operation. theShape2 Second argument for boolean operation. - + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + Returns: New GEOM.GEOM_Object, containing the result shape. """ # Example: see GEOM_TestOthers.py - return self.MakeBoolean(theShape1, theShape2, 1) + # note: auto-publishing is done in self.MakeBoolean() + return self.MakeBoolean(theShape1, theShape2, 1, theName) ## Perform Cut boolean operation on two given shapes. # @param theShape1 First argument for boolean operation. # @param theShape2 Second argument for boolean operation. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_cut "Example 1" # \n @ref swig_MakeCommon "Example 2" - def MakeCut(self, theShape1, theShape2): + def MakeCut(self, theShape1, theShape2, theName=None): """ Perform Cut boolean operation on two given shapes. Parameters: theShape1 First argument for boolean operation. theShape2 Second argument for boolean operation. - + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + Returns: New GEOM.GEOM_Object, containing the result shape. """ # Example: see GEOM_TestOthers.py - return self.MakeBoolean(theShape1, theShape2, 2) + # note: auto-publishing is done in self.MakeBoolean() + return self.MakeBoolean(theShape1, theShape2, 2, theName) ## Perform Fuse boolean operation on two given shapes. # @param theShape1 First argument for boolean operation. # @param theShape2 Second argument for boolean operation. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_fuse "Example 1" # \n @ref swig_MakeCommon "Example 2" - def MakeFuse(self, theShape1, theShape2): + def MakeFuse(self, theShape1, theShape2, theName=None): """ Perform Fuse boolean operation on two given shapes. Parameters: theShape1 First argument for boolean operation. theShape2 Second argument for boolean operation. - + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + Returns: New GEOM.GEOM_Object, containing the result shape. """ # Example: see GEOM_TestOthers.py - return self.MakeBoolean(theShape1, theShape2, 3) + # note: auto-publishing is done in self.MakeBoolean() + return self.MakeBoolean(theShape1, theShape2, 3, theName) ## Perform Section boolean operation on two given shapes. # @param theShape1 First argument for boolean operation. # @param theShape2 Second argument for boolean operation. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_section "Example 1" # \n @ref swig_MakeCommon "Example 2" - def MakeSection(self, theShape1, theShape2): + def MakeSection(self, theShape1, theShape2, theName=None): """ Perform Section boolean operation on two given shapes. Parameters: theShape1 First argument for boolean operation. theShape2 Second argument for boolean operation. - + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + Returns: New GEOM.GEOM_Object, containing the result shape. """ # Example: see GEOM_TestOthers.py - return self.MakeBoolean(theShape1, theShape2, 4) + # note: auto-publishing is done in self.MakeBoolean() + return self.MakeBoolean(theShape1, theShape2, 4, theName) # end of l3_boolean ## @} @@ -5198,6 +6534,10 @@ class geompyDC(GEOM._objref_GEOM_Gen): # target type (equal to Limit) are kept in the result, # else standalone shapes of lower dimension # are kept also (if they exist). + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @note Each compound from ListShapes and ListTools will be exploded # in order to avoid possible intersection between shapes from this compound. # @@ -5217,7 +6557,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @ref tui_partition "Example" def MakePartition(self, ListShapes, ListTools=[], ListKeepInside=[], ListRemoveInside=[], Limit=ShapeType["AUTO"], RemoveWebs=0, ListMaterials=[], - KeepNonlimitShapes=0): + KeepNonlimitShapes=0, theName=None): """ Perform partition operation. @@ -5231,6 +6571,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): target type (equal to Limit) are kept in the result, else standalone shapes of lower dimension are kept also (if they exist). + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Note: Each compound from ListShapes and ListTools will be exploded in order to avoid possible intersection between shapes from @@ -5263,6 +6606,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): Limit, RemoveWebs, ListMaterials, KeepNonlimitShapes); RaiseIfFailed("MakePartition", self.BoolOp) + self._autoPublish(anObj, theName, "partition") return anObj ## Perform partition operation. @@ -5281,7 +6625,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): def MakePartitionNonSelfIntersectedShape(self, ListShapes, ListTools=[], ListKeepInside=[], ListRemoveInside=[], Limit=ShapeType["AUTO"], RemoveWebs=0, - ListMaterials=[], KeepNonlimitShapes=0): + ListMaterials=[], KeepNonlimitShapes=0, + theName=None): """ Perform partition operation. This method may be useful if it is needed to make a partition for @@ -5309,6 +6654,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): Limit, RemoveWebs, ListMaterials, KeepNonlimitShapes); RaiseIfFailed("MakePartitionNonSelfIntersectedShape", self.BoolOp) + self._autoPublish(anObj, theName, "partition") return anObj ## See method MakePartition() for more information. @@ -5317,30 +6663,38 @@ class geompyDC(GEOM._objref_GEOM_Gen): # \n @ref swig_Partition "Example 2" def Partition(self, ListShapes, ListTools=[], ListKeepInside=[], ListRemoveInside=[], Limit=ShapeType["AUTO"], RemoveWebs=0, ListMaterials=[], - KeepNonlimitShapes=0): + KeepNonlimitShapes=0, theName=None): """ See method geompy.MakePartition for more information. """ # Example: see GEOM_TestOthers.py + # note: auto-publishing is done in self.MakePartition() anObj = self.MakePartition(ListShapes, ListTools, ListKeepInside, ListRemoveInside, Limit, RemoveWebs, ListMaterials, - KeepNonlimitShapes); + KeepNonlimitShapes, theName); return anObj ## Perform partition of the Shape with the Plane # @param theShape Shape to be intersected. # @param thePlane Tool shape, to intersect theShape. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_partition "Example" - def MakeHalfPartition(self,theShape, thePlane): + def MakeHalfPartition(self, theShape, thePlane, theName=None): """ Perform partition of the Shape with the Plane Parameters: theShape Shape to be intersected. thePlane Tool shape, to intersect theShape. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the result shape. @@ -5348,6 +6702,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.BoolOp.MakeHalfPartition(theShape, thePlane) RaiseIfFailed("MakeHalfPartition", self.BoolOp) + self._autoPublish(anObj, theName, "partition") return anObj # end of l3_basic_op @@ -5356,16 +6711,49 @@ class geompyDC(GEOM._objref_GEOM_Gen): ## @addtogroup l3_transform ## @{ + ## Translate the given object along the vector, specified + # by its end points. + # @param theObject The object to be translated. + # @param thePoint1 Start point of translation vector. + # @param thePoint2 End point of translation vector. + # @param theCopy Flag used to translate object itself or create a copy. + # @return Translated @a theObject (GEOM.GEOM_Object) if @a theCopy flag is @c False (default) or + # new GEOM.GEOM_Object, containing the translated object if @a theCopy flag is @c True. + def TranslateTwoPoints(self, theObject, thePoint1, thePoint2, theCopy=False): + """ + Translate the given object along the vector, specified by its end points. + + Parameters: + theObject The object to be translated. + thePoint1 Start point of translation vector. + thePoint2 End point of translation vector. + theCopy Flag used to translate object itself or create a copy. + + Returns: + Translated theObject (GEOM.GEOM_Object) if theCopy flag is False (default) or + new GEOM.GEOM_Object, containing the translated object if theCopy flag is True. + """ + if theCopy: + anObj = self.TrsfOp.TranslateTwoPointsCopy(theObject, thePoint1, thePoint2) + else: + anObj = self.TrsfOp.TranslateTwoPoints(theObject, thePoint1, thePoint2) + RaiseIfFailed("TranslateTwoPoints", self.TrsfOp) + return anObj + ## Translate the given object along the vector, specified # by its end points, creating its copy before the translation. # @param theObject The object to be translated. # @param thePoint1 Start point of translation vector. # @param thePoint2 End point of translation vector. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the translated object. # # @ref tui_translation "Example 1" # \n @ref swig_MakeTranslationTwoPoints "Example 2" - def MakeTranslationTwoPoints(self,theObject, thePoint1, thePoint2): + def MakeTranslationTwoPoints(self, theObject, thePoint1, thePoint2, theName=None): """ Translate the given object along the vector, specified by its end points, creating its copy before the translation. @@ -5374,6 +6762,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theObject The object to be translated. thePoint1 Start point of translation vector. thePoint2 End point of translation vector. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the translated object. @@ -5381,28 +6772,36 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.TrsfOp.TranslateTwoPointsCopy(theObject, thePoint1, thePoint2) RaiseIfFailed("TranslateTwoPointsCopy", self.TrsfOp) + self._autoPublish(anObj, theName, "translated") return anObj ## Translate the given object along the vector, specified by its components. # @param theObject The object to be translated. # @param theDX,theDY,theDZ Components of translation vector. - # @return Translated GEOM.GEOM_Object. + # @param theCopy Flag used to translate object itself or create a copy. + # @return Translated @a theObject (GEOM.GEOM_Object) if @a theCopy flag is @c False (default) or + # new GEOM.GEOM_Object, containing the translated object if @a theCopy flag is @c True. # # @ref tui_translation "Example" - def TranslateDXDYDZ(self,theObject, theDX, theDY, theDZ): + def TranslateDXDYDZ(self, theObject, theDX, theDY, theDZ, theCopy=False): """ Translate the given object along the vector, specified by its components. Parameters: theObject The object to be translated. theDX,theDY,theDZ Components of translation vector. + theCopy Flag used to translate object itself or create a copy. Returns: - Translated GEOM.GEOM_Object. + Translated theObject (GEOM.GEOM_Object) if theCopy flag is False (default) or + new GEOM.GEOM_Object, containing the translated object if theCopy flag is True. """ # Example: see GEOM_TestAll.py theDX, theDY, theDZ, Parameters = ParseParameters(theDX, theDY, theDZ) - anObj = self.TrsfOp.TranslateDXDYDZ(theObject, theDX, theDY, theDZ) + if theCopy: + anObj = self.TrsfOp.TranslateDXDYDZCopy(theObject, theDX, theDY, theDZ) + else: + anObj = self.TrsfOp.TranslateDXDYDZ(theObject, theDX, theDY, theDZ) anObj.SetParameters(Parameters) RaiseIfFailed("TranslateDXDYDZ", self.TrsfOp) return anObj @@ -5411,10 +6810,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # by its components, creating its copy before the translation. # @param theObject The object to be translated. # @param theDX,theDY,theDZ Components of translation vector. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the translated object. # # @ref tui_translation "Example" - def MakeTranslation(self,theObject, theDX, theDY, theDZ): + def MakeTranslation(self,theObject, theDX, theDY, theDZ, theName=None): """ Translate the given object along the vector, specified by its components, creating its copy before the translation. @@ -5422,6 +6825,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theObject The object to be translated. theDX,theDY,theDZ Components of translation vector. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the translated object. @@ -5431,16 +6837,47 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.TrsfOp.TranslateDXDYDZCopy(theObject, theDX, theDY, theDZ) anObj.SetParameters(Parameters) RaiseIfFailed("TranslateDXDYDZ", self.TrsfOp) + self._autoPublish(anObj, theName, "translated") return anObj - ## Translate the given object along the given vector, - # creating its copy before the translation. + ## Translate the given object along the given vector. # @param theObject The object to be translated. # @param theVector The translation vector. - # @return New GEOM.GEOM_Object, containing the translated object. - # + # @param theCopy Flag used to translate object itself or create a copy. + # @return Translated @a theObject (GEOM.GEOM_Object) if @a theCopy flag is @c False (default) or + # new GEOM.GEOM_Object, containing the translated object if @a theCopy flag is @c True. + def TranslateVector(self, theObject, theVector, theCopy=False): + """ + Translate the given object along the given vector. + + Parameters: + theObject The object to be translated. + theVector The translation vector. + theCopy Flag used to translate object itself or create a copy. + + Returns: + Translated theObject (GEOM.GEOM_Object) if theCopy flag is False (default) or + new GEOM.GEOM_Object, containing the translated object if theCopy flag is True. + """ + if theCopy: + anObj = self.TrsfOp.TranslateVectorCopy(theObject, theVector) + else: + anObj = self.TrsfOp.TranslateVector(theObject, theVector) + RaiseIfFailed("TranslateVector", self.TrsfOp) + return anObj + + ## Translate the given object along the given vector, + # creating its copy before the translation. + # @param theObject The object to be translated. + # @param theVector The translation vector. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @return New GEOM.GEOM_Object, containing the translated object. + # # @ref tui_translation "Example" - def MakeTranslationVector(self,theObject, theVector): + def MakeTranslationVector(self, theObject, theVector, theName=None): """ Translate the given object along the given vector, creating its copy before the translation. @@ -5448,6 +6885,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theObject The object to be translated. theVector The translation vector. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the translated object. @@ -5455,6 +6895,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.TrsfOp.TranslateVectorCopy(theObject, theVector) RaiseIfFailed("TranslateVectorCopy", self.TrsfOp) + self._autoPublish(anObj, theName, "translated") return anObj ## Translate the given object along the given vector on given distance. @@ -5462,10 +6903,11 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theVector The translation vector. # @param theDistance The translation distance. # @param theCopy Flag used to translate object itself or create a copy. - # @return New GEOM.GEOM_Object, containing the translated object. + # @return Translated @a theObject (GEOM.GEOM_Object) if @a theCopy flag is @c False (default) or + # new GEOM.GEOM_Object, containing the translated object if @a theCopy flag is @c True. # # @ref tui_translation "Example" - def TranslateVectorDistance(self, theObject, theVector, theDistance, theCopy): + def TranslateVectorDistance(self, theObject, theVector, theDistance, theCopy=False): """ Translate the given object along the given vector on given distance. @@ -5476,7 +6918,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): theCopy Flag used to translate object itself or create a copy. Returns: - New GEOM.GEOM_Object, containing the translated object. + Translated theObject (GEOM.GEOM_Object) if theCopy flag is False (default) or + new GEOM.GEOM_Object, containing the translated object if theCopy flag is True. """ # Example: see GEOM_TestAll.py theDistance,Parameters = ParseParameters(theDistance) @@ -5490,10 +6933,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theObject The object to be translated. # @param theVector The translation vector. # @param theDistance The translation distance. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the translated object. # # @ref tui_translation "Example" - def MakeTranslationVectorDistance(self, theObject, theVector, theDistance): + def MakeTranslationVectorDistance(self, theObject, theVector, theDistance, theName=None): """ Translate the given object along the given vector on given distance, creating its copy before the translation. @@ -5502,6 +6949,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theObject The object to be translated. theVector The translation vector. theDistance The translation distance. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the translated object. @@ -5511,16 +6961,20 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.TrsfOp.TranslateVectorDistance(theObject, theVector, theDistance, 1) RaiseIfFailed("TranslateVectorDistance", self.TrsfOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "translated") return anObj ## Rotate the given object around the given axis on the given angle. # @param theObject The object to be rotated. # @param theAxis Rotation axis. # @param theAngle Rotation angle in radians. - # @return New GEOM.GEOM_Object, containing the rotated object. + # @param theCopy Flag used to rotate object itself or create a copy. + # + # @return Rotated @a theObject (GEOM.GEOM_Object) if @a theCopy flag is @c False (default) or + # new GEOM.GEOM_Object, containing the rotated object if @a theCopy flag is @c True. # # @ref tui_rotation "Example" - def Rotate(self,theObject, theAxis, theAngle): + def Rotate(self, theObject, theAxis, theAngle, theCopy=False): """ Rotate the given object around the given axis on the given angle. @@ -5528,9 +6982,11 @@ class geompyDC(GEOM._objref_GEOM_Gen): theObject The object to be rotated. theAxis Rotation axis. theAngle Rotation angle in radians. + theCopy Flag used to rotate object itself or create a copy. - Returns: - New GEOM.GEOM_Object, containing the rotated object. + Returns: + Rotated theObject (GEOM.GEOM_Object) if theCopy flag is False (default) or + new GEOM.GEOM_Object, containing the rotated object if theCopy flag is True. """ # Example: see GEOM_TestAll.py flag = False @@ -5539,8 +6995,11 @@ class geompyDC(GEOM._objref_GEOM_Gen): theAngle, Parameters = ParseParameters(theAngle) if flag: theAngle = theAngle*math.pi/180.0 - anObj = self.TrsfOp.Rotate(theObject, theAxis, theAngle) - RaiseIfFailed("RotateCopy", self.TrsfOp) + if theCopy: + anObj = self.TrsfOp.RotateCopy(theObject, theAxis, theAngle) + else: + anObj = self.TrsfOp.Rotate(theObject, theAxis, theAngle) + RaiseIfFailed("Rotate", self.TrsfOp) anObj.SetParameters(Parameters) return anObj @@ -5549,10 +7008,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theObject The object to be rotated. # @param theAxis Rotation axis. # @param theAngle Rotation angle in radians. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the rotated object. # # @ref tui_rotation "Example" - def MakeRotation(self,theObject, theAxis, theAngle): + def MakeRotation(self, theObject, theAxis, theAngle, theName=None): """ Rotate the given object around the given axis on the given angle, creating its copy before the rotatation. @@ -5561,6 +7024,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theObject The object to be rotated. theAxis Rotation axis. theAngle Rotation angle in radians. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the rotated object. @@ -5575,6 +7041,39 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.TrsfOp.RotateCopy(theObject, theAxis, theAngle) RaiseIfFailed("RotateCopy", self.TrsfOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "rotated") + return anObj + + ## Rotate given object around vector perpendicular to plane + # containing three points. + # @param theObject The object to be rotated. + # @param theCentPoint central point the axis is the vector perpendicular to the plane + # containing the three points. + # @param thePoint1,thePoint2 points in a perpendicular plane of the axis. + # @param theCopy Flag used to rotate object itself or create a copy. + # @return Rotated @a theObject (GEOM.GEOM_Object) if @a theCopy flag is @c False (default) or + # new GEOM.GEOM_Object, containing the rotated object if @a theCopy flag is @c True. + def RotateThreePoints(self, theObject, theCentPoint, thePoint1, thePoint2, theCopy=False): + """ + Rotate given object around vector perpendicular to plane + containing three points. + + Parameters: + theObject The object to be rotated. + theCentPoint central point the axis is the vector perpendicular to the plane + containing the three points. + thePoint1,thePoint2 points in a perpendicular plane of the axis. + theCopy Flag used to rotate object itself or create a copy. + + Returns: + Rotated theObject (GEOM.GEOM_Object) if theCopy flag is False (default) or + new GEOM.GEOM_Object, containing the rotated object if theCopy flag is True. + """ + if theCopy: + anObj = self.TrsfOp.RotateThreePointsCopy(theObject, theCentPoint, thePoint1, thePoint2) + else: + anObj = self.TrsfOp.RotateThreePoints(theObject, theCentPoint, thePoint1, thePoint2) + RaiseIfFailed("RotateThreePoints", self.TrsfOp) return anObj ## Rotate given object around vector perpendicular to plane @@ -5583,10 +7082,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theCentPoint central point the axis is the vector perpendicular to the plane # containing the three points. # @param thePoint1,thePoint2 in a perpendicular plane of the axis. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the rotated object. # # @ref tui_rotation "Example" - def MakeRotationThreePoints(self,theObject, theCentPoint, thePoint1, thePoint2): + def MakeRotationThreePoints(self, theObject, theCentPoint, thePoint1, thePoint2, theName=None): """ Rotate given object around vector perpendicular to plane containing three points, creating its copy before the rotatation. @@ -5596,6 +7099,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theCentPoint central point the axis is the vector perpendicular to the plane containing the three points. thePoint1,thePoint2 in a perpendicular plane of the axis. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the rotated object. @@ -5603,6 +7109,40 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.TrsfOp.RotateThreePointsCopy(theObject, theCentPoint, thePoint1, thePoint2) RaiseIfFailed("RotateThreePointsCopy", self.TrsfOp) + self._autoPublish(anObj, theName, "rotated") + return anObj + + ## Scale the given object by the specified factor. + # @param theObject The object to be scaled. + # @param thePoint Center point for scaling. + # Passing None for it means scaling relatively the origin of global CS. + # @param theFactor Scaling factor value. + # @param theCopy Flag used to scale object itself or create a copy. + # @return Scaled @a theObject (GEOM.GEOM_Object) if @a theCopy flag is @c False (default) or + # new GEOM.GEOM_Object, containing the scaled object if @a theCopy flag is @c True. + def Scale(self, theObject, thePoint, theFactor, theCopy=False): + """ + Scale the given object by the specified factor. + + Parameters: + theObject The object to be scaled. + thePoint Center point for scaling. + Passing None for it means scaling relatively the origin of global CS. + theFactor Scaling factor value. + theCopy Flag used to scale object itself or create a copy. + + Returns: + Scaled theObject (GEOM.GEOM_Object) if theCopy flag is False (default) or + new GEOM.GEOM_Object, containing the scaled object if theCopy flag is True. + """ + # Example: see GEOM_TestAll.py + theFactor, Parameters = ParseParameters(theFactor) + if theCopy: + anObj = self.TrsfOp.ScaleShapeCopy(theObject, thePoint, theFactor) + else: + anObj = self.TrsfOp.ScaleShape(theObject, thePoint, theFactor) + RaiseIfFailed("Scale", self.TrsfOp) + anObj.SetParameters(Parameters) return anObj ## Scale the given object by the factor, creating its copy before the scaling. @@ -5610,10 +7150,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param thePoint Center point for scaling. # Passing None for it means scaling relatively the origin of global CS. # @param theFactor Scaling factor value. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the scaled shape. # # @ref tui_scale "Example" - def MakeScaleTransform(self, theObject, thePoint, theFactor): + def MakeScaleTransform(self, theObject, thePoint, theFactor, theName=None): """ Scale the given object by the factor, creating its copy before the scaling. @@ -5622,6 +7166,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): thePoint Center point for scaling. Passing None for it means scaling relatively the origin of global CS. theFactor Scaling factor value. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the scaled shape. @@ -5631,6 +7178,42 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.TrsfOp.ScaleShapeCopy(theObject, thePoint, theFactor) RaiseIfFailed("ScaleShapeCopy", self.TrsfOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "scaled") + return anObj + + ## Scale the given object by different factors along coordinate axes. + # @param theObject The object to be scaled. + # @param thePoint Center point for scaling. + # Passing None for it means scaling relatively the origin of global CS. + # @param theFactorX,theFactorY,theFactorZ Scaling factors along each axis. + # @param theCopy Flag used to scale object itself or create a copy. + # @return Scaled @a theObject (GEOM.GEOM_Object) if @a theCopy flag is @c False (default) or + # new GEOM.GEOM_Object, containing the scaled object if @a theCopy flag is @c True. + def ScaleAlongAxes(self, theObject, thePoint, theFactorX, theFactorY, theFactorZ, theCopy=False): + """ + Scale the given object by different factors along coordinate axes. + + Parameters: + theObject The object to be scaled. + thePoint Center point for scaling. + Passing None for it means scaling relatively the origin of global CS. + theFactorX,theFactorY,theFactorZ Scaling factors along each axis. + theCopy Flag used to scale object itself or create a copy. + + Returns: + Scaled theObject (GEOM.GEOM_Object) if theCopy flag is False (default) or + new GEOM.GEOM_Object, containing the scaled object if theCopy flag is True. + """ + # Example: see GEOM_TestAll.py + theFactorX, theFactorY, theFactorZ, Parameters = ParseParameters(theFactorX, theFactorY, theFactorZ) + if theCopy: + anObj = self.TrsfOp.ScaleShapeAlongAxesCopy(theObject, thePoint, + theFactorX, theFactorY, theFactorZ) + else: + anObj = self.TrsfOp.ScaleShapeAlongAxes(theObject, thePoint, + theFactorX, theFactorY, theFactorZ) + RaiseIfFailed("ScaleAlongAxes", self.TrsfOp) + anObj.SetParameters(Parameters) return anObj ## Scale the given object by different factors along coordinate axes, @@ -5639,10 +7222,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param thePoint Center point for scaling. # Passing None for it means scaling relatively the origin of global CS. # @param theFactorX,theFactorY,theFactorZ Scaling factors along each axis. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the scaled shape. # # @ref swig_scale "Example" - def MakeScaleAlongAxes(self, theObject, thePoint, theFactorX, theFactorY, theFactorZ): + def MakeScaleAlongAxes(self, theObject, thePoint, theFactorX, theFactorY, theFactorZ, theName=None): """ Scale the given object by different factors along coordinate axes, creating its copy before the scaling. @@ -5652,6 +7239,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): thePoint Center point for scaling. Passing None for it means scaling relatively the origin of global CS. theFactorX,theFactorY,theFactorZ Scaling factors along each axis. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the scaled shape. @@ -5662,22 +7252,56 @@ class geompyDC(GEOM._objref_GEOM_Gen): theFactorX, theFactorY, theFactorZ) RaiseIfFailed("MakeScaleAlongAxes", self.TrsfOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "scaled") + return anObj + + ## Mirror an object relatively the given plane. + # @param theObject The object to be mirrored. + # @param thePlane Plane of symmetry. + # @param theCopy Flag used to mirror object itself or create a copy. + # @return Mirrored @a theObject (GEOM.GEOM_Object) if @a theCopy flag is @c False (default) or + # new GEOM.GEOM_Object, containing the mirrored object if @a theCopy flag is @c True. + def MirrorByPlane(self, theObject, thePlane, theCopy=False): + """ + Mirror an object relatively the given plane. + + Parameters: + theObject The object to be mirrored. + thePlane Plane of symmetry. + theCopy Flag used to mirror object itself or create a copy. + + Returns: + Mirrored theObject (GEOM.GEOM_Object) if theCopy flag is False (default) or + new GEOM.GEOM_Object, containing the mirrored object if theCopy flag is True. + """ + if theCopy: + anObj = self.TrsfOp.MirrorPlaneCopy(theObject, thePlane) + else: + anObj = self.TrsfOp.MirrorPlane(theObject, thePlane) + RaiseIfFailed("MirrorByPlane", self.TrsfOp) return anObj ## Create an object, symmetrical # to the given one relatively the given plane. # @param theObject The object to be mirrored. # @param thePlane Plane of symmetry. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the mirrored shape. # # @ref tui_mirror "Example" - def MakeMirrorByPlane(self,theObject, thePlane): + def MakeMirrorByPlane(self, theObject, thePlane, theName=None): """ Create an object, symmetrical to the given one relatively the given plane. Parameters: theObject The object to be mirrored. thePlane Plane of symmetry. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the mirrored shape. @@ -5685,22 +7309,56 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.TrsfOp.MirrorPlaneCopy(theObject, thePlane) RaiseIfFailed("MirrorPlaneCopy", self.TrsfOp) + self._autoPublish(anObj, theName, "mirrored") + return anObj + + ## Mirror an object relatively the given axis. + # @param theObject The object to be mirrored. + # @param theAxis Axis of symmetry. + # @param theCopy Flag used to mirror object itself or create a copy. + # @return Mirrored @a theObject (GEOM.GEOM_Object) if @a theCopy flag is @c False (default) or + # new GEOM.GEOM_Object, containing the mirrored object if @a theCopy flag is @c True. + def MirrorByAxis(self, theObject, theAxis, theCopy=False): + """ + Mirror an object relatively the given axis. + + Parameters: + theObject The object to be mirrored. + theAxis Axis of symmetry. + theCopy Flag used to mirror object itself or create a copy. + + Returns: + Mirrored theObject (GEOM.GEOM_Object) if theCopy flag is False (default) or + new GEOM.GEOM_Object, containing the mirrored object if theCopy flag is True. + """ + if theCopy: + anObj = self.TrsfOp.MirrorAxisCopy(theObject, theAxis) + else: + anObj = self.TrsfOp.MirrorAxis(theObject, theAxis) + RaiseIfFailed("MirrorByAxis", self.TrsfOp) return anObj ## Create an object, symmetrical # to the given one relatively the given axis. # @param theObject The object to be mirrored. # @param theAxis Axis of symmetry. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the mirrored shape. # # @ref tui_mirror "Example" - def MakeMirrorByAxis(self,theObject, theAxis): + def MakeMirrorByAxis(self, theObject, theAxis, theName=None): """ Create an object, symmetrical to the given one relatively the given axis. Parameters: theObject The object to be mirrored. theAxis Axis of symmetry. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the mirrored shape. @@ -5708,16 +7366,48 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.TrsfOp.MirrorAxisCopy(theObject, theAxis) RaiseIfFailed("MirrorAxisCopy", self.TrsfOp) + self._autoPublish(anObj, theName, "mirrored") + return anObj + + ## Mirror an object relatively the given point. + # @param theObject The object to be mirrored. + # @param thePoint Point of symmetry. + # @param theCopy Flag used to mirror object itself or create a copy. + # @return Mirrored @a theObject (GEOM.GEOM_Object) if @a theCopy flag is @c False (default) or + # new GEOM.GEOM_Object, containing the mirrored object if @a theCopy flag is @c True. + def MirrorByPoint(self, theObject, thePoint, theCopy=False): + """ + Mirror an object relatively the given point. + + Parameters: + theObject The object to be mirrored. + thePoint Point of symmetry. + theCopy Flag used to mirror object itself or create a copy. + + Returns: + Mirrored theObject (GEOM.GEOM_Object) if theCopy flag is False (default) or + new GEOM.GEOM_Object, containing the mirrored object if theCopy flag is True. + """ + # Example: see GEOM_TestAll.py + if theCopy: + anObj = self.TrsfOp.MirrorPointCopy(theObject, thePoint) + else: + anObj = self.TrsfOp.MirrorPoint(theObject, thePoint) + RaiseIfFailed("MirrorByPoint", self.TrsfOp) return anObj ## Create an object, symmetrical # to the given one relatively the given point. # @param theObject The object to be mirrored. # @param thePoint Point of symmetry. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the mirrored shape. # # @ref tui_mirror "Example" - def MakeMirrorByPoint(self,theObject, thePoint): + def MakeMirrorByPoint(self, theObject, thePoint, theName=None): """ Create an object, symmetrical to the given one relatively the given point. @@ -5725,6 +7415,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theObject The object to be mirrored. thePoint Point of symmetry. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the mirrored shape. @@ -5732,6 +7425,44 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.TrsfOp.MirrorPointCopy(theObject, thePoint) RaiseIfFailed("MirrorPointCopy", self.TrsfOp) + self._autoPublish(anObj, theName, "mirrored") + return anObj + + ## Modify the location of the given object. + # @param theObject The object to be displaced. + # @param theStartLCS Coordinate system to perform displacement from it.\n + # If \a theStartLCS is NULL, displacement + # will be performed from global CS.\n + # If \a theObject itself is used as \a theStartLCS, + # its location will be changed to \a theEndLCS. + # @param theEndLCS Coordinate system to perform displacement to it. + # @param theCopy Flag used to displace object itself or create a copy. + # @return Displaced @a theObject (GEOM.GEOM_Object) if @a theCopy flag is @c False (default) or + # new GEOM.GEOM_Object, containing the displaced object if @a theCopy flag is @c True. + def Position(self, theObject, theStartLCS, theEndLCS, theCopy=False): + """ + Modify the Location of the given object by LCS, creating its copy before the setting. + + Parameters: + theObject The object to be displaced. + theStartLCS Coordinate system to perform displacement from it. + If theStartLCS is NULL, displacement + will be performed from global CS. + If theObject itself is used as theStartLCS, + its location will be changed to theEndLCS. + theEndLCS Coordinate system to perform displacement to it. + theCopy Flag used to displace object itself or create a copy. + + Returns: + Displaced theObject (GEOM.GEOM_Object) if theCopy flag is False (default) or + new GEOM.GEOM_Object, containing the displaced object if theCopy flag is True. + """ + # Example: see GEOM_TestAll.py + if theCopy: + anObj = self.TrsfOp.PositionShapeCopy(theObject, theStartLCS, theEndLCS) + else: + anObj = self.TrsfOp.PositionShape(theObject, theStartLCS, theEndLCS) + RaiseIfFailed("Displace", self.TrsfOp) return anObj ## Modify the Location of the given object by LCS, @@ -5743,10 +7474,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # If \a theObject itself is used as \a theStartLCS, # its location will be changed to \a theEndLCS. # @param theEndLCS Coordinate system to perform displacement to it. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the displaced shape. # # @ref tui_modify_location "Example" - def MakePosition(self,theObject, theStartLCS, theEndLCS): + def MakePosition(self, theObject, theStartLCS, theEndLCS, theName=None): """ Modify the Location of the given object by LCS, creating its copy before the setting. @@ -5758,6 +7493,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): If theObject itself is used as theStartLCS, its location will be changed to theEndLCS. theEndLCS Coordinate system to perform displacement to it. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the displaced shape. @@ -5772,20 +7510,22 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.TrsfOp.PositionShapeCopy(theObject, theStartLCS, theEndLCS) RaiseIfFailed("PositionShapeCopy", self.TrsfOp) + self._autoPublish(anObj, theName, "displaced") return anObj - ## Modify the Location of the given object by Path, + ## Modify the Location of the given object by Path. # @param theObject The object to be displaced. # @param thePath Wire or Edge along that the object will be translated. # @param theDistance progress of Path (0 = start location, 1 = end of path location). # @param theCopy is to create a copy objects if true. # @param theReverse 0 - for usual direction, 1 - to reverse path direction. - # @return New GEOM.GEOM_Object, containing the displaced shape. + # @return Displaced @a theObject (GEOM.GEOM_Object) if @a theCopy is @c False or + # new GEOM.GEOM_Object, containing the displaced shape if @a theCopy is @c True. # # @ref tui_modify_location "Example" def PositionAlongPath(self,theObject, thePath, theDistance, theCopy, theReverse): """ - Modify the Location of the given object by Path + Modify the Location of the given object by Path. Parameters: theObject The object to be displaced. @@ -5795,7 +7535,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): theReverse 0 - for usual direction, 1 - to reverse path direction. Returns: - New GEOM.GEOM_Object, containing the displaced shape. + Displaced theObject (GEOM.GEOM_Object) if theCopy is False or + new GEOM.GEOM_Object, containing the displaced shape if theCopy is True. Example of usage: position = geompy.PositionAlongPath(cylinder, circle, 0.75, 1, 1) @@ -5805,19 +7546,86 @@ class geompyDC(GEOM._objref_GEOM_Gen): RaiseIfFailed("PositionAlongPath", self.TrsfOp) return anObj + ## Modify the Location of the given object by Path, creating its copy before the operation. + # @param theObject The object to be displaced. + # @param thePath Wire or Edge along that the object will be translated. + # @param theDistance progress of Path (0 = start location, 1 = end of path location). + # @param theReverse 0 - for usual direction, 1 - to reverse path direction. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @return New GEOM.GEOM_Object, containing the displaced shape. + def MakePositionAlongPath(self, theObject, thePath, theDistance, theReverse, theName=None): + """ + Modify the Location of the given object by Path, creating its copy before the operation. + + Parameters: + theObject The object to be displaced. + thePath Wire or Edge along that the object will be translated. + theDistance progress of Path (0 = start location, 1 = end of path location). + theReverse 0 - for usual direction, 1 - to reverse path direction. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + New GEOM.GEOM_Object, containing the displaced shape. + """ + # Example: see GEOM_TestAll.py + anObj = self.TrsfOp.PositionAlongPath(theObject, thePath, theDistance, 1, theReverse) + RaiseIfFailed("PositionAlongPath", self.TrsfOp) + self._autoPublish(anObj, theName, "displaced") + return anObj + + ## Offset given shape. + # @param theObject The base object for the offset. + # @param theOffset Offset value. + # @param theCopy Flag used to offset object itself or create a copy. + # @return Modified @a theObject (GEOM.GEOM_Object) if @a theCopy flag is @c False (default) or + # new GEOM.GEOM_Object, containing the result of offset operation if @a theCopy flag is @c True. + def Offset(self, theObject, theOffset, theCopy=False): + """ + Offset given shape. + + Parameters: + theObject The base object for the offset. + theOffset Offset value. + theCopy Flag used to offset object itself or create a copy. + + Returns: + Modified theObject (GEOM.GEOM_Object) if theCopy flag is False (default) or + new GEOM.GEOM_Object, containing the result of offset operation if theCopy flag is True. + """ + theOffset, Parameters = ParseParameters(theOffset) + if theCopy: + anObj = self.TrsfOp.OffsetShapeCopy(theObject, theOffset) + else: + anObj = self.TrsfOp.OffsetShape(theObject, theOffset) + RaiseIfFailed("Offset", self.TrsfOp) + anObj.SetParameters(Parameters) + return anObj + ## Create new object as offset of the given one. # @param theObject The base object for the offset. # @param theOffset Offset value. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the offset object. # # @ref tui_offset "Example" - def MakeOffset(self,theObject, theOffset): + def MakeOffset(self, theObject, theOffset, theName=None): """ Create new object as offset of the given one. Parameters: theObject The base object for the offset. theOffset Offset value. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the offset object. @@ -5832,21 +7640,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.TrsfOp.OffsetShapeCopy(theObject, theOffset) RaiseIfFailed("OffsetShapeCopy", self.TrsfOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "offset") return anObj ## Create new object as projection of the given one on a 2D surface. # @param theSource The source object for the projection. It can be a point, edge or wire. # @param theTarget The target object. It can be planar or cylindrical face. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the projection. # # @ref tui_projection "Example" - def MakeProjection(self, theSource, theTarget): + def MakeProjection(self, theSource, theTarget, theName=None): """ Create new object as projection of the given one on a 2D surface. Parameters: theSource The source object for the projection. It can be a point, edge or wire. theTarget The target object. It can be planar or cylindrical face. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the projection. @@ -5854,6 +7670,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestAll.py anObj = self.TrsfOp.ProjectShapeCopy(theSource, theTarget) RaiseIfFailed("ProjectShapeCopy", self.TrsfOp) + self._autoPublish(anObj, theName, "projection") return anObj # ----------------------------------------------------------------------------- @@ -5862,22 +7679,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): ## Translate the given object along the given vector a given number times # @param theObject The object to be translated. - # @param theVector Direction of the translation. + # @param theVector Direction of the translation. DX if None. # @param theStep Distance to translate on. # @param theNbTimes Quantity of translations to be done. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing compound of all # the shapes, obtained after each translation. # # @ref tui_multi_translation "Example" - def MakeMultiTranslation1D(self,theObject, theVector, theStep, theNbTimes): + def MakeMultiTranslation1D(self, theObject, theVector, theStep, theNbTimes, theName=None): """ Translate the given object along the given vector a given number times Parameters: theObject The object to be translated. - theVector Direction of the translation. + theVector Direction of the translation. DX if None. theStep Distance to translate on. theNbTimes Quantity of translations to be done. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing compound of all @@ -5891,33 +7715,41 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.TrsfOp.MultiTranslate1D(theObject, theVector, theStep, theNbTimes) RaiseIfFailed("MultiTranslate1D", self.TrsfOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "multitranslation") return anObj ## Conseqently apply two specified translations to theObject specified number of times. # @param theObject The object to be translated. - # @param theVector1 Direction of the first translation. + # @param theVector1 Direction of the first translation. DX if None. # @param theStep1 Step of the first translation. # @param theNbTimes1 Quantity of translations to be done along theVector1. - # @param theVector2 Direction of the second translation. + # @param theVector2 Direction of the second translation. DY if None. # @param theStep2 Step of the second translation. # @param theNbTimes2 Quantity of translations to be done along theVector2. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing compound of all # the shapes, obtained after each translation. # # @ref tui_multi_translation "Example" - def MakeMultiTranslation2D(self,theObject, theVector1, theStep1, theNbTimes1, - theVector2, theStep2, theNbTimes2): + def MakeMultiTranslation2D(self, theObject, theVector1, theStep1, theNbTimes1, + theVector2, theStep2, theNbTimes2, theName=None): """ Conseqently apply two specified translations to theObject specified number of times. Parameters: theObject The object to be translated. - theVector1 Direction of the first translation. + theVector1 Direction of the first translation. DX if None. theStep1 Step of the first translation. theNbTimes1 Quantity of translations to be done along theVector1. - theVector2 Direction of the second translation. + theVector2 Direction of the second translation. DY if None. theStep2 Step of the second translation. theNbTimes2 Quantity of translations to be done along theVector2. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing compound of all @@ -5932,39 +7764,142 @@ class geompyDC(GEOM._objref_GEOM_Gen): theVector2, theStep2, theNbTimes2) RaiseIfFailed("MultiTranslate2D", self.TrsfOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "multitranslation") return anObj ## Rotate the given object around the given axis a given number times. # Rotation angle will be 2*PI/theNbTimes. # @param theObject The object to be rotated. - # @param theAxis The rotation axis. + # @param theAxis The rotation axis. DZ if None. # @param theNbTimes Quantity of rotations to be done. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing compound of all the # shapes, obtained after each rotation. # # @ref tui_multi_rotation "Example" - def MultiRotate1D(self,theObject, theAxis, theNbTimes): + def MultiRotate1DNbTimes (self, theObject, theAxis, theNbTimes, theName=None): """ Rotate the given object around the given axis a given number times. Rotation angle will be 2*PI/theNbTimes. Parameters: theObject The object to be rotated. - theAxis The rotation axis. + theAxis The rotation axis. DZ if None. theNbTimes Quantity of rotations to be done. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing compound of all the shapes, obtained after each rotation. Example of usage: - rot1d = geompy.MultiRotate1D(prism, vect, 4) + rot1d = geompy.MultiRotate1DNbTimes(prism, vect, 4) """ # Example: see GEOM_TestAll.py - theAxis, theNbTimes, Parameters = ParseParameters(theAxis, theNbTimes) + theNbTimes, Parameters = ParseParameters(theNbTimes) anObj = self.TrsfOp.MultiRotate1D(theObject, theAxis, theNbTimes) - RaiseIfFailed("MultiRotate1D", self.TrsfOp) + RaiseIfFailed("MultiRotate1DNbTimes", self.TrsfOp) + anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "multirotation") + return anObj + + ## Rotate the given object around the given axis + # a given number times on the given angle. + # @param theObject The object to be rotated. + # @param theAxis The rotation axis. DZ if None. + # @param theAngleStep Rotation angle in radians. + # @param theNbTimes Quantity of rotations to be done. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @return New GEOM.GEOM_Object, containing compound of all the + # shapes, obtained after each rotation. + # + # @ref tui_multi_rotation "Example" + def MultiRotate1DByStep(self, theObject, theAxis, theAngleStep, theNbTimes, theName=None): + """ + Rotate the given object around the given axis + a given number times on the given angle. + + Parameters: + theObject The object to be rotated. + theAxis The rotation axis. DZ if None. + theAngleStep Rotation angle in radians. + theNbTimes Quantity of rotations to be done. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + New GEOM.GEOM_Object, containing compound of all the + shapes, obtained after each rotation. + + Example of usage: + rot1d = geompy.MultiRotate1DByStep(prism, vect, math.pi/4, 4) + """ + # Example: see GEOM_TestAll.py + theAngleStep, theNbTimes, Parameters = ParseParameters(theAngleStep, theNbTimes) + anObj = self.TrsfOp.MultiRotate1DByStep(theObject, theAxis, theAngleStep, theNbTimes) + RaiseIfFailed("MultiRotate1DByStep", self.TrsfOp) + anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "multirotation") + return anObj + + ## Rotate the given object around the given axis a given + # number times and multi-translate each rotation result. + # Rotation angle will be 2*PI/theNbTimes1. + # Translation direction passes through center of gravity + # of rotated shape and its projection on the rotation axis. + # @param theObject The object to be rotated. + # @param theAxis Rotation axis. DZ if None. + # @param theNbTimes1 Quantity of rotations to be done. + # @param theRadialStep Translation distance. + # @param theNbTimes2 Quantity of translations to be done. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @return New GEOM.GEOM_Object, containing compound of all the + # shapes, obtained after each transformation. + # + # @ref tui_multi_rotation "Example" + def MultiRotate2DNbTimes(self, theObject, theAxis, theNbTimes1, theRadialStep, theNbTimes2, theName=None): + """ + Rotate the given object around the + given axis on the given angle a given number + times and multi-translate each rotation result. + Translation direction passes through center of gravity + of rotated shape and its projection on the rotation axis. + + Parameters: + theObject The object to be rotated. + theAxis Rotation axis. DZ if None. + theNbTimes1 Quantity of rotations to be done. + theRadialStep Translation distance. + theNbTimes2 Quantity of translations to be done. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + New GEOM.GEOM_Object, containing compound of all the + shapes, obtained after each transformation. + + Example of usage: + rot2d = geompy.MultiRotate2D(prism, vect, 60, 4, 50, 5) + """ + # Example: see GEOM_TestAll.py + theNbTimes1, theRadialStep, theNbTimes2, Parameters = ParseParameters(theNbTimes1, theRadialStep, theNbTimes2) + anObj = self.TrsfOp.MultiRotate2DNbTimes(theObject, theAxis, theNbTimes1, theRadialStep, theNbTimes2) + RaiseIfFailed("MultiRotate2DNbTimes", self.TrsfOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "multirotation") return anObj ## Rotate the given object around the @@ -5973,16 +7908,20 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Translation direction passes through center of gravity # of rotated shape and its projection on the rotation axis. # @param theObject The object to be rotated. - # @param theAxis Rotation axis. - # @param theAngle Rotation angle in graduces. + # @param theAxis Rotation axis. DZ if None. + # @param theAngleStep Rotation angle in radians. # @param theNbTimes1 Quantity of rotations to be done. - # @param theStep Translation distance. + # @param theRadialStep Translation distance. # @param theNbTimes2 Quantity of translations to be done. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing compound of all the # shapes, obtained after each transformation. # # @ref tui_multi_rotation "Example" - def MultiRotate2D(self,theObject, theAxis, theAngle, theNbTimes1, theStep, theNbTimes2): + def MultiRotate2DByStep (self, theObject, theAxis, theAngleStep, theNbTimes1, theRadialStep, theNbTimes2, theName=None): """ Rotate the given object around the given axis on the given angle a given number @@ -5992,80 +7931,197 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theObject The object to be rotated. - theAxis Rotation axis. - theAngle Rotation angle in graduces. + theAxis Rotation axis. DZ if None. + theAngleStep Rotation angle in radians. theNbTimes1 Quantity of rotations to be done. - theStep Translation distance. + theRadialStep Translation distance. theNbTimes2 Quantity of translations to be done. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing compound of all the shapes, obtained after each transformation. Example of usage: - rot2d = geompy.MultiRotate2D(prism, vect, 60, 4, 50, 5) + rot2d = geompy.MultiRotate2D(prism, vect, math.pi/3, 4, 50, 5) """ # Example: see GEOM_TestAll.py - theAngle, theNbTimes1, theStep, theNbTimes2, Parameters = ParseParameters(theAngle, theNbTimes1, theStep, theNbTimes2) - anObj = self.TrsfOp.MultiRotate2D(theObject, theAxis, theAngle, theNbTimes1, theStep, theNbTimes2) - RaiseIfFailed("MultiRotate2D", self.TrsfOp) + theAngleStep, theNbTimes1, theRadialStep, theNbTimes2, Parameters = ParseParameters(theAngleStep, theNbTimes1, theRadialStep, theNbTimes2) + anObj = self.TrsfOp.MultiRotate2DByStep(theObject, theAxis, theAngleStep, theNbTimes1, theRadialStep, theNbTimes2) + RaiseIfFailed("MultiRotate2DByStep", self.TrsfOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "multirotation") return anObj - ## The same, as MultiRotate1D(), but axis is given by direction and point + ## The same, as MultiRotate1DNbTimes(), but axis is given by direction and point + # + # @ref swig_MakeMultiRotation "Example" + def MakeMultiRotation1DNbTimes(self, aShape, aDir, aPoint, aNbTimes, theName=None): + """ + The same, as geompy.MultiRotate1DNbTimes, but axis is given by direction and point + + Example of usage: + pz = geompy.MakeVertex(0, 0, 100) + vy = geompy.MakeVectorDXDYDZ(0, 100, 0) + MultiRot1D = geompy.MakeMultiRotation1DNbTimes(prism, vy, pz, 6) + """ + # Example: see GEOM_TestOthers.py + aVec = self.MakeLine(aPoint,aDir) + # note: auto-publishing is done in self.MultiRotate1D() + anObj = self.MultiRotate1DNbTimes(aShape, aVec, aNbTimes, theName) + return anObj + + ## The same, as MultiRotate1DByStep(), but axis is given by direction and point # # @ref swig_MakeMultiRotation "Example" - def MakeMultiRotation1D(self,aShape,aDir,aPoint,aNbTimes): + def MakeMultiRotation1DByStep(self, aShape, aDir, aPoint, anAngle, aNbTimes, theName=None): """ The same, as geompy.MultiRotate1D, but axis is given by direction and point Example of usage: pz = geompy.MakeVertex(0, 0, 100) vy = geompy.MakeVectorDXDYDZ(0, 100, 0) - MultiRot1D = geompy.MakeMultiRotation1D(prism, vy, pz, 6) + MultiRot1D = geompy.MakeMultiRotation1DByStep(prism, vy, pz, math.pi/3, 6) """ # Example: see GEOM_TestOthers.py aVec = self.MakeLine(aPoint,aDir) - anObj = self.MultiRotate1D(aShape,aVec,aNbTimes) + # note: auto-publishing is done in self.MultiRotate1D() + anObj = self.MultiRotate1DByStep(aShape, aVec, anAngle, aNbTimes, theName) return anObj - ## The same, as MultiRotate2D(), but axis is given by direction and point + ## The same, as MultiRotate2DNbTimes(), but axis is given by direction and point # # @ref swig_MakeMultiRotation "Example" - def MakeMultiRotation2D(self,aShape,aDir,aPoint,anAngle,nbtimes1,aStep,nbtimes2): + def MakeMultiRotation2DNbTimes(self, aShape, aDir, aPoint, nbtimes1, aStep, nbtimes2, theName=None): """ - The same, as MultiRotate2D(), but axis is given by direction and point + The same, as MultiRotate2DNbTimes(), but axis is given by direction and point Example of usage: pz = geompy.MakeVertex(0, 0, 100) vy = geompy.MakeVectorDXDYDZ(0, 100, 0) - MultiRot2D = geompy.MakeMultiRotation2D(f12, vy, pz, 45, 6, 30, 3) + MultiRot2D = geompy.MakeMultiRotation2DNbTimes(f12, vy, pz, 6, 30, 3) """ # Example: see GEOM_TestOthers.py aVec = self.MakeLine(aPoint,aDir) - anObj = self.MultiRotate2D(aShape,aVec,anAngle,nbtimes1,aStep,nbtimes2) + # note: auto-publishing is done in self.MultiRotate2DNbTimes() + anObj = self.MultiRotate2DNbTimes(aShape, aVec, nbtimes1, aStep, nbtimes2, theName) + return anObj + + ## The same, as MultiRotate2DByStep(), but axis is given by direction and point + # + # @ref swig_MakeMultiRotation "Example" + def MakeMultiRotation2DByStep(self, aShape, aDir, aPoint, anAngle, nbtimes1, aStep, nbtimes2, theName=None): + """ + The same, as MultiRotate2DByStep(), but axis is given by direction and point + + Example of usage: + pz = geompy.MakeVertex(0, 0, 100) + vy = geompy.MakeVectorDXDYDZ(0, 100, 0) + MultiRot2D = geompy.MakeMultiRotation2DByStep(f12, vy, pz, math.pi/4, 6, 30, 3) + """ + # Example: see GEOM_TestOthers.py + aVec = self.MakeLine(aPoint,aDir) + # note: auto-publishing is done in self.MultiRotate2D() + anObj = self.MultiRotate2DByStep(aShape, aVec, anAngle, nbtimes1, aStep, nbtimes2, theName) return anObj # end of l3_transform ## @} + ## @addtogroup l3_transform_d + ## @{ + + ## Deprecated method. Use MultiRotate1DNbTimes instead. + def MultiRotate1D(self, theObject, theAxis, theNbTimes, theName=None): + """ + Deprecated method. Use MultiRotate1DNbTimes instead. + """ + print "The method MultiRotate1D is DEPRECATED. Use MultiRotate1DNbTimes instead." + return self.MultiRotate1DNbTimes(theObject, theAxis, theNbTimes, theName) + + ## The same, as MultiRotate2DByStep(), but theAngle is in degrees. + # This method is DEPRECATED. Use MultiRotate2DByStep() instead. + def MultiRotate2D(self, theObject, theAxis, theAngle, theNbTimes1, theStep, theNbTimes2, theName=None): + """ + The same, as MultiRotate2DByStep(), but theAngle is in degrees. + This method is DEPRECATED. Use MultiRotate2DByStep() instead. + + Example of usage: + rot2d = geompy.MultiRotate2D(prism, vect, 60, 4, 50, 5) + """ + print "The method MultiRotate2D is DEPRECATED. Use MultiRotate2DByStep instead." + theAngle, theNbTimes1, theStep, theNbTimes2, Parameters = ParseParameters(theAngle, theNbTimes1, theStep, theNbTimes2) + anObj = self.TrsfOp.MultiRotate2D(theObject, theAxis, theAngle, theNbTimes1, theStep, theNbTimes2) + RaiseIfFailed("MultiRotate2D", self.TrsfOp) + anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "multirotation") + return anObj + + ## The same, as MultiRotate1D(), but axis is given by direction and point + # This method is DEPRECATED. Use MakeMultiRotation1DNbTimes instead. + def MakeMultiRotation1D(self, aShape, aDir, aPoint, aNbTimes, theName=None): + """ + The same, as geompy.MultiRotate1D, but axis is given by direction and point. + This method is DEPRECATED. Use MakeMultiRotation1DNbTimes instead. + + Example of usage: + pz = geompy.MakeVertex(0, 0, 100) + vy = geompy.MakeVectorDXDYDZ(0, 100, 0) + MultiRot1D = geompy.MakeMultiRotation1D(prism, vy, pz, 6) + """ + print "The method MakeMultiRotation1D is DEPRECATED. Use MakeMultiRotation1DNbTimes instead." + aVec = self.MakeLine(aPoint,aDir) + # note: auto-publishing is done in self.MultiRotate1D() + anObj = self.MultiRotate1D(aShape, aVec, aNbTimes, theName) + return anObj + + ## The same, as MultiRotate2D(), but axis is given by direction and point + # This method is DEPRECATED. Use MakeMultiRotation2DByStep instead. + def MakeMultiRotation2D(self, aShape, aDir, aPoint, anAngle, nbtimes1, aStep, nbtimes2, theName=None): + """ + The same, as MultiRotate2D(), but axis is given by direction and point + This method is DEPRECATED. Use MakeMultiRotation2DByStep instead. + + Example of usage: + pz = geompy.MakeVertex(0, 0, 100) + vy = geompy.MakeVectorDXDYDZ(0, 100, 0) + MultiRot2D = geompy.MakeMultiRotation2D(f12, vy, pz, 45, 6, 30, 3) + """ + print "The method MakeMultiRotation2D is DEPRECATED. Use MakeMultiRotation2DByStep instead." + aVec = self.MakeLine(aPoint,aDir) + # note: auto-publishing is done in self.MultiRotate2D() + anObj = self.MultiRotate2D(aShape, aVec, anAngle, nbtimes1, aStep, nbtimes2, theName) + return anObj + + # end of l3_transform_d + ## @} + ## @addtogroup l3_local ## @{ ## Perform a fillet on all edges of the given shape. # @param theShape Shape, to perform fillet on. # @param theR Fillet radius. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_fillet "Example 1" # \n @ref swig_MakeFilletAll "Example 2" - def MakeFilletAll(self,theShape, theR): + def MakeFilletAll(self, theShape, theR, theName=None): """ Perform a fillet on all edges of the given shape. Parameters: theShape Shape, to perform fillet on. theR Fillet radius. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the result shape. @@ -6078,6 +8134,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.LocalOp.MakeFilletAll(theShape, theR) RaiseIfFailed("MakeFilletAll", self.LocalOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "fillet") return anObj ## Perform a fillet on the specified edges/faces of the given shape @@ -6085,11 +8142,16 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theR Fillet radius. # @param theShapeType Type of shapes in theListShapes (see ShapeType()) # @param theListShapes Global indices of edges/faces to perform fillet on. - # \note Global index of sub-shape can be obtained, using method GetSubShapeID(). + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @note Global index of sub-shape can be obtained, using method GetSubShapeID(). + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_fillet "Example" - def MakeFillet(self,theShape, theR, theShapeType, theListShapes): + def MakeFillet(self, theShape, theR, theShapeType, theListShapes, theName=None): """ Perform a fillet on the specified edges/faces of the given shape @@ -6098,6 +8160,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theR Fillet radius. theShapeType Type of shapes in theListShapes (see geompy.ShapeTypes) theListShapes Global indices of edges/faces to perform fillet on. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Note: Global index of sub-shape can be obtained, using method geompy.GetSubShapeID @@ -6125,10 +8190,11 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.LocalOp.MakeFilletFaces(theShape, theR, theListShapes) RaiseIfFailed("MakeFilletFaces", self.LocalOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "fillet") return anObj ## The same that MakeFillet() but with two Fillet Radius R1 and R2 - def MakeFilletR1R2(self, theShape, theR1, theR2, theShapeType, theListShapes): + def MakeFilletR1R2(self, theShape, theR1, theR2, theShapeType, theListShapes, theName=None): """ The same that geompy.MakeFillet but with two Fillet Radius R1 and R2 @@ -6151,6 +8217,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.LocalOp.MakeFilletFacesR1R2(theShape, theR1, theR2, theListShapes) RaiseIfFailed("MakeFilletFacesR1R2", self.LocalOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "fillet") return anObj ## Perform a fillet on the specified edges of the given shape @@ -6166,10 +8233,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # the fillet point, and such two (or more) edges can be united to allow # bigger radius. Set this flag to TRUE to allow collinear edges union, # thus ignoring the secant vertex (vertices). + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_fillet2d "Example" - def MakeFillet1D(self,theShape, theR, theListOfVertexes, doIgnoreSecantVertices = True): + def MakeFillet1D(self, theShape, theR, theListOfVertexes, doIgnoreSecantVertices = True, theName=None): """ Perform a fillet on the specified edges of the given shape @@ -6183,6 +8254,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): the fillet point, and such two (or more) edges can be united to allow bigger radius. Set this flag to TRUE to allow collinear edges union, thus ignoring the secant vertex (vertices). + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Note: Global index of sub-shape can be obtained, using method geompy.GetSubShapeID @@ -6202,17 +8276,23 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.LocalOp.MakeFillet1D(theShape, theR, theListOfVertexes, doIgnoreSecantVertices) RaiseIfFailed("MakeFillet1D", self.LocalOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "fillet") return anObj ## Perform a fillet at the specified vertices of the given face/shell. # @param theShape Face or Shell shape to perform fillet on. # @param theR Fillet radius. # @param theListOfVertexes Global indices of vertexes to perform fillet on. - # \note Global index of sub-shape can be obtained, using method GetSubShapeID(). + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @note Global index of sub-shape can be obtained, using method GetSubShapeID(). + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_fillet2d "Example" - def MakeFillet2D(self, theShape, theR, theListOfVertexes): + def MakeFillet2D(self, theShape, theR, theListOfVertexes, theName=None): """ Perform a fillet at the specified vertices of the given face/shell. @@ -6220,6 +8300,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShape Face or Shell shape to perform fillet on. theR Fillet radius. theListOfVertexes Global indices of vertexes to perform fillet on. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Note: Global index of sub-shape can be obtained, using method geompy.GetSubShapeID @@ -6235,22 +8318,30 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.LocalOp.MakeFillet2D(theShape, theR, theListOfVertexes) RaiseIfFailed("MakeFillet2D", self.LocalOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "fillet") return anObj ## Perform a symmetric chamfer on all edges of the given shape. # @param theShape Shape, to perform chamfer on. # @param theD Chamfer size along each face. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_chamfer "Example 1" # \n @ref swig_MakeChamferAll "Example 2" - def MakeChamferAll(self,theShape, theD): + def MakeChamferAll(self, theShape, theD, theName=None): """ Perform a symmetric chamfer on all edges of the given shape. Parameters: theShape Shape, to perform chamfer on. theD Chamfer size along each face. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the result shape. @@ -6263,6 +8354,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.LocalOp.MakeChamferAll(theShape, theD) RaiseIfFailed("MakeChamferAll", self.LocalOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "chamfer") return anObj ## Perform a chamfer on edges, common to the specified faces, @@ -6271,11 +8363,16 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theD1 Chamfer size along \a theFace1. # @param theD2 Chamfer size along \a theFace2. # @param theFace1,theFace2 Global indices of two faces of \a theShape. - # \note Global index of sub-shape can be obtained, using method GetSubShapeID(). + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @note Global index of sub-shape can be obtained, using method GetSubShapeID(). + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_chamfer "Example" - def MakeChamferEdge(self,theShape, theD1, theD2, theFace1, theFace2): + def MakeChamferEdge(self, theShape, theD1, theD2, theFace1, theFace2, theName=None): """ Perform a chamfer on edges, common to the specified faces, with distance D1 on the Face1 @@ -6285,6 +8382,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theD1 Chamfer size along theFace1. theD2 Chamfer size along theFace2. theFace1,theFace2 Global indices of two faces of theShape. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Note: Global index of sub-shape can be obtained, using method geompy.GetSubShapeID @@ -6303,6 +8403,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.LocalOp.MakeChamferEdge(theShape, theD1, theD2, theFace1, theFace2) RaiseIfFailed("MakeChamferEdge", self.LocalOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "chamfer") return anObj ## Perform a chamfer on edges @@ -6310,9 +8411,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theD Chamfer length # @param theAngle Angle of chamfer (angle in radians or a name of variable which defines angle in degrees) # @param theFace1,theFace2 Global indices of two faces of \a theShape. - # \note Global index of sub-shape can be obtained, using method GetSubShapeID(). + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @note Global index of sub-shape can be obtained, using method GetSubShapeID(). + # # @return New GEOM.GEOM_Object, containing the result shape. - def MakeChamferEdgeAD(self, theShape, theD, theAngle, theFace1, theFace2): + def MakeChamferEdgeAD(self, theShape, theD, theAngle, theFace1, theFace2, theName=None): """ Perform a chamfer on edges @@ -6321,6 +8427,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theD1 Chamfer size along theFace1. theAngle Angle of chamfer (angle in radians or a name of variable which defines angle in degrees). theFace1,theFace2 Global indices of two faces of theShape. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Note: Global index of sub-shape can be obtained, using method geompy.GetSubShapeID @@ -6344,6 +8453,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.LocalOp.MakeChamferEdgeAD(theShape, theD, theAngle, theFace1, theFace2) RaiseIfFailed("MakeChamferEdgeAD", self.LocalOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "chamfer") return anObj ## Perform a chamfer on all edges of the specified faces, @@ -6354,11 +8464,16 @@ class geompyDC(GEOM._objref_GEOM_Gen): # will be get along face, which is nearer to \a theFaces beginning. # @param theD2 Chamfer size along another of two faces, connected to the edge. # @param theFaces Sequence of global indices of faces of \a theShape. - # \note Global index of sub-shape can be obtained, using method GetSubShapeID(). + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @note Global index of sub-shape can be obtained, using method GetSubShapeID(). + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_chamfer "Example" - def MakeChamferFaces(self,theShape, theD1, theD2, theFaces): + def MakeChamferFaces(self, theShape, theD1, theD2, theFaces, theName=None): """ Perform a chamfer on all edges of the specified faces, with distance D1 on the first specified face (if several for one edge) @@ -6370,7 +8485,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): will be get along face, which is nearer to theFaces beginning. theD2 Chamfer size along another of two faces, connected to the edge. theFaces Sequence of global indices of faces of theShape. - + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Note: Global index of sub-shape can be obtained, using method geompy.GetSubShapeID(). @@ -6382,13 +8499,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.LocalOp.MakeChamferFaces(theShape, theD1, theD2, theFaces) RaiseIfFailed("MakeChamferFaces", self.LocalOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "chamfer") return anObj ## The Same that MakeChamferFaces() but with params theD is chamfer lenght and # theAngle is Angle of chamfer (angle in radians or a name of variable which defines angle in degrees) # # @ref swig_FilletChamfer "Example" - def MakeChamferFacesAD(self, theShape, theD, theAngle, theFaces): + def MakeChamferFacesAD(self, theShape, theD, theAngle, theFaces, theName=None): """ The Same that geompy.MakeChamferFaces but with params theD is chamfer lenght and theAngle is Angle of chamfer (angle in radians or a name of variable which defines angle in degrees) @@ -6402,6 +8520,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.LocalOp.MakeChamferFacesAD(theShape, theD, theAngle, theFaces) RaiseIfFailed("MakeChamferFacesAD", self.LocalOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "chamfer") return anObj ## Perform a chamfer on edges, @@ -6409,10 +8528,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theShape Shape, to perform chamfer on. # @param theD1,theD2 Chamfer size # @param theEdges Sequence of edges of \a theShape. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref swig_FilletChamfer "Example" - def MakeChamferEdges(self, theShape, theD1, theD2, theEdges): + def MakeChamferEdges(self, theShape, theD1, theD2, theEdges, theName=None): """ Perform a chamfer on edges, with distance D1 on the first specified face (if several for one edge) @@ -6421,6 +8544,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShape Shape, to perform chamfer on. theD1,theD2 Chamfer size theEdges Sequence of edges of theShape. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the result shape. @@ -6429,11 +8555,12 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.LocalOp.MakeChamferEdges(theShape, theD1, theD2, theEdges) RaiseIfFailed("MakeChamferEdges", self.LocalOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "chamfer") return anObj ## The Same that MakeChamferEdges() but with params theD is chamfer lenght and # theAngle is Angle of chamfer (angle in radians or a name of variable which defines angle in degrees) - def MakeChamferEdgesAD(self, theShape, theD, theAngle, theEdges): + def MakeChamferEdgesAD(self, theShape, theD, theAngle, theEdges, theName=None): """ The Same that geompy.MakeChamferEdges but with params theD is chamfer lenght and theAngle is Angle of chamfer (angle in radians or a name of variable which defines angle in degrees) @@ -6447,21 +8574,23 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.LocalOp.MakeChamferEdgesAD(theShape, theD, theAngle, theEdges) RaiseIfFailed("MakeChamferEdgesAD", self.LocalOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "chamfer") return anObj - ## /sa MakeChamferEdge() and MakeChamferFaces() + ## @sa MakeChamferEdge(), MakeChamferFaces() # # @ref swig_MakeChamfer "Example" - def MakeChamfer(self,aShape,d1,d2,aShapeType,ListShape): + def MakeChamfer(self, aShape, d1, d2, aShapeType, ListShape, theName=None): """ See geompy.MakeChamferEdge() and geompy.MakeChamferFaces() functions for more information. """ # Example: see GEOM_TestOthers.py anObj = None + # note: auto-publishing is done in self.MakeChamferEdge() or self.MakeChamferFaces() if aShapeType == ShapeType["EDGE"]: - anObj = self.MakeChamferEdge(aShape,d1,d2,ListShape[0],ListShape[1]) + anObj = self.MakeChamferEdge(aShape,d1,d2,ListShape[0],ListShape[1],theName) else: - anObj = self.MakeChamferFaces(aShape,d1,d2,ListShape) + anObj = self.MakeChamferFaces(aShape,d1,d2,ListShape,theName) return anObj ## Remove material from a solid by extrusion of the base shape on the given distance. @@ -6470,10 +8599,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theBase Closed edge or wire defining the base shape to be extruded. # @param theH Prism dimension along the normal to theBase # @param theAngle Draft angle in degrees. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the initial shape with removed material # # @ref tui_creation_prism "Example" - def MakeExtrudedCut(self, theInit, theBase, theH, theAngle): + def MakeExtrudedCut(self, theInit, theBase, theH, theAngle, theName=None): """ Add material to a solid by extrusion of the base shape on the given distance. @@ -6482,6 +8615,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theBase Closed edge or wire defining the base shape to be extruded. theH Prism dimension along the normal to theBase theAngle Draft angle in degrees. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the initial shape with removed material. @@ -6491,6 +8627,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeDraftPrism(theInit, theBase, theH, theAngle, False) RaiseIfFailed("MakeExtrudedBoss", self.PrimOp) #anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "extrudedCut") return anObj ## Add material to a solid by extrusion of the base shape on the given distance. @@ -6499,10 +8636,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theBase Closed edge or wire defining the base shape to be extruded. # @param theH Prism dimension along the normal to theBase # @param theAngle Draft angle in degrees. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the initial shape with added material # # @ref tui_creation_prism "Example" - def MakeExtrudedBoss(self, theInit, theBase, theH, theAngle): + def MakeExtrudedBoss(self, theInit, theBase, theH, theAngle, theName=None): """ Add material to a solid by extrusion of the base shape on the given distance. @@ -6511,6 +8652,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theBase Closed edge or wire defining the base shape to be extruded. theH Prism dimension along the normal to theBase theAngle Draft angle in degrees. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the initial shape with added material. @@ -6520,6 +8664,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.PrimOp.MakeDraftPrism(theInit, theBase, theH, theAngle, True) RaiseIfFailed("MakeExtrudedBoss", self.PrimOp) #anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "extrudedBoss") return anObj # end of l3_local @@ -6534,11 +8679,15 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theWeight Weight og the shape. # @param theWaterDensity Density of the water. # @param theMeshDeflection Deflection of the mesh, using to compute the section. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing a section of \a theShape # by a plane, corresponding to water level. # # @ref tui_archimede "Example" - def Archimede(self,theShape, theWeight, theWaterDensity, theMeshDeflection): + def Archimede(self, theShape, theWeight, theWaterDensity, theMeshDeflection, theName=None): """ Perform an Archimde operation on the given shape with given parameters. The object presenting the resulting face is returned. @@ -6548,6 +8697,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theWeight Weight og the shape. theWaterDensity Density of the water. theMeshDeflection Deflection of the mesh, using to compute the section. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing a section of theShape @@ -6559,6 +8711,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.LocalOp.MakeArchimede(theShape, theWeight, theWaterDensity, theMeshDeflection) RaiseIfFailed("MakeArchimede", self.LocalOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "archimede") return anObj # end of l3_basic_op @@ -6581,7 +8734,61 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestMeasures.py aTuple = self.MeasuOp.PointCoordinates(Point) RaiseIfFailed("PointCoordinates", self.MeasuOp) - return aTuple + return aTuple + + ## Get vector coordinates + # @return [x, y, z] + # + # @ref tui_measurement_tools_page "Example" + def VectorCoordinates(self,Vector): + """ + Get vector coordinates + + Returns: + [x, y, z] + """ + + p1=self.GetFirstVertex(Vector) + p2=self.GetLastVertex(Vector) + + X1=self.PointCoordinates(p1) + X2=self.PointCoordinates(p2) + + return (X2[0]-X1[0],X2[1]-X1[1],X2[2]-X1[2]) + + + ## Compute cross product + # @return vector w=u^v + # + # @ref tui_measurement_tools_page "Example" + def CrossProduct(self, Vector1, Vector2): + """ + Compute cross product + + Returns: vector w=u^v + """ + u=self.VectorCoordinates(Vector1) + v=self.VectorCoordinates(Vector2) + w=self.MakeVectorDXDYDZ(u[1]*v[2]-u[2]*v[1], u[2]*v[0]-u[0]*v[2], u[0]*v[1]-u[1]*v[0]) + + return w + + ## Compute cross product + # @return dot product p=u.v + # + # @ref tui_measurement_tools_page "Example" + def DotProduct(self, Vector1, Vector2): + """ + Compute cross product + + Returns: dot product p=u.v + """ + u=self.VectorCoordinates(Vector1) + v=self.VectorCoordinates(Vector2) + p=u[0]*v[0]+u[1]*v[1]+u[2]*v[2] + + return p + ## Get summarized length of all wires, # area of surface and volume of the given shape. @@ -6619,7 +8826,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Zmin,Zmax: Limits of shape along OZ axis. # # @ref tui_measurement_tools_page "Example" - def BoundingBox(self,theShape): + def BoundingBox (self, theShape): """ Get parameters of bounding box of the given shape @@ -6637,6 +8844,34 @@ class geompyDC(GEOM._objref_GEOM_Gen): RaiseIfFailed("GetBoundingBox", self.MeasuOp) return aTuple + ## Get bounding box of the given shape + # @param theShape Shape to obtain bounding box of. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @return New GEOM.GEOM_Object, containing the created box. + # + # @ref tui_measurement_tools_page "Example" + def MakeBoundingBox (self, theShape, theName=None): + """ + Get bounding box of the given shape + + Parameters: + theShape Shape to obtain bounding box of. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + New GEOM.GEOM_Object, containing the created box. + """ + # Example: see GEOM_TestMeasures.py + anObj = self.MeasuOp.MakeBoundingBox(theShape) + RaiseIfFailed("MakeBoundingBox", self.MeasuOp) + self._autoPublish(anObj, theName, "bndbox") + return anObj + ## Get inertia matrix and moments of inertia of theShape. # @param theShape Shape to calculate inertia of. # @return [I11,I12,I13, I21,I22,I23, I31,I32,I33, Ix,Iy,Iz] @@ -6702,7 +8937,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): ## Get minimal distance between the given shapes. # @param theShape1,theShape2 Shapes to find minimal distance between. - # @return Value of the minimal distance between the given shapes. + # @return Value of the minimal distance between the given shapes, in form of list + # [Distance, DX, DY, DZ]. # # @ref swig_all_measure "Example" def MinDistanceComponents(self, theShape1, theShape2): @@ -6713,7 +8949,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShape1,theShape2 Shapes to find minimal distance between. Returns: - Value of the minimal distance between the given shapes. + Value of the minimal distance between the given shapes, in form of list + [Distance, DX, DY, DZ] """ # Example: see GEOM_TestMeasures.py aTuple = self.MeasuOp.GetMinDistance(theShape1, theShape2) @@ -6721,6 +8958,28 @@ class geompyDC(GEOM._objref_GEOM_Gen): aRes = [aTuple[0], aTuple[4] - aTuple[1], aTuple[5] - aTuple[2], aTuple[6] - aTuple[3]] return aRes + ## Get closest points of the given shapes. + # @param theShape1,theShape2 Shapes to find closest points of. + # @return The number of found solutions (-1 in case of infinite number of + # solutions) and a list of (X, Y, Z) coordinates for all couples of points. + # + # @ref tui_measurement_tools_page "Example" + def ClosestPoints (self, theShape1, theShape2): + """ + Get closest points of the given shapes. + + Parameters: + theShape1,theShape2 Shapes to find closest points of. + + Returns: + The number of found solutions (-1 in case of infinite number of + solutions) and a list of (X, Y, Z) coordinates for all couples of points. + """ + # Example: see GEOM_TestMeasures.py + aTuple = self.MeasuOp.ClosestPoints(theShape1, theShape2) + RaiseIfFailed("ClosestPoints", self.MeasuOp) + return aTuple + ## Get angle between the given shapes in degrees. # @param theShape1,theShape2 Lines or linear edges to find angle between. # @note If both arguments are vectors, the angle is computed in accordance @@ -7066,15 +9325,22 @@ class geompyDC(GEOM._objref_GEOM_Gen): ## Get a point, situated at the centre of mass of theShape. # @param theShape Shape to define centre of mass of. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created point. # # @ref tui_measurement_tools_page "Example" - def MakeCDG(self,theShape): + def MakeCDG(self, theShape, theName=None): """ Get a point, situated at the centre of mass of theShape. Parameters: theShape Shape to define centre of mass of. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created point. @@ -7082,21 +9348,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestMeasures.py anObj = self.MeasuOp.GetCentreOfMass(theShape) RaiseIfFailed("GetCentreOfMass", self.MeasuOp) + self._autoPublish(anObj, theName, "centerOfMass") return anObj ## Get a vertex sub-shape by index depended with orientation. # @param theShape Shape to find sub-shape. # @param theIndex Index to find vertex by this index (starting from zero) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created vertex. # # @ref tui_measurement_tools_page "Example" - def GetVertexByIndex(self,theShape, theIndex): + def GetVertexByIndex(self, theShape, theIndex, theName=None): """ Get a vertex sub-shape by index depended with orientation. Parameters: theShape Shape to find sub-shape. theIndex Index to find vertex by this index (starting from zero) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created vertex. @@ -7104,46 +9378,63 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestMeasures.py anObj = self.MeasuOp.GetVertexByIndex(theShape, theIndex) RaiseIfFailed("GetVertexByIndex", self.MeasuOp) + self._autoPublish(anObj, theName, "vertex") return anObj ## Get the first vertex of wire/edge depended orientation. # @param theShape Shape to find first vertex. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created vertex. # # @ref tui_measurement_tools_page "Example" - def GetFirstVertex(self,theShape): + def GetFirstVertex(self, theShape, theName=None): """ Get the first vertex of wire/edge depended orientation. Parameters: theShape Shape to find first vertex. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created vertex. """ # Example: see GEOM_TestMeasures.py - anObj = self.GetVertexByIndex(theShape, 0) + # note: auto-publishing is done in self.GetVertexByIndex() + anObj = self.GetVertexByIndex(theShape, 0, theName) RaiseIfFailed("GetFirstVertex", self.MeasuOp) return anObj ## Get the last vertex of wire/edge depended orientation. # @param theShape Shape to find last vertex. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created vertex. # # @ref tui_measurement_tools_page "Example" - def GetLastVertex(self,theShape): + def GetLastVertex(self, theShape, theName=None): """ Get the last vertex of wire/edge depended orientation. Parameters: theShape Shape to find last vertex. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created vertex. """ # Example: see GEOM_TestMeasures.py nb_vert = self.ShapesOp.NumberOfSubShapes(theShape, ShapeType["VERTEX"]) - anObj = self.GetVertexByIndex(theShape, (nb_vert-1)) + # note: auto-publishing is done in self.GetVertexByIndex() + anObj = self.GetVertexByIndex(theShape, (nb_vert-1), theName) RaiseIfFailed("GetLastVertex", self.MeasuOp) return anObj @@ -7151,10 +9442,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # the normale is calculated at the center of mass. # @param theFace Face to define normale of. # @param theOptionalPoint Point to compute the normale at. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created vector. # # @ref swig_todo "Example" - def GetNormal(self, theFace, theOptionalPoint = None): + def GetNormal(self, theFace, theOptionalPoint = None, theName=None): """ Get a normale to the given face. If the point is not given, the normale is calculated at the center of mass. @@ -7162,6 +9457,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theFace Face to define normale of. theOptionalPoint Point to compute the normale at. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created vector. @@ -7169,6 +9467,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestMeasures.py anObj = self.MeasuOp.GetNormal(theFace, theOptionalPoint) RaiseIfFailed("GetNormal", self.MeasuOp) + self._autoPublish(anObj, theName, "normal") return anObj ## Check a topology of the given shape. @@ -7324,10 +9623,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # If format 'IGES_SCALE' is used instead of 'IGES' or # format 'STEP_SCALE' is used instead of 'STEP', # length unit will be set to 'meter' and result model will be scaled. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the imported shape. # # @ref swig_Import_Export "Example" - def ImportFile(self, theFileName, theFormatName): + def ImportFile(self, theFileName, theFormatName, theName=None): """ Import a shape from the BREP or IGES or STEP file (depends on given format) with given name. @@ -7339,44 +9642,55 @@ class geompyDC(GEOM._objref_GEOM_Gen): If format 'IGES_SCALE' is used instead of 'IGES' or format 'STEP_SCALE' is used instead of 'STEP', length unit will be set to 'meter' and result model will be scaled. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the imported shape. """ # Example: see GEOM_TestOthers.py anObj = self.InsertOp.ImportFile(theFileName, theFormatName) - RaiseIfFailed("Import", self.InsertOp) + RaiseIfFailed("ImportFile", self.InsertOp) + self._autoPublish(anObj, theName, "imported") return anObj ## Deprecated analog of ImportFile() - def Import(self, theFileName, theFormatName): + def Import(self, theFileName, theFormatName, theName=None): """ - Deprecated analog of geompy.ImportFile + Deprecated analog of geompy.ImportFile, kept for backward compatibility only. """ print "WARNING: Function Import is deprecated, use ImportFile instead" - anObj = self.InsertOp.ImportFile(theFileName, theFormatName) - RaiseIfFailed("Import", self.InsertOp) - return anObj + # note: auto-publishing is done in self.ImportFile() + return self.ImportFile(theFileName, theFormatName, theName) ## Shortcut to ImportFile() for BREP format. # Import a shape from the BREP file with given name. # @param theFileName The file, containing the shape. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the imported shape. # # @ref swig_Import_Export "Example" - def ImportBREP(self, theFileName): + def ImportBREP(self, theFileName, theName=None): """ geompy.ImportFile(...) function for BREP format Import a shape from the BREP file with given name. Parameters: theFileName The file, containing the shape. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the imported shape. """ # Example: see GEOM_TestOthers.py - return self.ImportFile(theFileName, "BREP") + # note: auto-publishing is done in self.ImportFile() + return self.ImportFile(theFileName, "BREP", theName) ## Shortcut to ImportFile() for IGES format # Import a shape from the IGES file with given name. @@ -7384,10 +9698,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param ignoreUnits If True, file length units will be ignored (set to 'meter') # and result model will be scaled, if its units are not meters. # If False (default), file length units will be taken into account. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the imported shape. # # @ref swig_Import_Export "Example" - def ImportIGES(self, theFileName, ignoreUnits = False): + def ImportIGES(self, theFileName, ignoreUnits = False, theName=None): """ geompy.ImportFile(...) function for IGES format @@ -7396,14 +9714,18 @@ class geompyDC(GEOM._objref_GEOM_Gen): ignoreUnits If True, file length units will be ignored (set to 'meter') and result model will be scaled, if its units are not meters. If False (default), file length units will be taken into account. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the imported shape. """ # Example: see GEOM_TestOthers.py + # note: auto-publishing is done in self.ImportFile() if ignoreUnits: - return self.ImportFile(theFileName, "IGES_SCALE") - return self.ImportFile(theFileName, "IGES") + return self.ImportFile(theFileName, "IGES_SCALE", theName) + return self.ImportFile(theFileName, "IGES", theName) ## Return length unit from given IGES file # @param theFileName The file, containing the shape. @@ -7430,10 +9752,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param ignoreUnits If True, file length units will be ignored (set to 'meter') # and result model will be scaled, if its units are not meters. # If False (default), file length units will be taken into account. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the imported shape. # # @ref swig_Import_Export "Example" - def ImportSTEP(self, theFileName, ignoreUnits = False): + def ImportSTEP(self, theFileName, ignoreUnits = False, theName=None): """ geompy.ImportFile(...) function for STEP format @@ -7442,14 +9768,18 @@ class geompyDC(GEOM._objref_GEOM_Gen): ignoreUnits If True, file length units will be ignored (set to 'meter') and result model will be scaled, if its units are not meters. If False (default), file length units will be taken into account. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the imported shape. """ # Example: see GEOM_TestOthers.py + # note: auto-publishing is done in self.ImportFile() if ignoreUnits: - return self.ImportFile(theFileName, "STEP_SCALE") - return self.ImportFile(theFileName, "STEP") + return self.ImportFile(theFileName, "STEP_SCALE", theName) + return self.ImportFile(theFileName, "STEP", theName) ## Return length unit from given IGES or STEP file # @param theFileName The file, containing the shape. @@ -7474,10 +9804,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @note This method will not be dumped to the python script by DumpStudy functionality. # @note GEOM.GEOM_Object.GetShapeStream() method can be used to obtain the shape's BRep stream. # @param theStream The BRep binary stream. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM_Object, containing the shape, read from theStream. # # @ref swig_Import_Export "Example" - def RestoreShape (self, theStream): + def RestoreShape (self, theStream, theName=None): """ Read a shape from the binary stream, containing its bounding representation (BRep). @@ -7486,6 +9820,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theStream The BRep binary stream. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM_Object, containing the shape, read from theStream. @@ -7493,13 +9830,15 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py anObj = self.InsertOp.RestoreShape(theStream) RaiseIfFailed("RestoreShape", self.InsertOp) + self._autoPublish(anObj, theName, "restored") return anObj ## Export the given shape into a file with given name. # @param theObject Shape to be stored in the file. # @param theFileName Name of the file to store the given shape in. # @param theFormatName Specify format for the shape storage. - # Available formats can be obtained with InsertOp.ImportTranslators() method. + # Available formats can be obtained with + # geompy.InsertOp.ExportTranslators()[0] method. # # @ref swig_Import_Export "Example" def Export(self, theObject, theFileName, theFormatName): @@ -7510,7 +9849,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): theObject Shape to be stored in the file. theFileName Name of the file to store the given shape in. theFormatName Specify format for the shape storage. - Available formats can be obtained with geompy.InsertOp.ImportTranslators() method. + Available formats can be obtained with + geompy.InsertOp.ExportTranslators()[0] method. """ # Example: see GEOM_TestOthers.py self.InsertOp.Export(theObject, theFileName, theFormatName) @@ -7558,16 +9898,23 @@ class geompyDC(GEOM._objref_GEOM_Gen): ## Create a quadrangle face from four edges. Order of Edges is not # important. It is not necessary that edges share the same vertex. # @param E1,E2,E3,E4 Edges for the face bound. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created face. # # @ref tui_building_by_blocks_page "Example" - def MakeQuad(self,E1, E2, E3, E4): + def MakeQuad(self, E1, E2, E3, E4, theName=None): """ Create a quadrangle face from four edges. Order of Edges is not important. It is not necessary that edges share the same vertex. Parameters: E1,E2,E3,E4 Edges for the face bound. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created face. @@ -7578,21 +9925,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py anObj = self.BlocksOp.MakeQuad(E1, E2, E3, E4) RaiseIfFailed("MakeQuad", self.BlocksOp) + self._autoPublish(anObj, theName, "quad") return anObj ## Create a quadrangle face on two edges. # The missing edges will be built by creating the shortest ones. # @param E1,E2 Two opposite edges for the face. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created face. # # @ref tui_building_by_blocks_page "Example" - def MakeQuad2Edges(self,E1, E2): + def MakeQuad2Edges(self, E1, E2, theName=None): """ Create a quadrangle face on two edges. The missing edges will be built by creating the shortest ones. Parameters: E1,E2 Two opposite edges for the face. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created face. @@ -7612,22 +9967,30 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py anObj = self.BlocksOp.MakeQuad2Edges(E1, E2) RaiseIfFailed("MakeQuad2Edges", self.BlocksOp) + self._autoPublish(anObj, theName, "quad") return anObj ## Create a quadrangle face with specified corners. # The missing edges will be built by creating the shortest ones. # @param V1,V2,V3,V4 Corner vertices for the face. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created face. # # @ref tui_building_by_blocks_page "Example 1" # \n @ref swig_MakeQuad4Vertices "Example 2" - def MakeQuad4Vertices(self,V1, V2, V3, V4): + def MakeQuad4Vertices(self, V1, V2, V3, V4, theName=None): """ Create a quadrangle face with specified corners. The missing edges will be built by creating the shortest ones. Parameters: V1,V2,V3,V4 Corner vertices for the face. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created face. @@ -7644,22 +10007,30 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py anObj = self.BlocksOp.MakeQuad4Vertices(V1, V2, V3, V4) RaiseIfFailed("MakeQuad4Vertices", self.BlocksOp) + self._autoPublish(anObj, theName, "quad") return anObj ## Create a hexahedral solid, bounded by the six given faces. Order of # faces is not important. It is not necessary that Faces share the same edge. # @param F1,F2,F3,F4,F5,F6 Faces for the hexahedral solid. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created solid. # # @ref tui_building_by_blocks_page "Example 1" # \n @ref swig_MakeHexa "Example 2" - def MakeHexa(self,F1, F2, F3, F4, F5, F6): + def MakeHexa(self, F1, F2, F3, F4, F5, F6, theName=None): """ Create a hexahedral solid, bounded by the six given faces. Order of faces is not important. It is not necessary that Faces share the same edge. Parameters: F1,F2,F3,F4,F5,F6 Faces for the hexahedral solid. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created solid. @@ -7670,22 +10041,30 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py anObj = self.BlocksOp.MakeHexa(F1, F2, F3, F4, F5, F6) RaiseIfFailed("MakeHexa", self.BlocksOp) + self._autoPublish(anObj, theName, "hexa") return anObj ## Create a hexahedral solid between two given faces. # The missing faces will be built by creating the smallest ones. # @param F1,F2 Two opposite faces for the hexahedral solid. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the created solid. # # @ref tui_building_by_blocks_page "Example 1" # \n @ref swig_MakeHexa2Faces "Example 2" - def MakeHexa2Faces(self,F1, F2): + def MakeHexa2Faces(self, F1, F2, theName=None): """ Create a hexahedral solid between two given faces. The missing faces will be built by creating the smallest ones. Parameters: F1,F2 Two opposite faces for the hexahedral solid. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the created solid. @@ -7696,6 +10075,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py anObj = self.BlocksOp.MakeHexa2Faces(F1, F2) RaiseIfFailed("MakeHexa2Faces", self.BlocksOp) + self._autoPublish(anObj, theName, "hexa") return anObj # end of l3_blocks @@ -7709,10 +10089,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theX,theY,theZ Coordinates of the sought vertex. # @param theEpsilon Maximum allowed distance between the resulting # vertex and point with the given coordinates. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the found vertex. # # @ref swig_GetPoint "Example" - def GetPoint(self, theShape, theX, theY, theZ, theEpsilon): + def GetPoint(self, theShape, theX, theY, theZ, theEpsilon, theName=None): """ Get a vertex, found in the given shape by its coordinates. @@ -7721,6 +10105,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theX,theY,theZ Coordinates of the sought vertex. theEpsilon Maximum allowed distance between the resulting vertex and point with the given coordinates. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the found vertex. @@ -7731,21 +10118,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py anObj = self.BlocksOp.GetPoint(theShape, theX, theY, theZ, theEpsilon) RaiseIfFailed("GetPoint", self.BlocksOp) + self._autoPublish(anObj, theName, "vertex") return anObj ## Find a vertex of the given shape, which has minimal distance to the given point. # @param theShape Any shape. # @param thePoint Point, close to the desired vertex. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the found vertex. # # @ref swig_GetVertexNearPoint "Example" - def GetVertexNearPoint(self, theShape, thePoint): + def GetVertexNearPoint(self, theShape, thePoint, theName=None): """ Find a vertex of the given shape, which has minimal distance to the given point. Parameters: theShape Any shape. thePoint Point, close to the desired vertex. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the found vertex. @@ -7757,21 +10152,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py anObj = self.BlocksOp.GetVertexNearPoint(theShape, thePoint) RaiseIfFailed("GetVertexNearPoint", self.BlocksOp) + self._autoPublish(anObj, theName, "vertex") return anObj ## Get an edge, found in the given shape by two given vertices. # @param theShape Block or a compound of blocks. # @param thePoint1,thePoint2 Points, close to the ends of the desired edge. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the found edge. # # @ref swig_GetEdge "Example" - def GetEdge(self, theShape, thePoint1, thePoint2): + def GetEdge(self, theShape, thePoint1, thePoint2, theName=None): """ Get an edge, found in the given shape by two given vertices. Parameters: theShape Block or a compound of blocks. thePoint1,thePoint2 Points, close to the ends of the desired edge. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the found edge. @@ -7779,21 +10182,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py anObj = self.BlocksOp.GetEdge(theShape, thePoint1, thePoint2) RaiseIfFailed("GetEdge", self.BlocksOp) + self._autoPublish(anObj, theName, "edge") return anObj ## Find an edge of the given shape, which has minimal distance to the given point. # @param theShape Block or a compound of blocks. # @param thePoint Point, close to the desired edge. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the found edge. # # @ref swig_GetEdgeNearPoint "Example" - def GetEdgeNearPoint(self, theShape, thePoint): + def GetEdgeNearPoint(self, theShape, thePoint, theName=None): """ Find an edge of the given shape, which has minimal distance to the given point. Parameters: theShape Block or a compound of blocks. thePoint Point, close to the desired edge. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the found edge. @@ -7801,21 +10212,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py anObj = self.BlocksOp.GetEdgeNearPoint(theShape, thePoint) RaiseIfFailed("GetEdgeNearPoint", self.BlocksOp) + self._autoPublish(anObj, theName, "edge") return anObj ## Returns a face, found in the given shape by four given corner vertices. # @param theShape Block or a compound of blocks. # @param thePoint1,thePoint2,thePoint3,thePoint4 Points, close to the corners of the desired face. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the found face. # # @ref swig_todo "Example" - def GetFaceByPoints(self,theShape, thePoint1, thePoint2, thePoint3, thePoint4): + def GetFaceByPoints(self, theShape, thePoint1, thePoint2, thePoint3, thePoint4, theName=None): """ Returns a face, found in the given shape by four given corner vertices. Parameters: theShape Block or a compound of blocks. thePoint1,thePoint2,thePoint3,thePoint4 Points, close to the corners of the desired face. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the found face. @@ -7823,21 +10242,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py anObj = self.BlocksOp.GetFaceByPoints(theShape, thePoint1, thePoint2, thePoint3, thePoint4) RaiseIfFailed("GetFaceByPoints", self.BlocksOp) + self._autoPublish(anObj, theName, "face") return anObj ## Get a face of block, found in the given shape by two given edges. # @param theShape Block or a compound of blocks. # @param theEdge1,theEdge2 Edges, close to the edges of the desired face. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the found face. # # @ref swig_todo "Example" - def GetFaceByEdges(self,theShape, theEdge1, theEdge2): + def GetFaceByEdges(self, theShape, theEdge1, theEdge2, theName=None): """ Get a face of block, found in the given shape by two given edges. Parameters: theShape Block or a compound of blocks. theEdge1,theEdge2 Edges, close to the edges of the desired face. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the found face. @@ -7845,21 +10272,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py anObj = self.BlocksOp.GetFaceByEdges(theShape, theEdge1, theEdge2) RaiseIfFailed("GetFaceByEdges", self.BlocksOp) + self._autoPublish(anObj, theName, "face") return anObj ## Find a face, opposite to the given one in the given block. # @param theBlock Must be a hexahedral solid. # @param theFace Face of \a theBlock, opposite to the desired face. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the found face. # # @ref swig_GetOppositeFace "Example" - def GetOppositeFace(self,theBlock, theFace): + def GetOppositeFace(self, theBlock, theFace, theName=None): """ Find a face, opposite to the given one in the given block. Parameters: theBlock Must be a hexahedral solid. theFace Face of theBlock, opposite to the desired face. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the found face. @@ -7867,21 +10302,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py anObj = self.BlocksOp.GetOppositeFace(theBlock, theFace) RaiseIfFailed("GetOppositeFace", self.BlocksOp) + self._autoPublish(anObj, theName, "face") return anObj ## Find a face of the given shape, which has minimal distance to the given point. # @param theShape Block or a compound of blocks. # @param thePoint Point, close to the desired face. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the found face. # # @ref swig_GetFaceNearPoint "Example" - def GetFaceNearPoint(self, theShape, thePoint): + def GetFaceNearPoint(self, theShape, thePoint, theName=None): """ Find a face of the given shape, which has minimal distance to the given point. Parameters: theShape Block or a compound of blocks. thePoint Point, close to the desired face. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the found face. @@ -7889,21 +10332,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py anObj = self.BlocksOp.GetFaceNearPoint(theShape, thePoint) RaiseIfFailed("GetFaceNearPoint", self.BlocksOp) + self._autoPublish(anObj, theName, "face") return anObj ## Find a face of block, whose outside normale has minimal angle with the given vector. # @param theBlock Block or a compound of blocks. # @param theVector Vector, close to the normale of the desired face. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the found face. # # @ref swig_todo "Example" - def GetFaceByNormale(self, theBlock, theVector): + def GetFaceByNormale(self, theBlock, theVector, theName=None): """ Find a face of block, whose outside normale has minimal angle with the given vector. Parameters: theBlock Block or a compound of blocks. theVector Vector, close to the normale of the desired face. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the found face. @@ -7911,6 +10362,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py anObj = self.BlocksOp.GetFaceByNormale(theBlock, theVector) RaiseIfFailed("GetFaceByNormale", self.BlocksOp) + self._autoPublish(anObj, theName, "face") return anObj ## Find all sub-shapes of type \a theShapeType of the given shape, @@ -7921,10 +10373,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theTolerance The tolerance for distances comparison. All shapes # with distances to the given point in interval # [minimal_distance, minimal_distance + theTolerance] will be gathered. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM_Object, containing a group of all found shapes. # # @ref swig_GetShapesNearPoint "Example" - def GetShapesNearPoint(self, theShape, thePoint, theShapeType, theTolerance = 1e-07): + def GetShapesNearPoint(self, theShape, thePoint, theShapeType, theTolerance = 1e-07, theName=None): """ Find all sub-shapes of type theShapeType of the given shape, which have minimal distance to the given point. @@ -7936,6 +10392,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theTolerance The tolerance for distances comparison. All shapes with distances to the given point in interval [minimal_distance, minimal_distance + theTolerance] will be gathered. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM_Object, containing a group of all found shapes. @@ -7943,6 +10402,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py anObj = self.BlocksOp.GetShapesNearPoint(theShape, thePoint, theShapeType, theTolerance) RaiseIfFailed("GetShapesNearPoint", self.BlocksOp) + self._autoPublish(anObj, theName, "group") return anObj # end of l3_blocks_op @@ -7991,6 +10451,10 @@ class geompyDC(GEOM._objref_GEOM_Gen): ## Retrieve all non blocks solids and faces from \a theShape. # @param theShape The shape to explore. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return A tuple of two GEOM_Objects. The first object is a group of all # non block solids (= not 6 faces, or with 6 faces, but with the # presence of non-quadrangular faces). The second object is a @@ -7998,12 +10462,15 @@ class geompyDC(GEOM._objref_GEOM_Gen): # # @ref tui_measurement_tools_page "Example 1" # \n @ref swig_GetNonBlocks "Example 2" - def GetNonBlocks (self, theShape): + def GetNonBlocks (self, theShape, theName=None): """ Retrieve all non blocks solids and faces from theShape. Parameters: theShape The shape to explore. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: A tuple of two GEOM_Objects. The first object is a group of all @@ -8017,6 +10484,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py aTuple = self.BlocksOp.GetNonBlocks(theShape) RaiseIfFailed("GetNonBlocks", self.BlocksOp) + self._autoPublish(aTuple, theName, ("groupNonHexas", "groupNonQuads")) return aTuple ## Remove all seam and degenerated edges from \a theShape. @@ -8025,10 +10493,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theShape The compound or single solid to remove irregular edges from. # @param doUnionFaces If True, then unite faces. If False (the default value), # do not unite faces. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return Improved shape. # # @ref swig_RemoveExtraEdges "Example" - def RemoveExtraEdges(self, theShape, doUnionFaces=False): + def RemoveExtraEdges(self, theShape, doUnionFaces=False, theName=None): """ Remove all seam and degenerated edges from theShape. Unite faces and edges, sharing one surface. It means that @@ -8038,6 +10510,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theShape The compound or single solid to remove irregular edges from. doUnionFaces If True, then unite faces. If False (the default value), do not unite faces. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: Improved shape. @@ -8047,16 +10522,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): if doUnionFaces is True: nbFacesOptimum = 0 # 0 means unite faces anObj = self.BlocksOp.RemoveExtraEdges(theShape, nbFacesOptimum) RaiseIfFailed("RemoveExtraEdges", self.BlocksOp) + self._autoPublish(anObj, theName, "removeExtraEdges") return anObj ## Check, if the given shape is a blocks compound. # Fix all detected errors. # \note Single block can be also fixed by this method. # @param theShape The compound to check and improve. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return Improved compound. # # @ref swig_CheckAndImprove "Example" - def CheckAndImprove(self,theShape): + def CheckAndImprove(self, theShape, theName=None): """ Check, if the given shape is a blocks compound. Fix all detected errors. @@ -8066,6 +10546,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theShape The compound to check and improve. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: Improved compound. @@ -8073,6 +10556,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py anObj = self.BlocksOp.CheckAndImprove(theShape) RaiseIfFailed("CheckAndImprove", self.BlocksOp) + self._autoPublish(anObj, theName, "improved") return anObj # end of l4_blocks_measure @@ -8085,12 +10569,17 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theCompound The compound to explode. # @param theMinNbFaces If solid has lower number of faces, it is not a block. # @param theMaxNbFaces If solid has higher number of faces, it is not a block. - # \note If theMaxNbFaces = 0, the maximum number of faces is not restricted. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @note If theMaxNbFaces = 0, the maximum number of faces is not restricted. + # # @return List of GEOM.GEOM_Object, containing the retrieved blocks. # # @ref tui_explode_on_blocks "Example 1" # \n @ref swig_MakeBlockExplode "Example 2" - def MakeBlockExplode(self,theCompound, theMinNbFaces, theMaxNbFaces): + def MakeBlockExplode(self, theCompound, theMinNbFaces, theMaxNbFaces, theName=None): """ Get all the blocks, contained in the given compound. @@ -8098,6 +10587,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theCompound The compound to explode. theMinNbFaces If solid has lower number of faces, it is not a block. theMaxNbFaces If solid has higher number of faces, it is not a block. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Note: If theMaxNbFaces = 0, the maximum number of faces is not restricted. @@ -8112,16 +10604,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): for anObj in aList: anObj.SetParameters(Parameters) pass + self._autoPublish(aList, theName, "block") return aList ## Find block, containing the given point inside its volume or on boundary. # @param theCompound Compound, to find block in. # @param thePoint Point, close to the desired block. If the point lays on # boundary between some blocks, we return block with nearest center. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the found block. # # @ref swig_todo "Example" - def GetBlockNearPoint(self,theCompound, thePoint): + def GetBlockNearPoint(self, theCompound, thePoint, theName=None): """ Find block, containing the given point inside its volume or on boundary. @@ -8129,6 +10626,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theCompound Compound, to find block in. thePoint Point, close to the desired block. If the point lays on boundary between some blocks, we return block with nearest center. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the found block. @@ -8136,21 +10636,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py anObj = self.BlocksOp.GetBlockNearPoint(theCompound, thePoint) RaiseIfFailed("GetBlockNearPoint", self.BlocksOp) + self._autoPublish(anObj, theName, "block") return anObj ## Find block, containing all the elements, passed as the parts, or maximum quantity of them. # @param theCompound Compound, to find block in. # @param theParts List of faces and/or edges and/or vertices to be parts of the found block. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the found block. # # @ref swig_GetBlockByParts "Example" - def GetBlockByParts(self,theCompound, theParts): + def GetBlockByParts(self, theCompound, theParts, theName=None): """ Find block, containing all the elements, passed as the parts, or maximum quantity of them. Parameters: theCompound Compound, to find block in. theParts List of faces and/or edges and/or vertices to be parts of the found block. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM_Object, containing the found block. @@ -8158,21 +10666,29 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py anObj = self.BlocksOp.GetBlockByParts(theCompound, theParts) RaiseIfFailed("GetBlockByParts", self.BlocksOp) + self._autoPublish(anObj, theName, "block") return anObj ## Return all blocks, containing all the elements, passed as the parts. # @param theCompound Compound, to find blocks in. # @param theParts List of faces and/or edges and/or vertices to be parts of the found blocks. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of GEOM.GEOM_Object, containing the found blocks. # # @ref swig_todo "Example" - def GetBlocksByParts(self,theCompound, theParts): + def GetBlocksByParts(self, theCompound, theParts, theName=None): """ Return all blocks, containing all the elements, passed as the parts. Parameters: theCompound Compound, to find blocks in. theParts List of faces and/or edges and/or vertices to be parts of the found blocks. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of GEOM.GEOM_Object, containing the found blocks. @@ -8180,6 +10696,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_Spanner.py aList = self.BlocksOp.GetBlocksByParts(theCompound, theParts) RaiseIfFailed("GetBlocksByParts", self.BlocksOp) + self._autoPublish(aList, theName, "block") return aList ## Multi-transformate block and glue the result. @@ -8188,11 +10705,16 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param DirFace1 ID of First direction face. # @param DirFace2 ID of Second direction face. # @param NbTimes Quantity of transformations to be done. - # \note Unique ID of sub-shape can be obtained, using method GetSubShapeID(). + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @note Unique ID of sub-shape can be obtained, using method GetSubShapeID(). + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_multi_transformation "Example" - def MakeMultiTransformation1D(self,Block, DirFace1, DirFace2, NbTimes): + def MakeMultiTransformation1D(self, Block, DirFace1, DirFace2, NbTimes, theName=None): """ Multi-transformate block and glue the result. Transformation is defined so, as to superpose direction faces. @@ -8202,6 +10724,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): DirFace1 ID of First direction face. DirFace2 ID of Second direction face. NbTimes Quantity of transformations to be done. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Note: Unique ID of sub-shape can be obtained, using method GetSubShapeID(). @@ -8214,6 +10739,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.BlocksOp.MakeMultiTransformation1D(Block, DirFace1, DirFace2, NbTimes) RaiseIfFailed("MakeMultiTransformation1D", self.BlocksOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "transformed") return anObj ## Multi-transformate block and glue the result. @@ -8221,11 +10747,15 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param DirFace1U,DirFace2U IDs of Direction faces for the first transformation. # @param DirFace1V,DirFace2V IDs of Direction faces for the second transformation. # @param NbTimesU,NbTimesV Quantity of transformations to be done. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM.GEOM_Object, containing the result shape. # # @ref tui_multi_transformation "Example" - def MakeMultiTransformation2D(self,Block, DirFace1U, DirFace2U, NbTimesU, - DirFace1V, DirFace2V, NbTimesV): + def MakeMultiTransformation2D(self, Block, DirFace1U, DirFace2U, NbTimesU, + DirFace1V, DirFace2V, NbTimesV, theName=None): """ Multi-transformate block and glue the result. @@ -8234,6 +10764,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): DirFace1U,DirFace2U IDs of Direction faces for the first transformation. DirFace1V,DirFace2V IDs of Direction faces for the second transformation. NbTimesU,NbTimesV Quantity of transformations to be done. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: New GEOM.GEOM_Object, containing the result shape. @@ -8245,6 +10778,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): DirFace1V, DirFace2V, NbTimesV) RaiseIfFailed("MakeMultiTransformation2D", self.BlocksOp) anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "transformed") return anObj ## Build all possible propagation groups. @@ -8252,10 +10786,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # edge of this group directly or through other opposite edges. # Notion of Opposite Edge make sence only on quadrangle face. # @param theShape Shape to build propagation groups on. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of GEOM.GEOM_Object, each of them is a propagation group. # # @ref swig_Propagate "Example" - def Propagate(self,theShape): + def Propagate(self, theShape, theName=None): """ Build all possible propagation groups. Propagation group is a set of all edges, opposite to one (main) @@ -8264,6 +10802,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theShape Shape to build propagation groups on. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of GEOM.GEOM_Object, each of them is a propagation group. @@ -8271,6 +10812,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py listChains = self.BlocksOp.Propagate(theShape) RaiseIfFailed("Propagate", self.BlocksOp) + self._autoPublish(listChains, theName, "propagate") return listChains # end of l3_blocks_op @@ -8282,11 +10824,15 @@ class geompyDC(GEOM._objref_GEOM_Gen): ## Creates a new group which will store sub-shapes of theMainShape # @param theMainShape is a GEOM object on which the group is selected # @param theShapeType defines a shape type of the group (see GEOM::shape_type) - # @return a newly created GEOM group + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @return a newly created GEOM group (GEOM.GEOM_Object) # # @ref tui_working_with_groups_page "Example 1" # \n @ref swig_CreateGroup "Example 2" - def CreateGroup(self,theMainShape, theShapeType): + def CreateGroup(self, theMainShape, theShapeType, theName=None): """ Creates a new group which will store sub-shapes of theMainShape @@ -8294,6 +10840,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theMainShape is a GEOM object on which the group is selected theShapeType defines a shape type of the group:"COMPOUND", "COMPSOLID", "SOLID", "SHELL", "FACE", "WIRE", "EDGE", "VERTEX", "SHAPE". + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: a newly created GEOM group @@ -8305,6 +10854,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py anObj = self.GroupOp.CreateGroup(theMainShape, theShapeType) RaiseIfFailed("CreateGroup", self.GroupOp) + self._autoPublish(anObj, theName, "group") return anObj ## Adds a sub-object with ID theSubShapeId to the group @@ -8430,9 +10980,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # which are present in groups theGroup1 and theGroup2. # @param theGroup1, theGroup2 are the initial GEOM groups # to create the united group from. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return a newly created GEOM group. + # # @ref tui_union_groups_anchor "Example" - def UnionGroups (self, theGroup1, theGroup2): + def UnionGroups (self, theGroup1, theGroup2, theName=None): """ Union of two groups. New group is created. It will contain all entities @@ -8441,6 +10996,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theGroup1, theGroup2 are the initial GEOM groups to create the united group from. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: a newly created GEOM group. @@ -8448,15 +11006,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py aGroup = self.GroupOp.UnionGroups(theGroup1, theGroup2) RaiseIfFailed("UnionGroups", self.GroupOp) + self._autoPublish(aGroup, theName, "group") return aGroup ## Intersection of two groups. # New group is created. It will contain only those entities # which are present in both groups theGroup1 and theGroup2. # @param theGroup1, theGroup2 are the initial GEOM groups to get common part of. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return a newly created GEOM group. + # # @ref tui_intersect_groups_anchor "Example" - def IntersectGroups (self, theGroup1, theGroup2): + def IntersectGroups (self, theGroup1, theGroup2, theName=None): """ Intersection of two groups. New group is created. It will contain only those entities @@ -8464,6 +11028,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theGroup1, theGroup2 are the initial GEOM groups to get common part of. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: a newly created GEOM group. @@ -8471,6 +11038,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py aGroup = self.GroupOp.IntersectGroups(theGroup1, theGroup2) RaiseIfFailed("IntersectGroups", self.GroupOp) + self._autoPublish(aGroup, theName, "group") return aGroup ## Cut of two groups. @@ -8478,9 +11046,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # present in group theGroup1 but are not present in group theGroup2. # @param theGroup1 is a GEOM group to include elements of. # @param theGroup2 is a GEOM group to exclude elements of. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return a newly created GEOM group. + # # @ref tui_cut_groups_anchor "Example" - def CutGroups (self, theGroup1, theGroup2): + def CutGroups (self, theGroup1, theGroup2, theName=None): """ Cut of two groups. New group is created. It will contain entities which are @@ -8489,6 +11062,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theGroup1 is a GEOM group to include elements of. theGroup2 is a GEOM group to exclude elements of. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: a newly created GEOM group. @@ -8496,15 +11072,21 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py aGroup = self.GroupOp.CutGroups(theGroup1, theGroup2) RaiseIfFailed("CutGroups", self.GroupOp) + self._autoPublish(aGroup, theName, "group") return aGroup ## Union of list of groups. # New group is created. It will contain all entities that are # present in groups listed in theGList. # @param theGList is a list of GEOM groups to create the united group from. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return a newly created GEOM group. + # # @ref tui_union_groups_anchor "Example" - def UnionListOfGroups (self, theGList): + def UnionListOfGroups (self, theGList, theName=None): """ Union of list of groups. New group is created. It will contain all entities that are @@ -8512,6 +11094,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theGList is a list of GEOM groups to create the united group from. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: a newly created GEOM group. @@ -8519,6 +11104,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py aGroup = self.GroupOp.UnionListOfGroups(theGList) RaiseIfFailed("UnionListOfGroups", self.GroupOp) + self._autoPublish(aGroup, theName, "group") return aGroup ## Cut of lists of groups. @@ -8527,9 +11113,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # are not present in groups from theGList2. # @param theGList1 is a list of GEOM groups to include elements of. # @param theGList2 is a list of GEOM groups to exclude elements of. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return a newly created GEOM group. + # # @ref tui_intersect_groups_anchor "Example" - def IntersectListOfGroups (self, theGList): + def IntersectListOfGroups (self, theGList, theName=None): """ Cut of lists of groups. New group is created. It will contain only entities @@ -8539,6 +11130,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theGList1 is a list of GEOM groups to include elements of. theGList2 is a list of GEOM groups to exclude elements of. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: a newly created GEOM group. @@ -8546,6 +11140,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py aGroup = self.GroupOp.IntersectListOfGroups(theGList) RaiseIfFailed("IntersectListOfGroups", self.GroupOp) + self._autoPublish(aGroup, theName, "group") return aGroup ## Cut of lists of groups. @@ -8554,9 +11149,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # are not present in groups from theGList2. # @param theGList1 is a list of GEOM groups to include elements of. # @param theGList2 is a list of GEOM groups to exclude elements of. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return a newly created GEOM group. + # # @ref tui_cut_groups_anchor "Example" - def CutListOfGroups (self, theGList1, theGList2): + def CutListOfGroups (self, theGList1, theGList2, theName=None): """ Cut of lists of groups. New group is created. It will contain only entities @@ -8566,6 +11166,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): Parameters: theGList1 is a list of GEOM groups to include elements of. theGList2 is a list of GEOM groups to exclude elements of. + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: a newly created GEOM group. @@ -8573,6 +11176,7 @@ class geompyDC(GEOM._objref_GEOM_Gen): # Example: see GEOM_TestOthers.py aGroup = self.GroupOp.CutListOfGroups(theGList1, theGList2) RaiseIfFailed("CutListOfGroups", self.GroupOp) + self._autoPublish(aGroup, theName, "group") return aGroup ## Returns a list of sub-objects ID stored in the group @@ -8748,9 +11352,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param max_length maximum length of edges of theShape # @param include_max indicating if edges with length == max_length should be included in result, 1-yes, 0-no (default=1) # @param include_min indicating if edges with length == min_length should be included in result, 1-yes, 0-no (default=1) + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return a newly created GEOM group of edges + # # @@ref swig_todo "Example" - def GetEdgesByLength (self, theShape, min_length, max_length, include_min = 1, include_max = 1): + def GetEdgesByLength (self, theShape, min_length, max_length, include_min = 1, include_max = 1, theName=None): """ Create group of edges of theShape, whose length is in range [min_length, max_length]. If include_min/max == 0, edges with length == min/max_length will not be included in result. @@ -8761,6 +11370,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): max_length maximum length of edges of theShape include_max indicating if edges with length == max_length should be included in result, 1-yes, 0-no (default=1) include_min indicating if edges with length == min_length should be included in result, 1-yes, 0-no (default=1) + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: a newly created GEOM group of edges. @@ -8780,9 +11392,10 @@ class geompyDC(GEOM._objref_GEOM_Gen): if len(edges_in_range) <= 0: print "No edges found by given criteria" - return 0 + return None - group_edges = self.CreateGroup(theShape, ShapeType["EDGE"]) + # note: auto-publishing is done in self.CreateGroup() + group_edges = self.CreateGroup(theShape, ShapeType["EDGE"], theName) self.UnionList(group_edges, edges_in_range) return group_edges @@ -8856,10 +11469,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theP1 1st junction point of main pipe # @param theP2 2nd junction point of main pipe # @param theP3 Junction point of incident pipe + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of GEOM.GEOM_Object, containing the created shape and propagation groups. # # @ref tui_creation_pipetshape "Example" - def MakePipeTShape(self, theR1, theW1, theL1, theR2, theW2, theL2, theHexMesh=True, theP1=None, theP2=None, theP3=None): + def MakePipeTShape(self, theR1, theW1, theL1, theR2, theW2, theL2, theHexMesh=True, theP1=None, theP2=None, theP3=None, theName=None): """ Create a T-shape object with specified caracteristics for the main and the incident pipes (radius, width, half-length). @@ -8879,6 +11496,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theP1 1st junction point of main pipe theP2 2nd junction point of main pipe theP3 Junction point of incident pipe + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of GEOM_Object, containing the created shape and propagation groups. @@ -8896,6 +11516,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.AdvOp.MakePipeTShape(theR1, theW1, theL1, theR2, theW2, theL2, theHexMesh) RaiseIfFailed("MakePipeTShape", self.AdvOp) if Parameters: anObj[0].SetParameters(Parameters) + def_names = [ "pipeTShape" ] + [ "pipeTShape_grp_%d" % i for i in range(1, len(anObj)) ] + self._autoPublish(anObj, _toListOfNames(theName, len(anObj)), def_names) return anObj ## Create a T-shape object with chamfer and with specified caracteristics for the main @@ -8917,10 +11539,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theP1 1st junction point of main pipe # @param theP2 2nd junction point of main pipe # @param theP3 Junction point of incident pipe + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of GEOM.GEOM_Object, containing the created shape and propagation groups. # # @ref tui_creation_pipetshape "Example" - def MakePipeTShapeChamfer(self, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, theHexMesh=True, theP1=None, theP2=None, theP3=None): + def MakePipeTShapeChamfer(self, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, theHexMesh=True, theP1=None, theP2=None, theP3=None, theName=None): """ Create a T-shape object with chamfer and with specified caracteristics for the main and the incident pipes (radius, width, half-length). The chamfer is @@ -8943,6 +11569,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theP1 1st junction point of main pipe theP2 2nd junction point of main pipe theP3 Junction point of incident pipe + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of GEOM_Object, containing the created shape and propagation groups. @@ -8960,6 +11589,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.AdvOp.MakePipeTShapeChamfer(theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, theHexMesh) RaiseIfFailed("MakePipeTShapeChamfer", self.AdvOp) if Parameters: anObj[0].SetParameters(Parameters) + def_names = [ "pipeTShape" ] + [ "pipeTShape_grp_%d" % i for i in range(1, len(anObj)) ] + self._autoPublish(anObj, _toListOfNames(theName, len(anObj)), def_names) return anObj ## Create a T-shape object with fillet and with specified caracteristics for the main @@ -8980,10 +11611,14 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theP1 1st junction point of main pipe # @param theP2 2nd junction point of main pipe # @param theP3 Junction point of incident pipe + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return List of GEOM.GEOM_Object, containing the created shape and propagation groups. # # @ref tui_creation_pipetshape "Example" - def MakePipeTShapeFillet(self, theR1, theW1, theL1, theR2, theW2, theL2, theRF, theHexMesh=True, theP1=None, theP2=None, theP3=None): + def MakePipeTShapeFillet(self, theR1, theW1, theL1, theR2, theW2, theL2, theRF, theHexMesh=True, theP1=None, theP2=None, theP3=None, theName=None): """ Create a T-shape object with fillet and with specified caracteristics for the main and the incident pipes (radius, width, half-length). The fillet is @@ -9005,6 +11640,9 @@ class geompyDC(GEOM._objref_GEOM_Gen): theP1 1st junction point of main pipe theP2 2nd junction point of main pipe theP3 Junction point of incident pipe + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: List of GEOM_Object, containing the created shape and propagation groups. @@ -9023,6 +11661,8 @@ class geompyDC(GEOM._objref_GEOM_Gen): anObj = self.AdvOp.MakePipeTShapeFillet(theR1, theW1, theL1, theR2, theW2, theL2, theRF, theHexMesh) RaiseIfFailed("MakePipeTShapeFillet", self.AdvOp) if Parameters: anObj[0].SetParameters(Parameters) + def_names = [ "pipeTShape" ] + [ "pipeTShape_grp_%d" % i for i in range(1, len(anObj)) ] + self._autoPublish(anObj, _toListOfNames(theName, len(anObj)), def_names) return anObj ## This function allows creating a disk already divided into blocks. It @@ -9031,14 +11671,35 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theOrientation Orientation of the plane on which the disk will be built # 1 = XOY, 2 = OYZ, 3 = OZX # @param thePattern Division pattern. It can be GEOM.SQUARE or GEOM.HEXAGON + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM_Object, containing the created shape. # # @ref tui_creation_divideddisk "Example" - def MakeDividedDisk(self, theR, theOrientation, thePattern ): + def MakeDividedDisk(self, theR, theOrientation, thePattern, theName=None): + """ + Creates a disk, divided into blocks. It can be used to create divided pipes + for later meshing in hexaedra. + + Parameters: + theR Radius of the disk + theOrientation Orientation of the plane on which the disk will be built: + 1 = XOY, 2 = OYZ, 3 = OZX + thePattern Division pattern. It can be GEOM.SQUARE or GEOM.HEXAGON + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + New GEOM_Object, containing the created shape. + """ theR, Parameters = ParseParameters(theR) anObj = self.AdvOp.MakeDividedDisk(theR, 67.0, theOrientation, thePattern) RaiseIfFailed("MakeDividedDisk", self.AdvOp) if Parameters: anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "dividedDisk") return anObj ## This function allows creating a disk already divided into blocks. It @@ -9047,28 +11708,68 @@ class geompyDC(GEOM._objref_GEOM_Gen): # @param theVector Normal vector to the plane of the created disk # @param theRadius Radius of the disk # @param thePattern Division pattern. It can be GEOM.SQUARE or GEOM.HEXAGON + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM_Object, containing the created shape. # # @ref tui_creation_divideddisk "Example" - def MakeDividedDiskPntVecR(self, theCenter, theVector, theRadius, thePattern): + def MakeDividedDiskPntVecR(self, theCenter, theVector, theRadius, thePattern, theName=None): + """ + Creates a disk already divided into blocks. It can be used to create divided pipes + for later meshing in hexaedra. + + Parameters: + theCenter Center of the disk + theVector Normal vector to the plane of the created disk + theRadius Radius of the disk + thePattern Division pattern. It can be GEOM.SQUARE or GEOM.HEXAGON + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + New GEOM_Object, containing the created shape. + """ theRadius, Parameters = ParseParameters(theRadius) anObj = self.AdvOp.MakeDividedDiskPntVecR(theCenter, theVector, theRadius, 67.0, thePattern) RaiseIfFailed("MakeDividedDiskPntVecR", self.AdvOp) if Parameters: anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "dividedDisk") return anObj ## Builds a cylinder prepared for hexa meshes # @param theR Radius of the cylinder # @param theH Height of the cylinder # @param thePattern Division pattern. It can be GEOM.SQUARE or GEOM.HEXAGON + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM_Object, containing the created shape. # # @ref tui_creation_dividedcylinder "Example" - def MakeDividedCylinder(self, theR, theH, thePattern): + def MakeDividedCylinder(self, theR, theH, thePattern, theName=None): + """ + Builds a cylinder prepared for hexa meshes + + Parameters: + theR Radius of the cylinder + theH Height of the cylinder + thePattern Division pattern. It can be GEOM.SQUARE or GEOM.HEXAGON + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + + Returns: + New GEOM_Object, containing the created shape. + """ theR, theH, Parameters = ParseParameters(theR, theH) anObj = self.AdvOp.MakeDividedCylinder(theR, theH, thePattern) RaiseIfFailed("MakeDividedCylinder", self.AdvOp) if Parameters: anObj.SetParameters(Parameters) + self._autoPublish(anObj, theName, "dividedCylinder") return anObj #@@ insert new functions before this line @@ do not remove this line @@# @@ -9079,24 +11780,33 @@ class geompyDC(GEOM._objref_GEOM_Gen): ## Create a copy of the given object # # @param theOriginal geometry object for copy - # @return unique object identifier + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # + # @return New GEOM_Object, containing the copied shape. + # # @ingroup l1_geompy_auxiliary # @ref swig_MakeCopy "Example" - def MakeCopy(self,theOriginal): + def MakeCopy(self, theOriginal, theName=None): """ Create a copy of the given object Paremeters: theOriginal geometry object for copy + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. Returns: - unique object identifier + New GEOM_Object, containing the copied shape. Example of usage: Copy = geompy.MakeCopy(Box) """ # Example: see GEOM_TestAll.py anObj = self.InsertOp.MakeCopy(theOriginal) RaiseIfFailed("MakeCopy", self.InsertOp) + self._autoPublish(anObj, theName, "copy") return anObj ## Add Path to load python scripts from diff --git a/src/GEOM_SWIG/gsketcher.py b/src/GEOM_SWIG/gsketcher.py index 11ef9bb6d..a3810ae06 100644 --- a/src/GEOM_SWIG/gsketcher.py +++ b/src/GEOM_SWIG/gsketcher.py @@ -253,11 +253,20 @@ class Sketcher3D: pass ## Obtain the sketcher result. + # @param theName Object name; when specified, this parameter is used + # for result publication in the study. Otherwise, if automatic + # publication is switched on, default value is used for result name. + # # @return New GEOM_Object, containing the created wire - def wire (self): + def wire (self, theName=None): """ Obtain the sketcher result. + Parameters: + theName Object name; when specified, this parameter is used + for result publication in the study. Otherwise, if automatic + publication is switched on, default value is used for result name. + Returns: New GEOM_Object, containing the created wire. @@ -272,4 +281,5 @@ class Sketcher3D: self.myCommand = "3DSketcher" RaiseIfFailed("Sketcher3D", self.geompyD.CurvesOp) wire.SetParameters(Parameters) + self.geompyD._autoPublish(wire, theName, "wire") return wire diff --git a/src/GEOM_SWIG_WITHIHM/Makefile.am b/src/GEOM_SWIG_WITHIHM/Makefile.am index 59166af81..710d23be6 100644 --- a/src/GEOM_SWIG_WITHIHM/Makefile.am +++ b/src/GEOM_SWIG_WITHIHM/Makefile.am @@ -66,12 +66,14 @@ _libGEOM_Swig_la_CPPFLAGS = \ -I$(srcdir)/../OBJECT \ -I$(srcdir)/../GEOMGUI \ -I$(srcdir)/../GEOMToolsGUI \ + -I$(srcdir)/../Material \ -I$(top_builddir)/idl _libGEOM_Swig_la_LDFLAGS = -module _libGEOM_Swig_la_LIBADD = \ ../GEOMGUI/libGEOM.la \ ../GEOMToolsGUI/libGEOMToolsGUI.la \ + ../Material/libMaterial.la \ $(PYTHON_LIBS) swig_wrap.cpp : $(SWIG_SOURCES) diff --git a/src/GEOM_SWIG_WITHIHM/libGEOM_Swig.cxx b/src/GEOM_SWIG_WITHIHM/libGEOM_Swig.cxx index 616fd5097..80623324f 100644 --- a/src/GEOM_SWIG_WITHIHM/libGEOM_Swig.cxx +++ b/src/GEOM_SWIG_WITHIHM/libGEOM_Swig.cxx @@ -19,705 +19,474 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - -// GEOM GEOMGUI : GUI for Geometry component // File : libGEOM_Swig.cxx // Author : Nicolas REJNERI, Paul RASCLE -// + #include "libGEOM_Swig.h" #include "GeometryGUI.h" -#include "GEOMToolsGUI.h" - -#include "SUIT_Desktop.h" -#include "SUIT_Session.h" -#include "SalomeApp_Application.h" -#include "SalomeApp_Study.h" - -#include "OB_Browser.h" - -#include "OCCViewer_ViewWindow.h" -#include "OCCViewer_ViewManager.h" -#include "SOCC_ViewModel.h" -#include - -#include "SVTK_ViewModel.h" -#include "SVTK_ViewWindow.h" -#include "SVTK_View.h" -#include "SVTK_Renderer.h" -#include - -#include "GEOM_Actor.h" -#include "GEOM_Client.hxx" -#include "GEOM_AISShape.hxx" -#include "GEOM_InteractiveObject.hxx" #include "GEOM_Displayer.h" #include "GEOM_Constants.h" +#include "Material_Model.h" -#include "SALOME_Event.h" +#include +#include +#include +#include +#include +#include +#include +#include -// OCCT Includes -#include -#include -#include -#include -#include -#include -#include +#include // IDL Headers #include #include CORBA_SERVER_HEADER(GEOM_Gen) -#include - -static SHAPE_READER(ShapeReader); - -inline OCCViewer_Viewer* GetOCCViewer(SUIT_Application* theApp){ - SUIT_ViewWindow* window = theApp->desktop()->activeWindow(); - if(window && window->getViewManager()->getType() == OCCViewer_Viewer::Type()){ - OCCViewer_ViewWindow* vw = dynamic_cast( window ); - if ( vw ) { - OCCViewer_ViewManager* vm = dynamic_cast( vw->getViewManager() ); - if ( vm ) - return vm->getOCCViewer(); - } - } - - return 0; -} - -inline SVTK_ViewWindow* GetSVTKViewWindow(SUIT_Application* theApp){ - SUIT_ViewWindow* window = theApp->desktop()->activeWindow(); - if(window && window->getViewManager()->getType() == SVTK_Viewer::Type()) - return dynamic_cast( window ); - - return 0; -} - +/*! + \brief Constructor +*/ GEOM_Swig::GEOM_Swig() { - // MESSAGE("Constructeur"); + init(); } +/*! + \brief Destructor +*/ GEOM_Swig::~GEOM_Swig() { - // MESSAGE("Destructeur"); } -void GEOM_Swig::createAndDisplayGO (const char* Entry, bool isUpdated) +/*! + \brief Internal initialization +*/ +void GEOM_Swig::init() { class TEvent: public SALOME_Event { - std::string myEntry; - bool myUpdateViewer; public: - TEvent(const char* theEntry, bool toUpdateViewer): - myEntry(theEntry), - myUpdateViewer(toUpdateViewer) + TEvent() {} virtual void Execute() { + // check active study SUIT_Application* app = SUIT_Session::session()->activeApplication(); if (!app) return; + + SalomeApp_Study* study = dynamic_cast( app->activeStudy() ); + if ( !study ) return; - SalomeApp_Study* ActiveStudy = dynamic_cast(app->activeStudy()); - if (!ActiveStudy) return; - - _PTR(Study) aStudy(ActiveStudy->studyDS()); - _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder(); + _PTR(Study) studyDS( study->studyDS() ); + _PTR(StudyBuilder) builder = studyDS->NewBuilder(); - GEOM::GEOM_Gen_var Geom = GeometryGUI::GetGeomGen(); - if (CORBA::is_nil(Geom)) { - GeometryGUI::InitGeomGen(); - Geom = GeometryGUI::GetGeomGen(); - } - if (CORBA::is_nil(Geom)) + // get/init GEOM engine + GEOM::GEOM_Gen_var engine = GeometryGUI::GetGeomGen(); + if ( CORBA::is_nil( engine ) ) return; - std::string aFatherIOR; - _PTR(SComponent) father = aStudy->FindComponent("GEOM"); - if (!father) - return; - if (!father->ComponentIOR(aFatherIOR)) { - CORBA::String_var objStr = SalomeApp_Application::orb()->object_to_string(Geom); - aStudyBuilder->LoadWith(father, objStr.in()); - father->ComponentIOR(aFatherIOR); - } - - _PTR(SObject) obj = aStudy->FindObjectID(myEntry); - if (!obj) + // find GEOM component in the study + _PTR(SComponent) component = studyDS->FindComponent( "GEOM" ); + if ( !component ) return; - // Create new actor - _PTR(GenericAttribute) anAttr; - if (!obj->FindAttribute(anAttr, "AttributeIOR")) - return; - _PTR(AttributeIOR) anIOR(anAttr); - std::string anIORValue = anIOR->Value(); - - GEOM::GEOM_Object_var aShape = Geom->GetIORFromString(anIORValue.c_str()); - TopoDS_Shape Shape = ShapeReader.GetShape(Geom,aShape); - if (!Shape.IsNull()) { - if (obj->FindAttribute(anAttr, "AttributeName")) { - _PTR(AttributeName) aName (anAttr); - std::string aNameValue = aName->Value(); - // open transaction - /*SUIT_Operation* op = new SalomeApp_ImportOperation (app); - op->start(); - - _PTR(SObject) newObj1 = aStudyBuilder->NewObject(father); - aStudyBuilder->Addreference(newObj1, obj); - // commit transaction - op->commit();*/ - Handle(GEOM_InteractiveObject) anIO = - new GEOM_InteractiveObject (const_cast(anIORValue.c_str()), - const_cast(aFatherIOR.c_str()), - "GEOM", - const_cast( obj->GetID().c_str())); - - GEOM_Displayer(ActiveStudy).Display(anIO, myUpdateViewer); - /*if (SVTK_ViewWindow* aViewWindow = GetSVTKViewWindow(app)) { - SVTK_View* aView = aViewWindow->getView(); - int aMode = aView->GetDisplayMode(); - - vtkActorCollection* theActors = - GEOM_AssemblyBuilder::BuildActors(Shape,0,aMode,true); - theActors->InitTraversal(); - while (vtkActor* anActor = theActors->GetNextActor()) { - GEOM_Actor* GActor = GEOM_Actor::SafeDownCast(anActor); - GActor->setName(const_cast(aNameValue.c_str())); - GActor->setIO(anIO); - aView->Display(GActor); - } - aView->Repaint(); - } else if (OCCViewer_Viewer* occViewer = GetOCCViewer(app)) { - Handle(AIS_InteractiveContext) ic = occViewer->getAISContext(); - Handle(GEOM_AISShape) aSh = - new GEOM_AISShape (Shape,const_cast(aNameValue.c_str())); - aSh->setName(const_cast(aNameValue.c_str())); - aSh->setIO(anIO); - ic->Display(aSh); - ic->AddOrRemoveCurrentObject(aSh,true); - }*/ - // update object browser - SalomeApp_Application* app = NULL; //dynamic_cast(app); - if (app) { - CAM_Module* module = app->module("Geometry"); - SalomeApp_Module* appMod = dynamic_cast(module); - if (appMod) - appMod->updateObjBrowser(true); - } - } + // load GEOM data (if it is not done yet) + std::string ior; + if ( !component->ComponentIOR( ior ) ) { + CORBA::String_var engineIOR = SalomeApp_Application::orb()->object_to_string( engine ); + builder->LoadWith( component, engineIOR.in() ); } + + // update Object browser + if ( dynamic_cast( app ) ) + dynamic_cast( app )->updateObjectBrowser( true ); } }; - // MESSAGE("createAndDisplayGO"); - ProcessVoidEvent(new TEvent (Entry, isUpdated)); + ProcessVoidEvent( new TEvent() ); +} - class TEventUpdateBrowser: public SALOME_Event +/*! + \brief Display the presenation in the currently active view + \param theEntry geometry object's entry + \param theUpdateViewer \c true to update active view's contents +*/ +void GEOM_Swig::createAndDisplayGO( const char* theEntry, bool theUpdateViewer ) +{ + class TEvent: public SALOME_Event + { + std::string myEntry; + bool myUpdateViewer; + public: + TEvent( const char* _entry, bool _update ): + myEntry( _entry ), myUpdateViewer( _update ) + {} + virtual void Execute() { - public: - TEventUpdateBrowser() {} - virtual void Execute() { - SalomeApp_Application* app = - dynamic_cast(SUIT_Session::session()->activeApplication()); - if (app) { - CAM_Module* module = app->module("Geometry"); - SalomeApp_Module* appMod = dynamic_cast(module); - if (appMod) appMod->updateObjBrowser(true); - } - } - }; - - if (isUpdated) - ProcessVoidEvent(new TEventUpdateBrowser ()); + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( !app ) return; + SalomeApp_Study* study = dynamic_cast( app->activeStudy() ); + if ( !study ) return; + + Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( myEntry.c_str(), "GEOM", "" ); + + GEOM_Displayer( study ).Display( io, myUpdateViewer ); + } + }; + + ProcessVoidEvent( new TEvent( theEntry, theUpdateViewer ) ); } -void GEOM_Swig::createAndDisplayFitAllGO (const char* Entry) +/*! + \brief Same as createAndDisplayGO, but also fits the active view to the contents + \param theEntry geometry object's entry + \param theUpdateViewer \c true to update active view's contents +*/ +void GEOM_Swig::createAndDisplayFitAllGO( const char* theEntry ) { + // display object + createAndDisplayGO( theEntry ); + + // fit all the view class TEventFitAll: public SALOME_Event { - public: - TEventFitAll() {} - virtual void Execute() { - SUIT_Application* app = SUIT_Session::session()->activeApplication(); - if (!app) return; - - if (SVTK_ViewWindow* aViewWindow = GetSVTKViewWindow(app)) - { - SVTK_View* aView = aViewWindow->getView(); - aView->GetRenderer()->OnFitAll(); - } - else if (OCCViewer_Viewer* occViewer = GetOCCViewer(app)) - { - Handle(V3d_Viewer) aViewer3d = occViewer->getViewer3d(); - aViewer3d->InitActiveViews(); - - if (aViewer3d->MoreActiveViews()) - aViewer3d->ActiveView()->FitAll(); - } + public: + TEventFitAll() {} + virtual void Execute() + { + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( app ) { + SUIT_ViewWindow* window = app->desktop()->activeWindow(); + if ( dynamic_cast( window ) ) + dynamic_cast( window )->onFitAll(); + else if ( dynamic_cast( window ) ) + dynamic_cast( window )->onViewFitAll(); } + } + }; + + ProcessVoidEvent( new TEventFitAll() ); +} + +/*! + \brief Erase presentation in the currently active viewer + \param theEntry geometry object's entry + \param theUpdateViewer \c true to update active view's contents +*/ +void GEOM_Swig::eraseGO( const char* theEntry, bool theUpdateViewer ) +{ + class TEvent: public SALOME_Event + { + std::string myEntry; + bool myUpdateViewer; + public: + TEvent( const char* _entry, bool _update ): + myEntry( _entry ), myUpdateViewer( _update ) + {} + virtual void Execute() + { + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( !app ) return; + SalomeApp_Study* study = dynamic_cast( app->activeStudy() ); + if ( !study ) return; + + Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( myEntry.c_str(), "GEOM", "" ); + + GEOM_Displayer( study ).Erase( io, true, myUpdateViewer ); + } }; - createAndDisplayGO(Entry); - ProcessVoidEvent(new TEventFitAll()); + ProcessVoidEvent( new TEvent( theEntry, theUpdateViewer ) ); } +/*! + \brief Update active viewer contents +*/ void GEOM_Swig::UpdateViewer() { class TEventUpdateViewer: public SALOME_Event { - public: - TEventUpdateViewer() {} - virtual void Execute() { - SUIT_Application* app = SUIT_Session::session()->activeApplication(); - if (!app) return; - SalomeApp_Study* ActiveStudy = dynamic_cast(app->activeStudy()); - if (!ActiveStudy) return; - - GEOM_Displayer(ActiveStudy).UpdateViewer(); - } + public: + TEventUpdateViewer() + {} + virtual void Execute() + { + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( !app ) return; + + SalomeApp_Study* study = dynamic_cast( app->activeStudy() ); + if ( !study ) return; + + GEOM_Displayer( study ).UpdateViewer(); + } }; ProcessVoidEvent(new TEventUpdateViewer()); } -int GEOM_Swig::getIndexTopology(const char* SubIOR, const char* IOR) +/*! + \brief Get sub-shape index inside main shape + \param theSubIOR sub-shape geometry object's IOR + \param theMainIOR main shape geometry object's IOR + \return sub-shape index (-1 in case of error) +*/ +int GEOM_Swig::getIndexTopology( const char* theSubIOR, const char* theMainIOR ) { - GEOM::GEOM_Gen_var aGeomGen = GeometryGUI::GetGeomGen(); - if (CORBA::is_nil(aGeomGen)) - return -1; + int index = -1; - GEOM::GEOM_Object_var aMainShape = aGeomGen->GetIORFromString(IOR); - GEOM::GEOM_Object_var aSubShape = aGeomGen->GetIORFromString(SubIOR); - if (CORBA::is_nil(aMainShape) || CORBA::is_nil(aSubShape)) - return -1; + // get geom engine + GEOM::GEOM_Gen_var aGeomGen = GeometryGUI::GetGeomGen(); - GEOM::GEOM_IShapesOperations_var anIShapesOperations = - aGeomGen->GetIShapesOperations(aMainShape->GetStudyID()); - if (CORBA::is_nil(anIShapesOperations)) - return -1; + // get main shape's geom object by IOR + CORBA::Object_var anObject = SalomeApp_Application::orb()->string_to_object( theMainIOR ); + GEOM::GEOM_Object_var aMainShape = GEOM::GEOM_Object::_narrow( anObject.in() ); + // get sub-shape's geom object by IOR + anObject = SalomeApp_Application::orb()->string_to_object( theSubIOR ); + GEOM::GEOM_Object_var aSubShape = GEOM::GEOM_Object::_narrow( anObject.in() ); + + if ( !CORBA::is_nil( aGeomGen ) && !CORBA::is_nil( aMainShape ) && !CORBA::is_nil( aSubShape ) ) { + // get shapes operations interface + GEOM::GEOM_IShapesOperations_var anIShapesOperations = + aGeomGen->GetIShapesOperations( aMainShape->GetStudyID() ); + if ( !CORBA::is_nil( anIShapesOperations ) ) + index = anIShapesOperations->GetTopologyIndex( aMainShape, aSubShape ); + } - return anIShapesOperations->GetTopologyIndex(aMainShape, aSubShape); + return index; } -const char* GEOM_Swig::getShapeTypeString(const char* IOR) +/*! + \brief Get shape type name + \param theIOR geometry object's IOR + \return shape type name ("Shape of unknown type" in case of error) +*/ +const char* GEOM_Swig::getShapeTypeString( const char* theIOR ) { - TCollection_AsciiString aTypeName ("Shape of unknown type"); + QString aTypeName = "Shape of unknown type"; + // get geom engine GEOM::GEOM_Gen_var aGeomGen = GeometryGUI::GetGeomGen(); - if (!CORBA::is_nil(aGeomGen)) - { - GEOM::GEOM_Object_var aShape = aGeomGen->GetIORFromString(IOR); - if (!CORBA::is_nil(aShape)) - { - GEOM::GEOM_IShapesOperations_var anIShapesOperations = - aGeomGen->GetIShapesOperations(aShape->GetStudyID()); - if (!CORBA::is_nil(anIShapesOperations)) - { - aTypeName = anIShapesOperations->GetShapeTypeString(aShape); - } - } + + // get shape's geom object by IOR + CORBA::Object_var anObject = SalomeApp_Application::orb()->string_to_object( theIOR ); + GEOM::GEOM_Object_var aShape = GEOM::GEOM_Object::_narrow( anObject.in() ); + + if ( !CORBA::is_nil( aGeomGen ) && !CORBA::is_nil( aShape ) ) { + // get shapes operations interface + GEOM::GEOM_IShapesOperations_var anIShapesOperations = + aGeomGen->GetIShapesOperations( aShape->GetStudyID() ); + if ( !CORBA::is_nil( anIShapesOperations ) ) + aTypeName = anIShapesOperations->GetShapeTypeString( aShape ); } - return CORBA::string_dup(aTypeName.ToCString()); + return strdup( qPrintable( aTypeName ) ); } - -const char* GEOM_Swig::getShapeTypeIcon(const char* IOR) +/*! + \brief Get shape's icon ID (specified by its type) + \param theIOR geometry object's IOR + \return icon ID ("None" in case of error) +*/ +const char* GEOM_Swig::getShapeTypeIcon( const char* theIOR ) { - GEOM::GEOM_Gen_var Geom = GeometryGUI::GetGeomGen(); - if ( CORBA::is_nil( Geom ) ) - return "None"; + static const char* icons[] = { + "ICON_OBJBROWSER_COMPOUND", + "ICON_OBJBROWSER_COMPSOLID", + "ICON_OBJBROWSER_SOLID", + "ICON_OBJBROWSER_SHELL", + "ICON_OBJBROWSER_FACE", + "ICON_OBJBROWSER_WIRE", + "ICON_OBJBROWSER_EDGE", + "ICON_OBJBROWSER_VERTEX" + }; - GEOM::GEOM_Object_var aShape = Geom->GetIORFromString(IOR); - TopoDS_Shape shape = ShapeReader.GetShape(Geom, aShape); + const char* anIcon = "None"; - if( shape.IsNull() ) { - return "None" ; + try { + CORBA::Object_var anObject = SalomeApp_Application::orb()->string_to_object( theIOR ); + if ( !CORBA::is_nil( anObject ) ) { + GEOM::GEOM_Object_var aShape = GEOM::GEOM_Object::_narrow( anObject.in() ); + if ( !CORBA::is_nil( aShape ) ) { + GEOM::shape_type aType = aShape->GetShapeType(); + if ( aType >= GEOM::COMPOUND && aType < GEOM::SHAPE ) + anIcon = icons[ (int)aType ]; + } + } + } + catch ( CORBA::Exception& ) { } - switch (shape.ShapeType() ) - { - case TopAbs_COMPOUND: - { return "ICON_OBJBROWSER_COMPOUND" ;} - case TopAbs_COMPSOLID: - { return "ICON_OBJBROWSER_COMPSOLID" ;} - case TopAbs_SOLID: - { return "ICON_OBJBROWSER_SOLID" ;} - case TopAbs_SHELL: - { return "ICON_OBJBROWSER_SHELL" ;} - case TopAbs_FACE: - { return "ICON_OBJBROWSER_FACE" ;} - case TopAbs_WIRE: - { return "ICON_OBJBROWSER_WIRE" ;} - case TopAbs_EDGE: - { return "ICON_OBJBROWSER_EDGE" ;} - case TopAbs_VERTEX: - { return "ICON_OBJBROWSER_VERTEX" ;} - } + return anIcon; +} - return "None"; +class TSetPropertyEvent: public SALOME_Event +{ + QString myEntry; + QString myProperty; + QVariant myValue; + bool myUpdateViewer; + +public: + TSetPropertyEvent( const QString& _entry, + const QString& _property, + const QVariant& _value, + bool _update = true ); + virtual void Execute(); +}; + +TSetPropertyEvent::TSetPropertyEvent( const QString& _entry, + const QString& _property, + const QVariant& _value, + bool _update ): + myEntry( _entry ), + myProperty( _property ), + myValue( _value ), + myUpdateViewer( _update ) +{ } -void GEOM_Swig::setDisplayMode(const char* theEntry, int theMode, bool isUpdated) +void TSetPropertyEvent::Execute() { - class TEvent: public SALOME_Event { - std::string myEntry; - int myMode; - bool myUpdateViewer; - public: - TEvent(const char* theEntryArg, int theModeArg, bool theUpdated): - myEntry(theEntryArg), myMode(theModeArg), myUpdateViewer(theUpdated) - {} - virtual void Execute() { - SUIT_Application* anApp = SUIT_Session::session()->activeApplication(); - if (!anApp) return; - - Handle(SALOME_InteractiveObject) anIO = - new SALOME_InteractiveObject(myEntry.c_str(), "GEOM", ""); - - if (SVTK_ViewWindow* aViewWindow = GetSVTKViewWindow(anApp)) { - SVTK_View* aView = aViewWindow->getView(); - aView->SetDisplayMode(anIO, myMode); - if (myUpdateViewer) - aView->Repaint(); - } - else if (OCCViewer_Viewer* occViewer = GetOCCViewer(anApp)) { - SOCC_Viewer* soccViewer = dynamic_cast(occViewer); - if (soccViewer) - soccViewer->switchRepresentation(anIO, myMode, myUpdateViewer); - } - } - }; + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( !app ) return; + + SalomeApp_Study* study = dynamic_cast( app->activeStudy() ); + if ( !study ) return; + + GEOM_Displayer displayer( study ); + + SALOME_View* window = displayer.GetActiveView(); + if ( !window ) return; + + int mgrId = dynamic_cast( window )->getViewManager()->getGlobalId(); - ProcessVoidEvent(new TEvent (theEntry, theMode, isUpdated)); + study->setObjectProperty( mgrId, myEntry, myProperty, myValue ); + + Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( myEntry.toLatin1().data(), "GEOM" ); + if ( window->isVisible( io ) ) displayer.Redisplay( io, myUpdateViewer ); } -void GEOM_Swig::setVectorsMode(const char* theEntry, bool isOn, bool isUpdated) +/*! + \brief Set display mode to the presentation + \param theEntry geometry object's entry + \param theMode display mode: 0 - wireframe, 1 - shading, 2 - shading+edges, 3-textured + \param theUpdateViewer \c true to update active view's contents +*/ +void GEOM_Swig::setDisplayMode( const char* theEntry, int theMode, bool theUpdateViewer ) { - class TEvent: public SALOME_Event { - std::string myEntry; - bool myOn; - bool myUpdateViewer; - public: - TEvent(const char* theEntryArg, bool theOn, bool theUpdated): - myEntry(theEntryArg), myOn(theOn), myUpdateViewer(theUpdated) - {} - virtual void Execute() { - SUIT_Application* anApp = SUIT_Session::session()->activeApplication(); - if (!anApp) return; - - Handle(SALOME_InteractiveObject) anIO = - new SALOME_InteractiveObject(myEntry.c_str(), "GEOM", ""); - - if (SVTK_ViewWindow* aViewWindow = GetSVTKViewWindow(anApp)) { - SVTK_View* aView = aViewWindow->getView(); - SVTK_Viewer* stvkViewer = dynamic_cast(aViewWindow->getViewManager()->getViewModel()); - SVTK_Prs* vtkPrs = dynamic_cast( stvkViewer->CreatePrs( myEntry.c_str() ) ); - vtkActorCollection* anActors = vtkPrs->GetObjects(); - anActors->InitTraversal(); - while (vtkActor* anAct = anActors->GetNextActor()) { - GEOM_Actor* aGeomActor = GEOM_Actor::SafeDownCast(anAct); - aGeomActor->SetVectorMode(!aGeomActor->GetVectorMode()); - } - if (myUpdateViewer) - aView->Repaint(); - } - else if (OCCViewer_Viewer* occViewer = GetOCCViewer(anApp)) { - Handle(AIS_InteractiveContext) ic = occViewer->getAISContext(); - SOCC_Viewer* soccViewer = dynamic_cast(occViewer); - if (soccViewer) { - SOCC_Prs* occPrs = dynamic_cast( soccViewer->CreatePrs( myEntry.c_str() ) ); - if ( occPrs && !occPrs->IsNull() ) { - AIS_ListOfInteractive shapes; occPrs->GetObjects( shapes ); - AIS_ListIteratorOfListOfInteractive interIter( shapes ); - for ( ; interIter.More(); interIter.Next() ) { - Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast( interIter.Value() ); - aSh->SetDisplayVectors(myOn); - ic->RecomputePrsOnly(interIter.Value()); - } - } - } - } - } - }; + ProcessVoidEvent( new TSetPropertyEvent( theEntry, GEOM::propertyName( GEOM::DisplayMode ), + theMode, theUpdateViewer ) ); +} - ProcessVoidEvent(new TEvent (theEntry, isOn, isUpdated)); +/*! + \brief Show / hide edges direction vectors for the presentation + \param theEntry geometry object's entry + \param theOn \c true to show edges direction vectors or \c false otherwise + \param theUpdateViewer \c true to update active view's contents +*/ +void GEOM_Swig::setVectorsMode( const char* theEntry, bool theOn, bool theUpdateViewer ) +{ + ProcessVoidEvent( new TSetPropertyEvent( theEntry, GEOM::propertyName( GEOM::EdgesDirection ), + theOn, theUpdateViewer ) ); } -void GEOM_Swig::setColor(const char* theEntry, int red, int green, int blue, bool isUpdated) +/*! + \brief Change color of the presentation + \param theEntry geometry object's entry + \param theRed red component of the component (0-255) + \param theGreen green component of the component (0-255) + \param theBlue blue component of the component (0-255) + \param theUpdateViewer \c true to update active view's contents +*/ +void GEOM_Swig::setColor( const char* theEntry, int theRed, int theGreen, int theBlue, bool theUpdateViewer ) { - class TEvent: public SALOME_Event { - QString myEntry; - int myRed; - int myGreen; - int myBlue; - bool myUpdateViewer; - public: - TEvent(const char* theEntryArg, int theR, int theG, int theB, bool theUpdated): - myEntry(theEntryArg), myRed(theR), myGreen(theG), myBlue(theB), myUpdateViewer(theUpdated) - {} - virtual void Execute() { - SUIT_Application* anApp = SUIT_Session::session()->activeApplication(); - if (!anApp) return; - GEOMToolsGUI::SetColor( myEntry, QColor( myRed, myGreen, myBlue), myUpdateViewer ); - } - }; - ProcessVoidEvent(new TEvent(theEntry, red, green, blue, isUpdated)); + ProcessVoidEvent( new TSetPropertyEvent( theEntry, GEOM::propertyName( GEOM::Color ), + QColor( theRed, theGreen, theBlue ), theUpdateViewer ) ); } -void GEOM_Swig::setIsos(const char* Entry, int nbU, int nbV, bool isUpdated ) +/*! + \brief Set number of iso-lines to the presentation + \param theEntry geometry object's entry + \param theNbU number of iso-lines along U axis (interger value >= 0) + \param theNbV number of iso-lines along V axis (interger value >= 0) + \param theUpdateViewer \c true to update active view's contents +*/ +void GEOM_Swig::setIsos( const char* theEntry, int theNbU, int theNbV, bool theUpdateViewer ) { - class TEvent: public SALOME_Event { - std::string myEntry; - int myNbU, myNbV; - bool myUpdateViewer; - public: - TEvent(const char* theEntry, int theNbU, int theNbV, bool theUpdated): - myEntry(theEntry), myNbU(theNbU), myNbV(theNbV), myUpdateViewer(theUpdated) - {} - virtual void Execute() { - SUIT_Application* app = SUIT_Session::session()->activeApplication(); - if (!app) return; - SalomeApp_Study* study = dynamic_cast(app->activeStudy()); - if (!study) return; - - Handle(SALOME_InteractiveObject) anIO = - new SALOME_InteractiveObject(myEntry.c_str(), "GEOM", ""); - - if (SVTK_ViewWindow* aViewWindow = GetSVTKViewWindow(app)) { - SVTK_Viewer* aView = dynamic_cast(aViewWindow->getViewManager()->getViewModel()); - SVTK_Prs* vtkPrs = dynamic_cast( aView->CreatePrs( myEntry.c_str() ) ); - if ( vtkPrs ) { - vtkActorCollection* anActors = vtkPrs->GetObjects(); - anActors->InitTraversal(); - GEOM_Actor* anActor = GEOM_Actor::SafeDownCast( anActors->GetNextActor() ); - if ( anActor ) { - int aIsos[2]={myNbU,myNbV}; - anActor->SetNbIsos(aIsos); - anActor->StoreIsoNumbers(); - QString anIsos = QString("%1%2%3").arg(myNbU).arg(DIGIT_SEPARATOR).arg(myNbV); - int aMgrId = aView->getViewManager()->getGlobalId(); - study->setObjectProperty(aMgrId, myEntry.c_str(), ISOS_PROP, anIsos); - } - } - - if (myUpdateViewer) - aView->Repaint(); - } - else if (OCCViewer_Viewer* occViewer = GetOCCViewer(app)) { - Handle(AIS_InteractiveContext) ic = occViewer->getAISContext(); - SOCC_Viewer* soccViewer = dynamic_cast(occViewer); - if (soccViewer) { - int aMgrId = soccViewer->getViewManager()->getGlobalId(); - SOCC_Prs* occPrs = dynamic_cast( soccViewer->CreatePrs( myEntry.c_str() ) ); - if ( occPrs && !occPrs->IsNull() ) { - AIS_ListOfInteractive shapes; occPrs->GetObjects( shapes ); - AIS_ListIteratorOfListOfInteractive interIter( shapes ); - for ( ; interIter.More(); interIter.Next() ) { - Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast( interIter.Value() ); - if ( !aSh.IsNull() ) { - Handle(AIS_Drawer) drawer = aSh->Attributes(); - QVariant v = study->getObjectProperty( aMgrId, myEntry.c_str(), EDGE_WIDTH_PROP, QVariant() ); - int width = v.isValid() ? v.toInt() : 1; - drawer->SetUIsoAspect( new Prs3d_IsoAspect(Quantity_NOC_GRAY75, Aspect_TOL_SOLID, width, myNbU) ); - drawer->SetVIsoAspect( new Prs3d_IsoAspect(Quantity_NOC_GRAY75, Aspect_TOL_SOLID, width, myNbV) ); - aSh->storeIsoNumbers(); - ic->SetLocalAttributes(aSh, drawer); - ic->Redisplay(aSh); - QString anIsos = QString("%1%2%3").arg(myNbU).arg(DIGIT_SEPARATOR).arg(myNbV); - study->setObjectProperty(aMgrId, myEntry.c_str(), ISOS_PROP, anIsos); - } - } - } - } - } - } - }; + ProcessVoidEvent( new TSetPropertyEvent( theEntry, GEOM::propertyName( GEOM::NbIsos ), + QString( "%1%2%3" ).arg( theNbU ).arg( GEOM::subSectionSeparator() ).arg( theNbV ), + theUpdateViewer ) ); +} - ProcessVoidEvent(new TEvent (Entry, nbU, nbV, isUpdated)); +/*! + \brief Set transparency of the presentation + \param theEntry geometry object's entry + \param theTransparency transparency (floating point value between 0 and 1) + \param theUpdateViewer \c true to update active view's contents +*/ +void GEOM_Swig::setTransparency( const char* theEntry, float theTransparency, bool theUpdateViewer ) +{ + ProcessVoidEvent( new TSetPropertyEvent( theEntry, GEOM::propertyName( GEOM::Transparency ), + theTransparency, theUpdateViewer ) ); } -void GEOM_Swig::setTransparency(const char* theEntry, float transp, bool isUpdated) +/*! + \brief Set deflection coefficient of the presentation + \param theEntry geometry object's entry + \param theDeflection deflection coefficient (floating point value) + \param theUpdateViewer \c true to update active view's contents +*/ +void GEOM_Swig::setDeflection( const char* theEntry, float theDeflection, bool theUpdateViewer ) { - class TEvent: public SALOME_Event { - std::string myEntry; - float myParam; - bool myUpdateViewer; - public: - TEvent(const char* theEntryArg, float theParam, bool theUpdated): - myEntry(theEntryArg), myParam(theParam), myUpdateViewer(theUpdated) - {} - virtual void Execute() { - SUIT_Application* anApp = SUIT_Session::session()->activeApplication(); - if (!anApp) return; - - Handle(SALOME_InteractiveObject) anIO = - new SALOME_InteractiveObject(myEntry.c_str(), "GEOM", ""); - - if (SVTK_ViewWindow* aViewWindow = GetSVTKViewWindow(anApp)) { - SVTK_View* aView = aViewWindow->getView(); - aView->SetTransparency(anIO, myParam); - if (myUpdateViewer) - aView->Repaint(); - } else if (OCCViewer_Viewer* occViewer = GetOCCViewer(anApp)) { - SOCC_Viewer* soccViewer = dynamic_cast(occViewer); - if (soccViewer) - soccViewer->setTransparency(anIO, myParam, myUpdateViewer); - } - } - }; + ProcessVoidEvent( new TSetPropertyEvent( theEntry, GEOM::propertyName( GEOM::Deflection ), + theDeflection, theUpdateViewer ) ); +} - ProcessVoidEvent(new TEvent (theEntry, transp, isUpdated)); +/*! + \brief Set material to the presentation + \param theEntry geometry object's entry + \param theMaterial material name (string) + \param theUpdateViewer \c true to update active view's contents +*/ +void GEOM_Swig::setMaterial( const char* theEntry, const char* theMaterial, bool theUpdateViewer ) +{ + Material_Model material; + material.fromResources( theMaterial ); + ProcessVoidEvent( new TSetPropertyEvent( theEntry, GEOM::propertyName( GEOM::Material ), + material.toProperties(), theUpdateViewer ) ); } +/*! + \brief Set material property to the presentation + \param theEntry geometry object's entry + \param theMaterial material property string + \param theUpdateViewer \c true to update active view's contents +*/ +void GEOM_Swig::setMaterialProperty( const char* theEntry, const char* theMaterial, bool theUpdateViewer ) +{ + ProcessVoidEvent( new TSetPropertyEvent( theEntry, GEOM::propertyName( GEOM::Material ), + theMaterial, theUpdateViewer ) ); +} -class TInitGeomGenEvent: public SALOME_Event { +class TInitGeomGenEvent: public SALOME_Event +{ public: typedef bool TResult; TResult myResult; - TInitGeomGenEvent() : myResult(false) {} - virtual void Execute() { + TInitGeomGenEvent() : myResult(false) + {} + virtual void Execute() + { myResult = GeometryGUI::InitGeomGen(); } }; -bool GEOM_Swig::initGeomGen() -{ - return ProcessEvent(new TInitGeomGenEvent()); -} - - -void GEOM_Swig::eraseGO (const char* Entry, bool allWindows) -{ - class TEvent: public SALOME_Event - { - std::string myEntry; - bool myFromAllWindows; - public: - TEvent(const char* theEntry, bool fromAllWindows): - myEntry(theEntry), myFromAllWindows(fromAllWindows) - {} - virtual void Execute() - { - SUIT_Application* app = SUIT_Session::session()->activeApplication(); - if (!app) return; - SalomeApp_Study* ActiveStudy = dynamic_cast(app->activeStudy()); - if (!ActiveStudy) return; - - Handle (SALOME_InteractiveObject) aIO = new SALOME_InteractiveObject(myEntry.c_str(), "GEOM", ""); - - GEOM_Displayer(ActiveStudy).Erase(aIO, true); - /* if (myFromAllWindows) { - QPtrList aWindows = app->desktop()->windows(); - SUIT_ViewWindow* aWin = 0; - for (aWin = aWindows.first(); aWin; aWin = aWindows.next()) { - EraseObject(aWin, aIO); - } - } else { - SUIT_ViewWindow* aWin = app->desktop()->activeWindow(); - if (aWin) - EraseObject(aWin, aIO); - }*/ - } - - /* private: - void EraseObject(SUIT_ViewWindow* theWin, Handle (SALOME_InteractiveObject) theIO) - { - if (theWin->getViewManager()->getType() == OCCViewer_Viewer::Type()){ - OCCViewer_ViewWindow* vw = dynamic_cast( theWin ); - if ( vw ) { - OCCViewer_ViewManager* vm = dynamic_cast( vw->getViewManager() ); - if ( vm ) { - SOCC_Viewer* aViewer = dynamic_cast(vm->getOCCViewer()); - if (aViewer) { - SALOME_Prs* aPrs = aViewer->CreatePrs(myEntry.c_str()); - if (aPrs) { - SALOME_OCCPrs* aOccPrs = dynamic_cast(aPrs); - if (aOccPrs) { - aViewer->Erase(aOccPrs); - aViewer->Repaint(); - } - } - } - } - } - } else if (theWin->getViewManager()->getType() == SVTK_Viewer::Type()){ - SVTK_ViewWindow* aViewWindow = dynamic_cast( theWin ); - if (aViewWindow) { - aViewWindow->Erase(theIO); - } - } - }*/ - - }; - ProcessVoidEvent(new TEvent(Entry, allWindows)); -} - - - -void GEOM_Swig::setDeflection(const char* theEntry, float theDeflect) +/*! + \brief Initialize GEOM module's engine + \return \c true if initialization succeedes or \c false otherwise +*/ +bool GEOM_Swig::initGeomGen() { - class TEvent: public SALOME_Event { - std::string myEntry; - float myParam; - public: - TEvent(const char* theEntryArg, float theParam): - myEntry(theEntryArg), myParam(theParam) - {} - virtual void Execute() { - SUIT_Application* anApp = SUIT_Session::session()->activeApplication(); - if (!anApp) return; - - Handle(SALOME_InteractiveObject) anIO = - new SALOME_InteractiveObject(myEntry.c_str(), "GEOM", ""); - - if (SVTK_ViewWindow* aViewWindow = GetSVTKViewWindow(anApp)) { - vtkActorCollection* aActors = aViewWindow->getRenderer()->GetActors(); - aActors->InitTraversal(); - while (vtkActor* aAct = aActors->GetNextActor()) { - if (GEOM_Actor* aGeomActor = dynamic_cast(aAct)) { - if (aGeomActor->hasIO()) { - Handle(SALOME_InteractiveObject) aNextIO = aGeomActor->getIO(); - if (aNextIO->isSame(anIO)) { - aGeomActor->setDeflection(myParam); - aViewWindow->Repaint(); - return; - } - } - } - } - // aView->SetTransparency(anIO, myParam); - //aView->Repaint(); - } else if (OCCViewer_Viewer* occViewer = GetOCCViewer(anApp)) { - Handle(AIS_InteractiveContext) aContext = occViewer->getAISContext(); - AIS_ListOfInteractive aAISList; - aContext->DisplayedObjects(aAISList); - AIS_ListIteratorOfListOfInteractive it(aAISList); - for (; it.More(); it.Next()) { - Handle(SALOME_InteractiveObject) aObj = - Handle(SALOME_InteractiveObject)::DownCast(it.Value()->GetOwner()); - if ((!aObj.IsNull()) && aObj->hasEntry() && aObj->isSame(anIO)) { - Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(it.Value()); - if (!aShape.IsNull()) { - TopoDS_Shape aSh = aShape->Shape(); - if (!aSh.IsNull()) - BRepTools::Clean(aSh); - - aShape->SetOwnDeviationCoefficient( myParam ); - aShape->SetOwnHLRDeviationAngle( 1.57 ); - aContext->Redisplay(aShape); - return; - } - } - } - } - } - }; - - ProcessVoidEvent(new TEvent (theEntry, theDeflect)); + return ProcessEvent( new TInitGeomGenEvent() ); } - diff --git a/src/GEOM_SWIG_WITHIHM/libGEOM_Swig.h b/src/GEOM_SWIG_WITHIHM/libGEOM_Swig.h index 5f85b568b..8580c87c9 100644 --- a/src/GEOM_SWIG_WITHIHM/libGEOM_Swig.h +++ b/src/GEOM_SWIG_WITHIHM/libGEOM_Swig.h @@ -19,45 +19,43 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - -// GEOM GEOMGUI : GUI for Geometry component // File : libGEOM_Swig.h // Author : Nicolas REJNERI, Paul RASCLE -// -#ifndef GEOMETRYGUI_SWIG_HXX -#define GEOMETRYGUI_SWIG_HXX +#ifndef LIBGEOM_SWIG_H +#define LIBGEOM_SWIG_H #include "GEOM_GEOMGUI.hxx" -// IDL Headers -#include -#include CORBA_SERVER_HEADER(GEOM_Gen) -#include CORBA_SERVER_HEADER(SALOMEDS) -#include CORBA_SERVER_HEADER(SALOMEDS_Attributes) - class GEOMGUI_EXPORT GEOM_Swig { public: GEOM_Swig(); ~GEOM_Swig(); - void createAndDisplayGO(const char* Entry, bool isUpdated = true); - void eraseGO(const char* Entry, bool allWindows); - void createAndDisplayFitAllGO(const char* Entry); + void createAndDisplayGO( const char* theEntry, bool theUpdateViewer = true ); + void createAndDisplayFitAllGO( const char* theEntry ); + void eraseGO( const char* theEntry, bool theUpdateViewer = true ); + void UpdateViewer(); - void setDisplayMode(const char* Entry, int mode, bool isUpdated = true); - void setVectorsMode(const char* Entry, bool isSet, bool isUpdated = true); - void setColor(const char* Entry, int red, int green, int blue, bool isUpdated = true); - void setTransparency(const char* Entry, float transp, bool isUpdated = true); - void setIsos(const char* Entry, int nbU, int nbV, bool isUpdated =true); - void setDeflection(const char* Entry, float deflect); - int getIndexTopology(const char *SubEntry, const char *Entry); - const char* getShapeTypeString(const char *Entry); - const char* getShapeTypeIcon(const char *Ior); + void setDisplayMode( const char* theEntry, int theMode, bool theUpdateViewer = true ); + void setVectorsMode( const char* theEntry, bool theOn, bool theUpdateViewer = true ); + void setColor( const char* theEntry, int theRed, int theGreen, int theBlue, bool theUpdateViewer = true ); + void setTransparency( const char* theEntry, float theTransparency, bool theUpdateViewer = true ); + void setIsos( const char* theEntry, int theNbU, int theNbV, bool theUpdateViewer = true ); + void setDeflection( const char* theEntry, float theDeflection, bool theUpdateViewer = true ); + void setMaterial( const char* theEntry, const char* theMaterial, bool theUpdateViewer = true ); + void setMaterialProperty( const char* theEntry, const char* theMaterial, bool theUpdateViewer = true ); + + int getIndexTopology( const char* theSubIOR, const char* theMainIOR ); + const char* getShapeTypeString( const char* theIOR ); + const char* getShapeTypeIcon( const char* theIOR ); bool initGeomGen(); +private: + + void init(); }; -#endif // GEOMETRYGUI_SWIG_HXX +#endif // LIBGEOM_SWIG_H diff --git a/src/GEOM_SWIG_WITHIHM/libGEOM_Swig.i b/src/GEOM_SWIG_WITHIHM/libGEOM_Swig.i index 6bf220c2d..7504d783f 100644 --- a/src/GEOM_SWIG_WITHIHM/libGEOM_Swig.i +++ b/src/GEOM_SWIG_WITHIHM/libGEOM_Swig.i @@ -22,7 +22,6 @@ // Author : Nicolas REJNERI, Paul RASCLE // Project : SALOME // Module : GEOM -// $Header$ // %module libGEOM_Swig @@ -56,20 +55,24 @@ class GEOM_Swig GEOM_Swig(); ~GEOM_Swig(); - void createAndDisplayGO(const char* Entry, bool isUpdated =true); - void eraseGO(const char* Entry, bool allWindows); - void createAndDisplayFitAllGO(const char* Entry); + void createAndDisplayGO( const char* theEntry, bool theUpdateViewer = true ); + void createAndDisplayFitAllGO( const char* theEntry ); + void eraseGO( const char* theEntry, bool theUpdateViewer = true ); + void UpdateViewer(); - int getIndexTopology(const char *SubEntry, const char *Entry); - const char* getShapeTypeString(const char *Entry); - void setDisplayMode(const char* Entry, int mode, bool isUpdated =true); - void setVectorsMode(const char* Entry, bool isSet, bool isUpdated =true); - void setColor(const char* Entry, int red, int green, int blue, bool isUpdated =true); - void setTransparency(const char* Entry, float transp, bool isUpdated =true); - void setIsos(const char* Entry, int nbU, int nbV, bool isUpdated =true); - void setDeflection(const char* Entry, float deflect); - const char* getShapeTypeIcon(const char *Ior); + void setDisplayMode( const char* theEntry, int theMode, bool theUpdateViewer = true ); + void setVectorsMode( const char* theEntry, bool theOn, bool theUpdateViewer = true ); + void setColor( const char* theEntry, int theRed, int theGreen, int theBlue, bool theUpdateViewer = true ); + void setTransparency( const char* theEntry, float theTransparency, bool theUpdateViewer = true ); + void setIsos( const char* theEntry, int theNbU, int theNbV, bool theUpdateViewer = true ); + void setDeflection( const char* theEntry, float theDeflection, bool theUpdateViewer = true ); + void setMaterial( const char* theEntry, const char* theMaterial, bool theUpdateViewer = true ); + void setMaterialProperty( const char* theEntry, const char* theMaterial, bool theUpdateViewer = true ); + + int getIndexTopology( const char* theSubIOR, const char* theMainIOR ); + const char* getShapeTypeString( const char* theIOR ); + const char* getShapeTypeIcon( const char* theIOR ); bool initGeomGen(); }; diff --git a/src/GroupGUI/GroupGUI_GroupDlg.cxx b/src/GroupGUI/GroupGUI_GroupDlg.cxx index 5d51da8fb..8cd1ae6a7 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.cxx +++ b/src/GroupGUI/GroupGUI_GroupDlg.cxx @@ -33,6 +33,7 @@ #include #include +#include #include @@ -66,6 +67,9 @@ #include +#define GROUP_IDLST_COLOR Qt::blue // Specific color for the IDs of subShapes in the dialog box +#define GROUP_NEWIDLST_COLOR Qt::red // Specific color for the new IDs of subShapes in the dialog box + enum { ALL_SUBSHAPES = 0, GET_IN_PLACE, SUBSHAPES_OF_SHAPE2, SUBSHAPES_OF_INVISIBLE_SHAPE2 }; GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QWidget* parent) @@ -186,11 +190,13 @@ GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QW GroupGUI_GroupDlg::~GroupGUI_GroupDlg() { + GEOM_Displayer* aDisplayer = getDisplayer(); if (myIsHiddenMain) { - GEOM_Displayer* aDisplayer = getDisplayer(); aDisplayer->Display(myMainObj); myIsHiddenMain = false; } + aDisplayer->Display(myGroup); + myDmMode = -1; } //================================================================================= @@ -199,6 +205,7 @@ GroupGUI_GroupDlg::~GroupGUI_GroupDlg() //================================================================================= void GroupGUI_GroupDlg::Init() { + myDmMode = -1; LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); //unset shape type to avoid preparation of selection before exact user shape type selection @@ -236,9 +243,12 @@ void GroupGUI_GroupDlg::Init() setShapeType((TopAbs_ShapeEnum)anOper->GetType(myGroup)); GEOM::ListOfLong_var aCurrList = anOper->GetObjects(myGroup); - for (int i = 0, n = aCurrList->length(); i < n; i++) - myIdList->addItem(new QListWidgetItem(QString("%1").arg(aCurrList[i]))); - + for (int i = 0, n = aCurrList->length(); i < n; i++) { + QListWidgetItem* itm = new QListWidgetItem( QString( "%1" ).arg( aCurrList[ i ] ) ); + myGroupIdList.append( aCurrList[ i ] ); + itm->setTextColor( QColor( GROUP_IDLST_COLOR ) ); + myIdList->addItem( itm ); + } myEditCurrentArgument = 0; } connect(mySelBtn2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); @@ -306,14 +316,18 @@ void GroupGUI_GroupDlg::ClickOnOk() //================================================================================= bool GroupGUI_GroupDlg::ClickOnApply() { - if(!isApplyAndClose()) + if(!isApplyAndClose()) { setIsDisableBrowsing( true ); + setIsDisplayResult( false ); + } - if (!onAccept(myMode == CreateGroup, true,isApplyAndClose())) + if (!onAccept(myMode == CreateGroup, true, isApplyAndClose())) return false; - if(!isApplyAndClose()) + if(!isApplyAndClose()) { setIsDisableBrowsing( false ); + setIsDisplayResult( true ); + } if (myMode == CreateGroup) { @@ -322,8 +336,19 @@ bool GroupGUI_GroupDlg::ClickOnApply() ConstructorsClicked(getConstructorId()); } else + { + int n = myIdList->count(); + myGroupIdList.clear(); + if (n > 0) + { + for (int i = 0; i < n; i++) { + QListWidgetItem* anItem = myIdList->item( i ); + myGroupIdList.append( anItem->text().toInt() ); + anItem->setTextColor( GROUP_IDLST_COLOR ); + } + } activateSelection(); - + } return true; } @@ -576,7 +601,7 @@ void GroupGUI_GroupDlg::selectAllSubShapes() if (aSubShapes->length() > 0) { if (subSelectionWay() == ALL_SUBSHAPES) { - myIdList->clear(); // for sorted final list? +// myIdList->clear(); // for sorted final list? if (!aShOp->IsDone()) return; @@ -600,12 +625,13 @@ void GroupGUI_GroupDlg::selectAllSubShapes() QListWidgetItem* anItem = 0; QString text = QString("%1").arg(anIndex); - if (!myInPlaceObj->_is_nil()) { +// if (!myInPlaceObj->_is_nil()) { QList found = myIdList->findItems(text, Qt::MatchExactly); if (found.count()) anItem = found[0]; - } +// } if (!anItem) { anItem = new QListWidgetItem(text); + anItem->setTextColor( myGroupIdList.contains(anIndex) ? QColor( GROUP_IDLST_COLOR ) : QColor( GROUP_NEWIDLST_COLOR ) ); myIdList->addItem(anItem); } anItem->setSelected(true); @@ -754,6 +780,7 @@ void GroupGUI_GroupDlg::add() continue; QListWidgetItem* anItem = new QListWidgetItem(QString("%1").arg(aMapIndex(i))); + anItem->setTextColor( myGroupIdList.contains( aMapIndex( i ) ) ? QColor( GROUP_IDLST_COLOR ) : QColor( GROUP_NEWIDLST_COLOR ) ); myIdList->addItem(anItem); anItem->setSelected(true); } @@ -835,7 +862,7 @@ void GroupGUI_GroupDlg::setShapeType(const TopAbs_ShapeEnum theType) void GroupGUI_GroupDlg::activateSelection() { bool isApply = ((QPushButton*)sender() == buttonApply()); - if(!isApply) + if(!isApplyAndClose()) erasePreview(false); // local selection @@ -844,27 +871,42 @@ void GroupGUI_GroupDlg::activateSelection() myIsShapeType) // check if shape type is already choosen by user { GEOM_Displayer* aDisplayer = getDisplayer(); - - // Mantis issue 0021421: do not hide main shape, if explode on VERTEX - if (getShapeType() == TopAbs_VERTEX) { - if (myIsHiddenMain) - aDisplayer->Display(myMainObj); - } - else { - SALOME_View* view = GEOM_Displayer::GetActiveView(); + + //display mode for main shape + if ( myDmMode == -1 ) { + SALOME_View* view = GEOM_Displayer::GetActiveView(); if (view) { CORBA::String_var aMainEntry = myMainObj->GetStudyEntry(); Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO"); - if (view->isVisible(io)) { - aDisplayer->Erase(myMainObj, false, false); - myIsHiddenMain = true; + if ( view->isVisible( io ) ) { + Handle(GEOM_AISShape) aSh = GEOMBase::ConvertIOinGEOMAISShape( io, true ); + if(!aSh.IsNull()) { + myDmMode = aSh->isTopLevel() ? aSh->prevDisplayMode() : aSh->DisplayMode(); + } + // Hide main shape, if explode on VERTEX + if(getShapeType() != TopAbs_VERTEX) { + aDisplayer->Erase(myMainObj, false, false); + myIsHiddenMain = true; + } } + else + myDmMode = SUIT_Session::session()->resourceMgr()->integerValue( "Geometry", "display_mode" ); } } - if(!isApply) { - int prevDisplayMode = aDisplayer->SetDisplayMode(0); + aDisplayer->SetDisplayMode(myDmMode); + + // Mantis issue 0021421: do not hide main shape, if explode on VERTEX + if (getShapeType() == TopAbs_VERTEX) { + if (myIsHiddenMain) + aDisplayer->Display(myMainObj); + } + aDisplayer->Erase(myGroup, false, false); + + QColor aColor = SUIT_Session::session()->resourceMgr()->colorValue( "Geometry", "editgroup_color" ); + Quantity_NameOfColor aCol = SalomeApp_Tools::color( aColor ).Name(); + if(!isApplyAndClose()) { SUIT_ViewWindow* aViewWindow = 0; SUIT_Study* activeStudy = SUIT_Session::session()->activeApplication()->activeStudy(); if (activeStudy) @@ -895,8 +937,15 @@ void GroupGUI_GroupDlg::activateSelection() for (; anExp.More(); anExp.Next()) { TopoDS_Shape aSubShape = anExp.Current(); int index = aSubShapesMap.FindIndex(aSubShape); - QString anEntry = anEntryBase + QString("_%1").arg(index); - + QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index); + Handle(SALOME_InteractiveObject) io = + new SALOME_InteractiveObject(anEntry.toAscii(), "GEOM", "TEMP_IO"); + if ( myGroupIdList.contains( index ) ) { + aDisplayer->SetColor( aCol ); + } + else { + aDisplayer->UnsetColor(); + } SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, aView); if (aPrs) { displayPreview(aPrs, true, false); // append, do not update @@ -914,7 +963,14 @@ void GroupGUI_GroupDlg::activateSelection() for (; aM2IPit.More(); aM2IPit.Next()) { int index = aM2IPit.Key(); TopoDS_Shape aSubShape = aSubShapesMap.FindKey(index); - QString anEntry = anEntryBase + QString("_%1").arg(index); + QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index); + + if ( myGroupIdList.contains( index ) ) { + aDisplayer->SetColor( aCol ); + } + else { + aDisplayer->UnsetColor(); + } SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, aView); if (aPrs) { @@ -923,9 +979,9 @@ void GroupGUI_GroupDlg::activateSelection() } } else ; - + aDisplayer->UnsetDisplayMode(); + aDisplayer->UnsetColor(); aDisplayer->UpdateViewer(); - aDisplayer->SetDisplayMode(prevDisplayMode); } } diff --git a/src/GroupGUI/GroupGUI_GroupDlg.h b/src/GroupGUI/GroupGUI_GroupDlg.h index 438f52b10..84618bf4b 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.h +++ b/src/GroupGUI/GroupGUI_GroupDlg.h @@ -102,6 +102,8 @@ private: GEOM::GEOM_Object_var myInPlaceObj; int myInPlaceObjSelectState; TColStd_DataMapOfIntegerInteger myMain2InPlaceIndices; + QList myGroupIdList; + int myDmMode; QPushButton* mySelBtn; QLineEdit* myMainName; diff --git a/src/IGESExport/Makefile.am b/src/IGESExport/Makefile.am index 694aee5b0..9fed32fdb 100644 --- a/src/IGESExport/Makefile.am +++ b/src/IGESExport/Makefile.am @@ -21,7 +21,6 @@ # Author : Pavel TELKOV # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : GEOM -# $Header$ # include $(top_srcdir)/adm_local/unix/make_common_starter.am diff --git a/src/IGESImport/Makefile.am b/src/IGESImport/Makefile.am index b6001bf34..ebecee851 100644 --- a/src/IGESImport/Makefile.am +++ b/src/IGESImport/Makefile.am @@ -20,7 +20,6 @@ # Author : Pavel TELKOV # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : GEOM -# $Header$ include $(top_srcdir)/adm_local/unix/make_common_starter.am diff --git a/src/Makefile.am b/src/Makefile.am index 862b90287..e81e3bfd9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,15 +15,14 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# # File : Makefile.am # Author : Alexander BORODIN, Open CASCADE S.A.S. (alexander.borodin@opencascade.com) # Package : src (source files directory) -SUBDIRS = ARCHIMEDE NMTDS NMTTools GEOMAlgo SKETCHER OCC2VTK GEOM \ - BREPExport BREPImport IGESExport IGESImport STEPExport \ - STEPImport STLExport VTKExport ShHealOper GEOMImpl GEOM_I \ +SUBDIRS = ARCHIMEDE NMTDS NMTTools BlockFix GEOMAlgo SKETCHER OCC2VTK GEOM \ + BREPExport BREPImport IGESExport IGESImport STEPExport STEPImport \ + STLExport VTKExport ShHealOper GEOMUtils GEOMImpl GEOM_I \ GEOMClient GEOM_I_Superv GEOM_SWIG GEOM_PY if WITH_OPENCV @@ -31,18 +30,18 @@ if WITH_OPENCV endif if GEOM_ENABLE_GUI - SUBDIRS += OBJECT DlgRef GEOMFiltersSelection Material GEOMGUI GEOMBase GEOMToolsGUI \ - DisplayGUI BasicGUI PrimitiveGUI GenerationGUI EntityGUI BuildGUI \ - BooleanGUI TransformationGUI OperationGUI RepairGUI MeasureGUI \ - GroupGUI BlocksGUI AdvancedGUI GEOM_SWIG_WITHIHM + SUBDIRS += OBJECT DlgRef GEOMFiltersSelection Material GEOMGUI GEOMBase \ + GEOMToolsGUI DisplayGUI BasicGUI PrimitiveGUI GenerationGUI \ + EntityGUI BuildGUI BooleanGUI TransformationGUI OperationGUI \ + RepairGUI MeasureGUI GroupGUI BlocksGUI AdvancedGUI GEOM_SWIG_WITHIHM endif -DIST_SUBDIRS = ARCHIMEDE NMTDS NMTTools GEOMAlgo \ - SKETCHER OCC2VTK GEOM BREPExport \ - BREPImport IGESExport IGESImport STEPExport STEPImport STLExport \ - VTKExport ShHealOper GEOMImpl GEOM_I GEOMClient GEOM_I_Superv \ - GEOM_SWIG OBJECT DlgRef GEOMFiltersSelection Material GEOMGUI GEOMBase \ +DIST_SUBDIRS = ARCHIMEDE NMTDS NMTTools BlockFix GEOMAlgo SKETCHER \ + OCC2VTK GEOM BREPExport BREPImport IGESExport IGESImport \ + STEPExport STEPImport STLExport VTKExport ShHealOper GEOMUtils \ + GEOMImpl GEOM_I GEOMClient GEOM_I_Superv GEOM_SWIG OBJECT \ + DlgRef GEOMFiltersSelection Material GEOMGUI GEOMBase \ GEOMToolsGUI DisplayGUI BasicGUI PrimitiveGUI GenerationGUI \ EntityGUI BuildGUI BooleanGUI TransformationGUI OperationGUI \ - RepairGUI MeasureGUI GroupGUI BlocksGUI AdvancedGUI \ + RepairGUI MeasureGUI GroupGUI BlocksGUI AdvancedGUI \ GEOM_SWIG_WITHIHM GEOM_PY ShapeRecognition diff --git a/src/Material/Makefile.am b/src/Material/Makefile.am index c0c43367f..e87bf9360 100644 --- a/src/Material/Makefile.am +++ b/src/Material/Makefile.am @@ -36,6 +36,12 @@ dist_libMaterial_la_SOURCES = \ Material_Model.cxx \ Material_ResourceMgr.cxx +MOC_FILES = \ + Material_ResourceMgr_moc.cxx + +nodist_libMaterial_la_SOURCES = \ + $(MOC_FILES) + # additional information to compile and link file libMaterial_la_CPPFLAGS = \ $(QT_INCLUDES) \ diff --git a/src/Material/Material_Model.cxx b/src/Material/Material_Model.cxx index 9744571c5..949d7d2b0 100644 --- a/src/Material/Material_Model.cxx +++ b/src/Material/Material_Model.cxx @@ -25,6 +25,8 @@ #include "GEOM_VTKPropertyMaterial.hxx" #include "Material_ResourceMgr.h" +#include + /*! \brief Constructor @@ -78,21 +80,36 @@ void Material_Model::fromProperties( const QString& props ) else if ( key == "emissivecolor" && Qtx::stringToColor( data, colorValue ) ) { setColor( Emissive, colorValue ); } - else if ( key == "ambientcoefficient" && dblOk ) { + else if ( key == "frontambientcoefficient" && dblOk ) { setReflection( Ambient, dblValue ); } - else if ( key == "diffusecoefficient" && dblOk ) { + else if ( key == "backambientcoefficient" && dblOk ) { + setReflection( Ambient, dblValue, false ); + } + else if ( key == "frontdiffusecoefficient" && dblOk ) { setReflection( Diffuse, dblValue ); } - else if ( key == "specularcoefficient" && dblOk ) { + else if ( key == "backdiffusecoefficient" && dblOk ) { + setReflection( Diffuse, dblValue, false ); + } + else if ( key == "frontspecularcoefficient" && dblOk ) { setReflection( Specular, dblValue ); } - else if ( key == "emissivecoefficient" && dblOk ) { + else if ( key == "backspecularcoefficient" && dblOk ) { + setReflection( Specular, dblValue, false ); + } + else if ( key == "frontemissivecoefficient" && dblOk ) { setReflection( Emissive, dblValue ); } - else if ( key == "shininess" && dblOk ) { + else if ( key == "backemissivecoefficient" && dblOk ) { + setReflection( Emissive, dblValue, false ); + } + else if ( key == "frontshininess" && dblOk ) { setShininess( dblValue ); } + else if ( key == "backshininess" && dblOk ) { + setShininess( dblValue, false ); + } else if ( key == "transparency" && dblOk ) { setTransparency( dblValue ); } @@ -128,7 +145,7 @@ QString Material_Model::toProperties() props << fmt.arg( "Physical" ).arg( isPhysical() ); // shininess - props << fmt.arg( "Shininess" ).arg( shininess() ); + props << fmt.arg( "FrontShininess" ).arg( QString::number ( shininess( true ), 'g', 4 ) ) << fmt.arg( "BackShininess" ).arg( QString::number ( shininess( false ), 'g', 4 ) ); //transparency props << fmt.arg( "Transparency" ).arg( transparency() ); @@ -137,25 +154,25 @@ QString Material_Model::toProperties() props << fmt.arg( "Ambient" ).arg( hasReflection( Ambient ) ); if ( color( Ambient ).isValid() ) props << fmt.arg( "AmbientColor" ).arg( Qtx::colorToString( color( Ambient ) ) ); - props << fmt.arg( "AmbientCoefficient" ).arg( reflection( Ambient ) ); + props << fmt.arg( "FrontAmbientCoefficient" ).arg( QString::number ( reflection( Ambient, true ), 'g', 4 ) ) << fmt.arg( "BackAmbientCoefficient" ).arg( QString::number ( reflection( Ambient, false ), 'g', 4 ) ); // diffuse reflection props << fmt.arg( "Diffuse" ).arg( hasReflection( Diffuse ) ); if ( color( Diffuse ).isValid() ) props << fmt.arg( "DiffuseColor" ).arg( Qtx::colorToString( color( Diffuse ) ) ); - props << fmt.arg( "DiffuseCoefficient" ).arg( reflection( Diffuse ) ); + props << fmt.arg( "FrontDiffuseCoefficient" ).arg( QString::number ( reflection( Diffuse, true ), 'g', 4 ) ) << fmt.arg( "BackDiffuseCoefficient" ).arg( QString::number ( reflection( Diffuse, false ), 'g', 4 ) ); // specular reflection props << fmt.arg( "Specular" ).arg( hasReflection( Specular ) ); if ( color( Specular ).isValid() ) props << fmt.arg( "SpecularColor" ).arg( Qtx::colorToString( color( Specular ) ) ); - props << fmt.arg( "SpecularCoefficient" ).arg( reflection( Specular ) ); + props << fmt.arg( "FrontSpecularCoefficient" ).arg( QString::number ( reflection( Specular, true ), 'g', 4 ) ) << fmt.arg( "BackSpecularCoefficient" ).arg( QString::number ( reflection( Specular, false ), 'g', 4 ) ); // emissive reflection props << fmt.arg( "Emissive" ).arg( hasReflection( Emissive ) ); if ( color( Emissive ).isValid() ) props << fmt.arg( "EmissiveColor" ).arg( Qtx::colorToString( color( Emissive ) ) ); - props << fmt.arg( "EmissiveCoefficient" ).arg( reflection( Emissive ) ); + props << fmt.arg( "FrontEmissiveCoefficient" ).arg( QString::number ( reflection( Emissive, true ), 'g', 4 ) ) << fmt.arg( "BackEmissiveCoefficient" ).arg( QString::number ( reflection( Emissive, false ), 'g', 4 ) ); return props.join( ":" ); } @@ -169,7 +186,7 @@ QString Material_Model::toProperties() \param resMgr resource manager (if not specified, new resources manager is created) \sa toResources() */ -void Material_Model::fromResources( const QString& material, QtxResourceMgr* resMgr ) +void Material_Model::fromResources( const QString& material, Material_ResourceMgr* resMgr ) { static QString common = "[common]"; @@ -179,23 +196,33 @@ void Material_Model::fromResources( const QString& material, QtxResourceMgr* res // material name is not specified: use default values if ( material.isEmpty() ) return; - bool ownResourcesMgr = resMgr == 0; - - if ( ownResourcesMgr ) - resMgr = new Material_ResourceMgr(); + if ( !resMgr ) + resMgr = Material_ResourceMgr::resourceMgr(); + + // lock resources manager + QMutexLocker lock( &resMgr->myMutex ); // read common section if ( material != common && resMgr->hasSection( common ) ) - fromResources( common, resMgr ); + read( common, resMgr ); + + // read material section + read( material, resMgr ); +} +void Material_Model::read( const QString& material, Material_ResourceMgr* resMgr ) +{ // physical if ( resMgr->hasValue( material, "physical" ) ) { setPhysical( resMgr->booleanValue( material, "physical" ) ); } // shininess - if ( resMgr->hasValue( material, "shininess" ) ) { - setShininess( resMgr->doubleValue( material, "shininess" ) ); + if ( resMgr->hasValue( material, "front_shininess" ) ) { + setShininess( resMgr->doubleValue( material, "front_shininess" ) ); + } + if ( resMgr->hasValue( material, "back_shininess" ) ) { + setShininess( resMgr->doubleValue( material, "back_shininess" ), false ); } // transparency @@ -207,8 +234,11 @@ void Material_Model::fromResources( const QString& material, QtxResourceMgr* res if ( resMgr->hasValue( material, "ambient-color" ) ) { setColor( Ambient, resMgr->colorValue( material, "ambient-color" ) ); } - if ( resMgr->hasValue( material, "ambient-coefficient" ) ) { - setReflection( Ambient, resMgr->doubleValue( material, "ambient-coefficient" ) ); + if ( resMgr->hasValue( material, "front_ambient-coefficient" ) ) { + setReflection( Ambient, resMgr->doubleValue( material, "front_ambient-coefficient" ) ); + } + if ( resMgr->hasValue( material, "back_ambient-coefficient" ) ) { + setReflection( Ambient, resMgr->doubleValue( material, "back_ambient-coefficient" ), false ); } if ( resMgr->hasValue( material, "ambient" ) ) { setReflection( Ambient, resMgr->booleanValue( material, "ambient" ) ); @@ -218,8 +248,11 @@ void Material_Model::fromResources( const QString& material, QtxResourceMgr* res if ( resMgr->hasValue( material, "diffuse-color" ) ) { setColor( Diffuse, resMgr->colorValue( material, "diffuse-color" ) ); } - if ( resMgr->hasValue( material, "diffuse-coefficient" ) ) { - setReflection( Diffuse, resMgr->doubleValue( material, "diffuse-coefficient" ) ); + if ( resMgr->hasValue( material, "front_diffuse-coefficient" ) ) { + setReflection( Diffuse, resMgr->doubleValue( material, "front_diffuse-coefficient" ) ); + } + if ( resMgr->hasValue( material, "back_diffuse-coefficient" ) ) { + setReflection( Diffuse, resMgr->doubleValue( material, "back_diffuse-coefficient" ), false ); } if ( resMgr->hasValue( material, "diffuse" ) ) { setReflection( Diffuse, resMgr->booleanValue( material, "diffuse" ) ); @@ -229,8 +262,11 @@ void Material_Model::fromResources( const QString& material, QtxResourceMgr* res if ( resMgr->hasValue( material, "specular-color" ) ) { setColor( Specular, resMgr->colorValue( material, "specular-color" ) ); } - if ( resMgr->hasValue( material, "specular-coefficient" ) ) { - setReflection( Specular, resMgr->doubleValue( material, "specular-coefficient" ) ); + if ( resMgr->hasValue( material, "front_specular-coefficient" ) ) { + setReflection( Specular, resMgr->doubleValue( material, "front_specular-coefficient" ) ); + } + if ( resMgr->hasValue( material, "back_specular-coefficient" ) ) { + setReflection( Specular, resMgr->doubleValue( material, "back_specular-coefficient" ), false ); } if ( resMgr->hasValue( material, "specular" ) ) { setReflection( Specular, resMgr->booleanValue( material, "specular" ) ); @@ -240,15 +276,15 @@ void Material_Model::fromResources( const QString& material, QtxResourceMgr* res if ( resMgr->hasValue( material, "emissive-color" ) ) { setColor( Emissive, resMgr->colorValue( material, "emissive-color" ) ); } - if ( resMgr->hasValue( material, "emissive-coefficient" ) ) { - setReflection( Emissive, resMgr->doubleValue( material, "emissive-coefficient" ) ); + if ( resMgr->hasValue( material, "front_emissive-coefficient" ) ) { + setReflection( Emissive, resMgr->doubleValue( material, "front_emissive-coefficient" ) ); + } + if ( resMgr->hasValue( material, "back_emissive-coefficient" ) ) { + setReflection( Emissive, resMgr->doubleValue( material, "back_emissive-coefficient" ), false ); } if ( resMgr->hasValue( material, "emissive" ) ) { setReflection( Emissive, resMgr->booleanValue( material, "emissive" ) ); } - - if ( ownResourcesMgr ) - delete resMgr; } /*! @@ -257,9 +293,12 @@ void Material_Model::fromResources( const QString& material, QtxResourceMgr* res \param resMgr resource manager \sa fromResources() */ -void Material_Model::toResources( const QString& material, QtxResourceMgr* resMgr ) +void Material_Model::toResources( const QString& material, Material_ResourceMgr* resMgr ) { if ( resMgr && !material.isEmpty() ) { + // lock resources manager + QMutexLocker lock( &resMgr->myMutex ); + // remove resources section (to clean-up all previous properties) resMgr->remove( material ); @@ -267,7 +306,8 @@ void Material_Model::toResources( const QString& material, QtxResourceMgr* resMg resMgr->setValue( material, "physical", isPhysical() ); // shininess - resMgr->setValue( material, "shininess", shininess() ); + resMgr->setValue( material, "front_shininess", shininess( true) ); + resMgr->setValue( material, "back_shininess", shininess( false ) ); // transparency resMgr->setValue( material, "transparency", transparency() ); @@ -275,46 +315,33 @@ void Material_Model::toResources( const QString& material, QtxResourceMgr* resMg // ambient reflection if ( color( Ambient ).isValid() ) resMgr->setValue( material, "ambient-color", color( Ambient ) ); - resMgr->setValue( material, "ambient-coefficient", reflection( Ambient ) ); + resMgr->setValue( material, "front_ambient-coefficient", reflection( Ambient ) ); + resMgr->setValue( material, "back_ambient-coefficient", reflection( Ambient, false ) ); resMgr->setValue( material, "ambient", hasReflection( Ambient ) ); // diffuse reflection if ( color( Diffuse ).isValid() ) resMgr->setValue( material, "diffuse-color", color( Diffuse ) ); - resMgr->setValue( material, "diffuse-coefficient", reflection( Diffuse ) ); + resMgr->setValue( material, "front_diffuse-coefficient", reflection( Diffuse ) ); + resMgr->setValue( material, "back_diffuse-coefficient", reflection( Diffuse, false ) ); resMgr->setValue( material, "diffuse", hasReflection( Diffuse ) ); // Specular reflection if ( color( Specular ).isValid() ) resMgr->setValue( material, "specular-color", color( Specular ) ); - resMgr->setValue( material, "specular-coefficient", reflection( Specular ) ); + resMgr->setValue( material, "front_specular-coefficient", reflection( Specular ) ); + resMgr->setValue( material, "back_specular-coefficient", reflection( Specular, false ) ); resMgr->setValue( material, "specular", hasReflection( Specular ) ); // Emissive reflection if ( color( Emissive ).isValid() ) resMgr->setValue( material, "emissive-color", color( Emissive ) ); - resMgr->setValue( material, "emissive-coefficient", reflection( Emissive ) ); + resMgr->setValue( material, "front_emissive-coefficient", reflection( Emissive ) ); + resMgr->setValue( material, "back_emissive-coefficient", reflection( Emissive, false ) ); resMgr->setValue( material, "emissive", hasReflection( Emissive ) ); } } -/*! - \brief Initialize material model from the preferences - - The material name is retrieved from the "material" parameter of the "Geometry" section - of the specified resources manager. - - \param resMgr resources manager - \sa fromResources(), toResources() -*/ -// void Material_Model::fromPreferences( QtxResourceMgr* resMgr ) -// { -// if ( resMgr ) { -// // default material is Plastic -// fromResources( resMgr->stringValue( "Geometry", "material", "Plastic" ) ); -// } -// } - /*! \brief Get material type \return \c true if material is physical or \c false otherwise @@ -390,14 +417,18 @@ void Material_Model::setColor( ReflectionType type, const QColor& value ) /*! \brief Get coefficient value for the given reflection type \param type reflection type + \param theIsFront boolean flag for choosing side \return coefficient value for the specified reflection type - \sa setReflection(ReflectionType, double) + \sa setReflection(ReflectionType, double, bool = true) */ -double Material_Model::reflection( ReflectionType type ) const +double Material_Model::reflection( ReflectionType type, bool theIsFront ) const { double value = 0.0; if ( type >= 0 && type < 4 ) - value = myReflection[ type ].coef; + if ( theIsFront ) + value = myReflection[ type ].front_coef; + else + value = myReflection[ type ].back_coef; return value; } @@ -405,32 +436,44 @@ double Material_Model::reflection( ReflectionType type ) const \brief Set coefficient value for the given reflection type \param type reflection type \param value coefficient to be used by the given reflection type - \sa reflection() + \param theIsFront boolean flag for choosing side + \sa reflection( bool = true) */ -void Material_Model::setReflection( ReflectionType type, double value ) +void Material_Model::setReflection( ReflectionType type, double value, bool theIsFront ) { if ( type >= 0 && type < 4 ) - myReflection[ type ].coef = value; + if ( theIsFront ) + myReflection[ type ].front_coef = value; + else + myReflection[ type ].back_coef = value; } /*! \brief Get shininess value + \param theIsFront boolean flag for choosing side \return shininess value of the material - \sa setShininess() + \sa setShininess( double, bool = true ) */ -double Material_Model::shininess() const +double Material_Model::shininess( bool theIsFront ) const { - return myShininess; + if ( theIsFront ) + return myFrontShininess; + else + return myBackShininess; } /*! \brief Set shininess value \param value new shininess value - \sa shininess() + \param theIsFront boolean flag for choosing side + \sa shininess( bool = true ) */ -void Material_Model::setShininess( double value ) +void Material_Model::setShininess( double value, bool theIsFront ) { - myShininess = value; + if ( theIsFront ) + myFrontShininess = value; + else + myBackShininess = value; } /*! @@ -464,39 +507,45 @@ void Material_Model::init() setPhysical( false ); // shininess setShininess( 0.039 ); + setShininess( 0.039, false ); // transparency setTransparency( 0.0 ); // ambient reflection (enabled by default) Qtx::stringToColor( "#333333", c ); setColor( Ambient, c ); - setReflection( Ambient, 0.3 ); + setReflection( Ambient, 0.3, true ); + setReflection( Ambient, 0.3, false ); setReflection( Ambient, true ); // diffuse reflection (enabled by default) Qtx::stringToColor( "#000000", c ); setColor( Diffuse, c ); setReflection( Diffuse, 0.65 ); + setReflection( Diffuse, 0.65, false ); setReflection( Diffuse, true ); // specular reflection (enabled by default) Qtx::stringToColor( "#ffffff", c ); setColor( Specular, c ); - setReflection( Specular, 0.0 ); + setReflection( Specular, 0.0 ); + setReflection( Specular, 0.0, false ); setReflection( Specular, true ); // emissive reflection (disabled by default) Qtx::stringToColor( "#000000", c ); setColor( Emissive, c ); - setReflection( Emissive, 0.0 ); + setReflection( Emissive, 0.0 ); + setReflection( Emissive, 0.0, false ); setReflection( Emissive, false ); } /*! \brief Construct OCCT material aspect from material model + \param theIsFront boolean flag for choosing side \return material aspect object with corresponding properties */ -Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect() +Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect( bool theIsFront ) { // Get material aspect from the current model Graphic3d_MaterialAspect aspect; @@ -508,7 +557,7 @@ Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect() c = color( Ambient ); aspect.SetAmbientColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) ); } - aspect.SetAmbient( reflection( Ambient )); + aspect.SetAmbient( reflection( Ambient, theIsFront )); if ( hasReflection( Ambient ) ) aspect.SetReflectionModeOn( Graphic3d_TOR_AMBIENT ); else @@ -519,7 +568,7 @@ Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect() c = color( Diffuse ); aspect.SetDiffuseColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) ); } - aspect.SetDiffuse( reflection( Diffuse )); + aspect.SetDiffuse( reflection( Diffuse, theIsFront )); if ( hasReflection( Diffuse ) ) aspect.SetReflectionModeOn( Graphic3d_TOR_DIFFUSE ); else @@ -530,7 +579,7 @@ Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect() c = color( Specular ); aspect.SetSpecularColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) ); } - aspect.SetSpecular( reflection( Specular )); + aspect.SetSpecular( reflection( Specular, theIsFront )); if ( hasReflection( Specular ) ) aspect.SetReflectionModeOn( Graphic3d_TOR_SPECULAR ); else @@ -541,14 +590,14 @@ Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect() c = color( Emissive ); aspect.SetEmissiveColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) ); } - aspect.SetEmissive( reflection( Emissive )); + aspect.SetEmissive( reflection( Emissive, theIsFront )); if ( hasReflection( Emissive ) ) aspect.SetReflectionModeOn( Graphic3d_TOR_EMISSION ); else aspect.SetReflectionModeOff( Graphic3d_TOR_EMISSION ); // shininess - aspect.SetShininess( shininess() ); + aspect.SetShininess( shininess( theIsFront ) ); // transparency aspect.SetTransparency( transparency() ); @@ -561,9 +610,10 @@ Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect() /*! \brief Construct VTK property from material model + \param theIsFront boolean flag for choosing side \return VTK property with correspondent material properties */ -GEOM_VTKPropertyMaterial* Material_Model::getMaterialVTKProperty() +GEOM_VTKPropertyMaterial* Material_Model::getMaterialVTKProperty( bool theIsFront ) { // NOTE: In VTK it's impossible to switch on/off specific reflection type // NOTE: In VTK emissive reflection type is not supported @@ -579,25 +629,25 @@ GEOM_VTKPropertyMaterial* Material_Model::getMaterialVTKProperty() if ( color( Ambient ).isValid() && hasReflection( Ambient ) ) { c = color( Ambient ); prop->SetAmbientColor( c.redF(), c.greenF(), c.blueF() ); - prop->SetAmbient( reflection( Ambient ) ); + prop->SetAmbient( reflection( Ambient, theIsFront ) ); } // diffuse reflection if ( color( Diffuse ).isValid() && hasReflection( Diffuse ) ) { c = color( Diffuse ); prop->SetDiffuseColor( c.redF(), c.greenF(), c.blueF() ); - prop->SetDiffuse( reflection( Diffuse ) ); + prop->SetDiffuse( reflection( Diffuse, theIsFront ) ); } // specular reflection if ( color( Specular ).isValid() && hasReflection( Specular ) ) { c = color( Specular ); prop->SetSpecularColor( c.redF(), c.greenF(), c.blueF() ); - prop->SetSpecular( reflection( Specular ) ); + prop->SetSpecular( reflection( Specular, theIsFront ) ); } // shininess - prop->SetSpecularPower( shininess()*100.0 ); + prop->SetSpecularPower( shininess( theIsFront )*100.0 ); // transparency prop->SetOpacity( 1 - transparency() ); diff --git a/src/Material/Material_Model.h b/src/Material/Material_Model.h index 3f3c8ff24..d27ad1236 100644 --- a/src/Material/Material_Model.h +++ b/src/Material/Material_Model.h @@ -32,7 +32,7 @@ #include -class QtxResourceMgr; +class Material_ResourceMgr; class GEOM_VTKPropertyMaterial; class MATERIAL_SALOME_EXPORT Material_Model @@ -51,8 +51,8 @@ public: void fromProperties( const QString& ); QString toProperties(); - void fromResources( const QString& = QString(), QtxResourceMgr* = 0 ); - void toResources( const QString&, QtxResourceMgr* ); + void fromResources( const QString& = QString(), Material_ResourceMgr* = 0 ); + void toResources( const QString&, Material_ResourceMgr* ); bool isPhysical() const; void setPhysical( bool ); @@ -63,32 +63,35 @@ public: QColor color( ReflectionType ) const; void setColor( ReflectionType, const QColor& ); - double reflection( ReflectionType ) const; - void setReflection( ReflectionType, double ); + double reflection( ReflectionType, bool = true ) const; + void setReflection( ReflectionType, double, bool = true ); - double shininess() const; - void setShininess( double ); + double shininess( bool = true) const; + void setShininess( double, bool = true ); double transparency() const; void setTransparency( double ); - Graphic3d_MaterialAspect getMaterialOCCAspect(); - GEOM_VTKPropertyMaterial* getMaterialVTKProperty(); + Graphic3d_MaterialAspect getMaterialOCCAspect( bool = true ); + GEOM_VTKPropertyMaterial* getMaterialVTKProperty( bool = true ); private: void init(); + void read( const QString&, Material_ResourceMgr* ); private: typedef struct { QColor color; - double coef; + double front_coef; + double back_coef; bool enabled; } ReflectionData; typedef QVector ReflectionList; bool myIsPhysical; - double myShininess; + double myFrontShininess; + double myBackShininess; double myTransparency; ReflectionList myReflection; }; diff --git a/src/Material/Material_ResourceMgr.cxx b/src/Material/Material_ResourceMgr.cxx index 97853f532..eef31d76d 100644 --- a/src/Material/Material_ResourceMgr.cxx +++ b/src/Material/Material_ResourceMgr.cxx @@ -22,6 +22,31 @@ #include "Material_ResourceMgr.h" +#include +#include + +/*! + \class Material_ResourceMgr::Updater + \brief Updates the contents of the resource manager as soon as + user materials database file is changed + \internal +*/ +class Material_ResourceMgr::Updater : public QThread +{ +public: + Material_ResourceMgr* myResourceMgr; + Updater( Material_ResourceMgr* resMgr ) : myResourceMgr( resMgr ) + { + start(); + } + void run() + { + QMutexLocker lock( &myResourceMgr->myMutex ); + myResourceMgr->clear(); + myResourceMgr->load(); + } +}; + /*! \class Material_ResourceMgr \brief Material properties resources manager. @@ -41,7 +66,8 @@ \brief Constructor */ Material_ResourceMgr::Material_ResourceMgr() - : QtxResourceMgr( "SalomeMaterial", "%1Config" ) + : QtxResourceMgr( "SalomeMaterial", "%1Config" ), + myWatcher( 0 ) { if ( dirList().isEmpty() && ::getenv( "GEOM_ROOT_DIR" ) ) setDirList( QStringList() << Qtx::addSlash( ::getenv( "GEOM_ROOT_DIR" ) ) + "share/salome/resources/geom" ); @@ -53,6 +79,24 @@ Material_ResourceMgr::Material_ResourceMgr() */ Material_ResourceMgr::~Material_ResourceMgr() { + watchUserFile( false ); +} + +/*! + \brief Get shared instance of resources manager + + This instance of resource manager is global for the application; + it watches for changes in the user materials database file to + maintain the fresh version of the materials data. +*/ +Material_ResourceMgr* Material_ResourceMgr::resourceMgr() +{ + static Material_ResourceMgr* resMgr = 0; + if ( !resMgr ) { + resMgr = new Material_ResourceMgr(); + resMgr->watchUserFile( true ); + } + return resMgr; } /*! @@ -63,6 +107,8 @@ Material_ResourceMgr::~Material_ResourceMgr() */ QStringList Material_ResourceMgr::materials( MaterialType theType, bool theSort ) { + QMutexLocker lock( &myMutex ); + // store original working mode WorkingMode m = workingMode(); @@ -114,3 +160,34 @@ QStringList Material_ResourceMgr::materials( MaterialType theType, bool theSort return result; } + +/*! + \brief Start/stop this resource manager watching the user materials database file. + \internal +*/ +void Material_ResourceMgr::watchUserFile( bool on ) +{ + if ( on ) { + if ( !myWatcher ) { + myWatcher = new QFileSystemWatcher( this ); + myWatcher->addPath( userFileName( appName() ) ); + connect( myWatcher, SIGNAL( fileChanged( QString ) ), this, SLOT( update() ) ); + } + } + else { + if ( myWatcher ) { + delete myWatcher; + myWatcher = 0; + } + } +} + +/*! + \brief Update user database slot + \internal +*/ +void Material_ResourceMgr::update() +{ + Updater( this ).wait(); + emit changed(); +} diff --git a/src/Material/Material_ResourceMgr.h b/src/Material/Material_ResourceMgr.h index a98a531d7..de71b1028 100644 --- a/src/Material/Material_ResourceMgr.h +++ b/src/Material/Material_ResourceMgr.h @@ -25,10 +25,18 @@ #include "Material.h" +#include +#include #include -class MATERIAL_SALOME_EXPORT Material_ResourceMgr : public QtxResourceMgr +class QFileSystemWatcher; + +class MATERIAL_SALOME_EXPORT Material_ResourceMgr : public QObject, public QtxResourceMgr { + Q_OBJECT; + + class Updater; + public: //! Material type typedef enum { @@ -40,8 +48,24 @@ public: Material_ResourceMgr(); ~Material_ResourceMgr(); + static Material_ResourceMgr* resourceMgr(); + QStringList materials( MaterialType = All, bool = true ); - + +signals: + void changed(); + +private: + void watchUserFile( bool ); + +private slots: + void update(); + +private: + QFileSystemWatcher* myWatcher; + QMutex myMutex; + + friend class Material_Model; }; #endif // MATERIAL_RESOURCEMGR_H diff --git a/src/Material/resources/SalomeMaterial.xml b/src/Material/resources/SalomeMaterial.xml index d1e26882c..6cdcb94a5 100644 --- a/src/Material/resources/SalomeMaterial.xml +++ b/src/Material/resources/SalomeMaterial.xml @@ -23,196 +23,279 @@ -->

    - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + +
    - - - - + + + + + + + +
    - - - - + + + + + + + +
    - - - - + + + + + + + +
    - - - - - - - + + + + + + + + + + + +
    - - - - - + + + + + + + + +
    - - - - - - - - + + + + + + + + + + + +
    - - - - - - - - + + + + + + + + + + + +
    - - - - - - - - + + + + + + + + + + + +
    - - - - - - - - + + + + + + + + + + + +
    - - - - - - - - + + + + + + + + + + + +
    - - - - - - - + + + + + + + + + + +
    - - - - - - - - + + + + + + + + + + + +
    - - - - - - + + + + + + + + + +
    - - - - - - - - + + + + + + + + + + + +
    - - - - - - - - + + + + + + + + + + + +
    - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + +
    - - - - - - - - + + + + + + + + + + + +
    - - - - - - - - + + + + + + + + + + + +
    - - - - - - - - + + + + + + + + + + + +
    diff --git a/src/MeasureGUI/Makefile.am b/src/MeasureGUI/Makefile.am index 55cfcf7a5..c739ca76b 100644 --- a/src/MeasureGUI/Makefile.am +++ b/src/MeasureGUI/Makefile.am @@ -15,7 +15,6 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# # GEOM MEASUREGUI : # File : Makefile.am @@ -95,7 +94,6 @@ UIC_FILES = \ ui_MeasureGUI_1Sel3LineEdit_QTD.h \ ui_MeasureGUI_1Sel6LineEdit_QTD.h \ ui_MeasureGUI_2Sel1LineEdit_QTD.h \ - ui_MeasureGUI_2Sel4LineEdit_QTD.h \ ui_MeasureGUI_SkeletonBox_QTD.h BUILT_SOURCES = $(UIC_FILES) diff --git a/src/MeasureGUI/MeasureGUI_2Sel4LineEdit_QTD.ui b/src/MeasureGUI/MeasureGUI_2Sel4LineEdit_QTD.ui deleted file mode 100644 index d63fb5ab9..000000000 --- a/src/MeasureGUI/MeasureGUI_2Sel4LineEdit_QTD.ui +++ /dev/null @@ -1,189 +0,0 @@ - - MeasureGUI_2Sel4LineEdit_QTD - - - - 0 - 0 - 198 - 197 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - 0 - 0 - - - - TL1 - - - false - - - - - - - - 0 - 0 - - - - - - - - - 100 - 0 - - - - - - - - - 0 - 0 - - - - TL2 - - - false - - - - - - - - 0 - 0 - - - - - - - - - 100 - 0 - - - - - - - - - 0 - 0 - - - - TL3 - - - false - - - - - - - - - - - 0 - 0 - - - - TL4 - - - false - - - - - - - - - - - 0 - 0 - - - - TL5 - - - false - - - - - - - - - - - 0 - 0 - - - - TL6 - - - false - - - - - - - - - - - - - - diff --git a/src/MeasureGUI/MeasureGUI_BndBoxDlg.cxx b/src/MeasureGUI/MeasureGUI_BndBoxDlg.cxx index d3eb0603a..790c0a41c 100644 --- a/src/MeasureGUI/MeasureGUI_BndBoxDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_BndBoxDlg.cxx @@ -35,6 +35,10 @@ #include #include +#include +#include +#include +#include //================================================================================= // class : MeasureGUI_BndBoxDlg() @@ -44,21 +48,23 @@ // true to construct a modal dialog. //================================================================================= MeasureGUI_BndBoxDlg::MeasureGUI_BndBoxDlg (GeometryGUI* GUI, QWidget* parent) - : MeasureGUI_Skeleton(GUI, parent) + : GEOMBase_Skeleton(GUI, parent) { - QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap( - "GEOM", tr( "ICON_DLG_BOUNDING_BOX" ) ) ); - QPixmap image1( SUIT_Session::session()->resourceMgr()->loadPixmap( - "GEOM", tr( "ICON_SELECT" ) ) ); + QPixmap image0 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_BOUNDING_BOX"))); + QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT"))); - setWindowTitle( tr( "GEOM_BNDBOX_TITLE" ) ); + setWindowTitle(tr("GEOM_BNDBOX_TITLE")); /***************************************************************/ - mainFrame()->GroupConstructors->setTitle( tr( "GEOM_BNDBOX" ) ); - mainFrame()->RadioButton1->setIcon( image0 ); + mainFrame()->GroupConstructors->setTitle(tr("GEOM_BNDBOX")); + mainFrame()->RadioButton1->setIcon(image0); + mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose ); + mainFrame()->RadioButton2->close(); + mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose ); + mainFrame()->RadioButton3->close(); - myGrp = new MeasureGUI_1Sel6LineEdit( centralWidget() ); + myGrp = new MeasureGUI_1Sel6LineEdit (centralWidget()); myGrp->GroupBox1->setTitle( tr( "GEOM_BNDBOX_OBJDIM" ) ); myGrp->TextLabel1->setText( tr( "GEOM_OBJECT" ) ); myGrp->TextLabel2->setText( tr( "GEOM_MIN" ) ); @@ -87,7 +93,7 @@ MeasureGUI_BndBoxDlg::MeasureGUI_BndBoxDlg (GeometryGUI* GUI, QWidget* parent) /***************************************************************/ - myHelpFileName = "using_measurement_tools_page.html#bounding_box_anchor"; + myHelpFileName = "bounding_box_page.html"; /* Initialisation */ Init(); @@ -107,9 +113,66 @@ MeasureGUI_BndBoxDlg::~MeasureGUI_BndBoxDlg() //================================================================================= void MeasureGUI_BndBoxDlg::Init() { - mySelBtn = myGrp->PushButton1; - mySelEdit = myGrp->LineEdit1; - MeasureGUI_Skeleton::Init(); + myEditCurrentArgument = myGrp->LineEdit1; + + connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); + connect(myGrp->PushButton1, SIGNAL(clicked()), this, SLOT(SelectionIntoArgument())); + + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + + initName(tr("GEOM_BNDBOX")); + globalSelection(); + SelectionIntoArgument(); +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void MeasureGUI_BndBoxDlg::ClickOnOk() +{ + if (ClickOnApply()) + ClickOnCancel(); +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool MeasureGUI_BndBoxDlg::ClickOnApply() +{ + if (!onAccept()) + return false; + + initName(); + return true; +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void MeasureGUI_BndBoxDlg::ActivateThisDialog() +{ + GEOMBase_Skeleton::ActivateThisDialog(); + + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + + globalSelection(); + redisplayPreview(); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void MeasureGUI_BndBoxDlg::enterEvent(QEvent*) +{ + if (!mainFrame()->GroupConstructors->isEnabled()) + ActivateThisDialog(); } //================================================================================= @@ -121,7 +184,7 @@ void MeasureGUI_BndBoxDlg::processObject() double aXMin, aXMax, aYMin, aYMax, aZMin, aZMax; if (!getParameters(aXMin, aXMax, aYMin, aYMax, aZMin, aZMax)) { - mySelEdit->setText(""); + myEditCurrentArgument->setText(""); myGrp->LineEdit11->setText(""); myGrp->LineEdit12->setText(""); myGrp->LineEdit21->setText(""); @@ -177,3 +240,97 @@ SALOME_Prs* MeasureGUI_BndBoxDlg::buildPrs() return !aShape.IsNull() ? getDisplayer()->BuildPrs(aShape) : 0; } + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection as changed or other case +//================================================================================= +void MeasureGUI_BndBoxDlg::SelectionIntoArgument() +{ + myEditCurrentArgument->setText(""); + myObj = GEOM::GEOM_Object::_nil(); + + LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); + SALOME_ListIO aSelList; + aSelMgr->selectedObjects(aSelList); + + if (aSelList.Extent() != 1) { + processObject(); + erasePreview(); + return; + } + + GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject(aSelList.First()); + + if (aSelectedObject->_is_nil()) { + processObject(); + erasePreview(); + return; + } + + myObj = aSelectedObject; + myEditCurrentArgument->setText(GEOMBase::GetName(myObj)); + processObject(); + redisplayPreview(); +} + +//================================================================================= +// function : createOperation +// purpose : +//================================================================================= +GEOM::GEOM_IOperations_ptr MeasureGUI_BndBoxDlg::createOperation() +{ + return getGeomEngine()->GetIMeasureOperations(getStudyId()); +} + +//================================================================================= +// function : isValid +// purpose : +//================================================================================= +bool MeasureGUI_BndBoxDlg::isValid (QString&) +{ + return !myObj->_is_nil(); +} + +//================================================================================= +// function : execute +// purpose : +//================================================================================= +bool MeasureGUI_BndBoxDlg::execute (ObjectList& objects) +{ + GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow(getOperation()); + GEOM::GEOM_Object_var anObj = anOper->MakeBoundingBox(myObj); + + if (!anObj->_is_nil()) + objects.push_back(anObj._retn()); + + return true; +} + +//================================================================================= +// function : redisplayPreview() +// purpose : +//================================================================================= +void MeasureGUI_BndBoxDlg::redisplayPreview() +{ + QString aMess; + if (!isValid(aMess)) { + erasePreview(true); + return; + } + + erasePreview(false); + + try { + SUIT_OverrideCursor(); + + getDisplayer()->SetColor(Quantity_NOC_VIOLET); + getDisplayer()->SetToActivate(false); + + if (SALOME_Prs* aPrs = buildPrs()) + displayPreview(aPrs); + } + catch (const SALOME::SALOME_Exception& e) { + SalomeApp_Tools::QtCatchCorbaException(e); + } +} diff --git a/src/MeasureGUI/MeasureGUI_BndBoxDlg.h b/src/MeasureGUI/MeasureGUI_BndBoxDlg.h index 8fd3af034..e2c5367f8 100644 --- a/src/MeasureGUI/MeasureGUI_BndBoxDlg.h +++ b/src/MeasureGUI/MeasureGUI_BndBoxDlg.h @@ -18,16 +18,15 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : MeasureGUI_BndBoxDlg.h // Author : Nicolas REJNERI, Open CASCADE S.A.S. -// + #ifndef MEASUREGUI_BNDBOXDLG_H #define MEASUREGUI_BNDBOXDLG_H -#include "MeasureGUI_Skeleton.h" +#include "GEOMBase_Skeleton.h" class MeasureGUI_1Sel6LineEdit; @@ -35,27 +34,38 @@ class MeasureGUI_1Sel6LineEdit; // class : DialogBox_PROPERTIES // purpose : //================================================================================= -class MeasureGUI_BndBoxDlg : public MeasureGUI_Skeleton +class MeasureGUI_BndBoxDlg : public GEOMBase_Skeleton { Q_OBJECT public: - MeasureGUI_BndBoxDlg( GeometryGUI*, QWidget* ); + MeasureGUI_BndBoxDlg (GeometryGUI*, QWidget*); ~MeasureGUI_BndBoxDlg(); protected: - // redefined from GEOMBase_Helper and MeasureGUI_Skeleton - virtual void processObject(); - virtual SALOME_Prs* buildPrs(); + // redefined from GEOMBase_Helper + virtual GEOM::GEOM_IOperations_ptr createOperation(); + virtual bool isValid (QString&); + virtual bool execute (ObjectList&); + + void redisplayPreview(); + virtual void processObject(); + virtual SALOME_Prs* buildPrs(); private: - void Init(); - bool getParameters( double&, double&, - double&, double&, - double&, double& ); + void Init(); + void enterEvent (QEvent*); + bool getParameters (double&, double&, double&, double&, double&, double&); private: - MeasureGUI_1Sel6LineEdit* myGrp; + GEOM::GEOM_Object_var myObj; + MeasureGUI_1Sel6LineEdit* myGrp; + +private slots: + void ClickOnOk(); + bool ClickOnApply(); + void SelectionIntoArgument(); + void ActivateThisDialog(); }; #endif // MEASUREGUI_BNDBOXDLG_H diff --git a/src/MeasureGUI/MeasureGUI_DistanceDlg.cxx b/src/MeasureGUI/MeasureGUI_DistanceDlg.cxx index ffd630a9a..a49f2789d 100644 --- a/src/MeasureGUI/MeasureGUI_DistanceDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_DistanceDlg.cxx @@ -18,12 +18,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : MeasureGUI_DistanceDlg.cxx // Author : Nicolas REJNERI, Open CASCADE S.A.S. -// + #include "MeasureGUI_DistanceDlg.h" #include "MeasureGUI_Widgets.h" @@ -36,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -61,7 +61,7 @@ // true to construct a modal dialog. //================================================================================= MeasureGUI_DistanceDlg::MeasureGUI_DistanceDlg (GeometryGUI* GUI, QWidget* parent) - : MeasureGUI_Skeleton(GUI, parent) + : GEOMBase_Skeleton(GUI, parent) { SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_MINDIST"))); @@ -72,30 +72,39 @@ MeasureGUI_DistanceDlg::MeasureGUI_DistanceDlg (GeometryGUI* GUI, QWidget* paren /***************************************************************/ mainFrame()->GroupConstructors->setTitle(tr("GEOM_DISTANCE")); mainFrame()->RadioButton1->setIcon(image0); + mainFrame()->RadioButton2->setAttribute(Qt::WA_DeleteOnClose); + mainFrame()->RadioButton2->close(); + mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose); + mainFrame()->RadioButton3->close(); - myGrp = new MeasureGUI_2Sel4LineEdit(centralWidget()); + mainFrame()->GroupBoxName->hide(); + + myGrp = new MeasureGUI_DistanceGroup (centralWidget()); myGrp->GroupBox1->setTitle(tr("GEOM_MINDIST_OBJ")); + + // Arguments myGrp->TextLabel1->setText(tr("GEOM_OBJECT_I").arg("1")); myGrp->TextLabel2->setText(tr("GEOM_OBJECT_I").arg("2")); + myGrp->PushButton1->setIcon(image1); + myGrp->PushButton2->setIcon(image1); + myGrp->LineEdit1->setReadOnly(true); + myGrp->LineEdit2->setReadOnly(true); + + // Solutions combobox + myGrp->TextLabel7->setText(tr("GEOM_SOLUTION")); + + // Distance, dx, dy and dz myGrp->TextLabel3->setText(tr("GEOM_LENGTH")); myGrp->TextLabel4->setText(tr("GEOM_DX")); myGrp->TextLabel5->setText(tr("GEOM_DY")); myGrp->TextLabel6->setText(tr("GEOM_DZ")); myGrp->LineEdit3->setReadOnly(true); - myGrp->PushButton1->setIcon(image1); - myGrp->PushButton2->setIcon(image1); - myGrp->LineEdit1->setReadOnly(true); - myGrp->LineEdit2->setReadOnly(true); myGrp->LineEdit4->setReadOnly(true); myGrp->LineEdit5->setReadOnly(true); myGrp->LineEdit6->setReadOnly(true); - - QVBoxLayout* layout = new QVBoxLayout(centralWidget()); - layout->setMargin(0); layout->setSpacing(6); - layout->addWidget(myGrp); /***************************************************************/ - myHelpFileName = "using_measurement_tools_page.html#min_distance_anchor"; + myHelpFileName = "min_distance_page.html"; // Initialisation Init(); @@ -115,120 +124,139 @@ MeasureGUI_DistanceDlg::~MeasureGUI_DistanceDlg() //================================================================================= void MeasureGUI_DistanceDlg::Init() { - // init variables - myGrp->LineEdit1->setText(""); - myGrp->LineEdit2->setText(""); - myObj = myObj2 = GEOM::GEOM_Object::_nil(); - - mySelBtn = myGrp->PushButton1; - mySelEdit = myGrp->LineEdit1; - myEditCurrentArgument = myGrp->LineEdit1; + myDbls = new GEOM::ListOfDouble(); // signals and slots connections - connect(myGrp->LineEdit2, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed())); + connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); + + connect(myGrp->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); connect(myGrp->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); - MeasureGUI_Skeleton::Init(); + connect(myGrp->ComboBox1, SIGNAL(currentIndexChanged(int)), this, SLOT(SolutionSelected(int))); + + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + + globalSelection(); + SelectionIntoArgument(); } //================================================================================= -// function : SelectionIntoArgument() -// purpose : Called when selection has changed +// function : ClickOnOk() +// purpose : //================================================================================= -void MeasureGUI_DistanceDlg::SelectionIntoArgument() +void MeasureGUI_DistanceDlg::ClickOnOk() { - LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); - SALOME_ListIO aSelList; - aSelMgr->selectedObjects(aSelList); + if (ClickOnApply()) + ClickOnCancel(); +} - GEOM::GEOM_Object_var aSelectedObject = GEOM::GEOM_Object::_nil(); +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool MeasureGUI_DistanceDlg::ClickOnApply() +{ + if (!onAccept()) + return false; - if (aSelList.Extent() > 0) { - aSelectedObject = GEOMBase::ConvertIOinGEOMObject( aSelList.First() ); - } + initName(); + return true; +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void MeasureGUI_DistanceDlg::ActivateThisDialog() +{ + GEOMBase_Skeleton::ActivateThisDialog(); - // clear selection - disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); - myGeomGUI->getApp()->selectionMgr()->clearSelected(); connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); - if (myEditCurrentArgument == myGrp->LineEdit1) { - myObj = aSelectedObject; - if (!myObj->_is_nil() && myObj2->_is_nil()) - myGrp->PushButton2->click(); - } - else { - myObj2 = aSelectedObject; - if (!myObj2->_is_nil() && myObj->_is_nil()) - myGrp->PushButton1->click(); - } - - processObject(); + globalSelection(); + redisplayPreview(); } //================================================================================= -// function : processObject() -// purpose : Fill dialogs fields in accordance with myObj and myObj2 +// function : enterEvent() +// purpose : //================================================================================= -void MeasureGUI_DistanceDlg::processObject() +void MeasureGUI_DistanceDlg::enterEvent(QEvent*) { - myGrp->LineEdit1->setText(!myObj->_is_nil() ? GEOMBase::GetName(myObj ) : ""); - myGrp->LineEdit2->setText(!myObj2->_is_nil() ? GEOMBase::GetName(myObj2) : ""); - - gp_Pnt aPnt1, aPnt2; - double aDist = 0.; - if (getParameters(aDist, aPnt1, aPnt2)) { - SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); - int aPrecision = resMgr->integerValue( "Geometry", "length_precision", 6 ); - - myGrp->LineEdit3->setText(DlgRef::PrintDoubleValue(aDist, aPrecision)); - - gp_XYZ aVec = aPnt2.XYZ() - aPnt1.XYZ(); - myGrp->LineEdit4->setText(DlgRef::PrintDoubleValue(aVec.X(), aPrecision)); - myGrp->LineEdit5->setText(DlgRef::PrintDoubleValue(aVec.Y(), aPrecision)); - myGrp->LineEdit6->setText(DlgRef::PrintDoubleValue(aVec.Z(), aPrecision)); + if (!mainFrame()->GroupConstructors->isEnabled()) + ActivateThisDialog(); +} - redisplayPreview(); - } - else { +//================================================================================= +// function : SolutionSelected() +// purpose : Called when ComboBox selection has changed +//================================================================================= +void MeasureGUI_DistanceDlg::SolutionSelected (int i) +{ + if (i < 0 || myDbls->length() < (i+1)*6) { myGrp->LineEdit3->setText(""); myGrp->LineEdit4->setText(""); myGrp->LineEdit5->setText(""); myGrp->LineEdit6->setText(""); erasePreview(); + return; } + + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + int aPrecision = resMgr->integerValue( "Geometry", "length_precision", 6 ); + + gp_Pnt p1 (myDbls[i*6 + 0], myDbls[i*6 + 1], myDbls[i*6 + 2]); + gp_Pnt p2 (myDbls[i*6 + 3], myDbls[i*6 + 4], myDbls[i*6 + 5]); + + double aDist = p1.Distance(p2); + myGrp->LineEdit3->setText(DlgRef::PrintDoubleValue(aDist, aPrecision)); + + gp_XYZ aVec = p2.XYZ() - p1.XYZ(); + myGrp->LineEdit4->setText(DlgRef::PrintDoubleValue(aVec.X(), aPrecision)); + myGrp->LineEdit5->setText(DlgRef::PrintDoubleValue(aVec.Y(), aPrecision)); + myGrp->LineEdit6->setText(DlgRef::PrintDoubleValue(aVec.Z(), aPrecision)); + + redisplayPreview(); } //================================================================================= -// function : getParameters() -// purpose : Get distance between objects +// function : SelectionIntoArgument() +// purpose : Called when selection has changed //================================================================================= -bool MeasureGUI_DistanceDlg::getParameters (double& theDistance, - gp_Pnt& thePnt1, - gp_Pnt& thePnt2) +void MeasureGUI_DistanceDlg::SelectionIntoArgument() { - QString msg; - if (isValid(msg)) { - GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow( getOperation() ); + LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); + SALOME_ListIO aSelList; + aSelMgr->selectedObjects(aSelList); - try { - double x1, y1, z1, x2, y2, z2; - theDistance = anOper->GetMinDistance(myObj, myObj2, x1, y1, z1, x2, y2, z2); + GEOM::GEOM_Object_var aSelectedObject = GEOM::GEOM_Object::_nil(); - thePnt1.SetCoord(x1, y1, z1); - thePnt2.SetCoord(x2, y2, z2); - } - catch(const SALOME::SALOME_Exception& e) { - SalomeApp_Tools::QtCatchCorbaException(e); - return false; - } + if (aSelList.Extent() > 0) { + aSelectedObject = GEOMBase::ConvertIOinGEOMObject(aSelList.First()); + } - return anOper->IsDone(); + // clear selection + disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); + myGeomGUI->getApp()->selectionMgr()->clearSelected(); + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + + if (myEditCurrentArgument == myGrp->LineEdit1) { + myObj1 = aSelectedObject; + if (!myObj1->_is_nil() && myObj2->_is_nil()) + myGrp->PushButton2->click(); + } + else { + myObj2 = aSelectedObject; + if (!myObj2->_is_nil() && myObj1->_is_nil()) + myGrp->PushButton1->click(); } - return false; + processObject(); } //================================================================================= @@ -263,22 +291,41 @@ void MeasureGUI_DistanceDlg::SetEditCurrentArgument() } //================================================================================= -// function : LineEditReturnPressed() -// purpose : +// function : processObject() +// purpose : Fill dialogs fields in accordance with myObj1 and myObj2 //================================================================================= -void MeasureGUI_DistanceDlg::LineEditReturnPressed() +void MeasureGUI_DistanceDlg::processObject() { - QLineEdit* send = (QLineEdit*)sender(); + myGrp->LineEdit1->setText(!myObj1->_is_nil() ? GEOMBase::GetName(myObj1) : ""); + myGrp->LineEdit2->setText(!myObj2->_is_nil() ? GEOMBase::GetName(myObj2) : ""); + + myGrp->ComboBox1->clear(); + myDbls->length(0); + erasePreview(); - if (send == myGrp->LineEdit1 || send == myGrp->LineEdit2) { - myEditCurrentArgument = send; + int nbSols = 0; + + QString msg; + if (!isValid(msg)) return; - LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); - SALOME_ListIO aSelList; - aSelMgr->selectedObjects(aSelList); + GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow(getOperation()); + try { + nbSols = anOper->ClosestPoints(myObj1, myObj2, myDbls); + } + catch (const SALOME::SALOME_Exception& e) { + SalomeApp_Tools::QtCatchCorbaException(e); + return; + } - if (GEOMBase::SelectionByNameInDialogs(this, myGrp->LineEdit1->text(), aSelList)) - myGrp->LineEdit1->setText(myGrp->LineEdit1->text()); + if (!anOper->IsDone()) + myGrp->ComboBox1->addItem(tr(anOper->GetErrorCode())); + else if (nbSols <= 0) + myGrp->ComboBox1->addItem(tr("GEOM_MINDIST_NO_SOL")); + else { + for (int i = 0; i < nbSols; i++) { + myGrp->ComboBox1->addItem(tr("GEOM_SOLUTION_I").arg(i + 1)); + } + myGrp->ComboBox1->setCurrentIndex(0); } } @@ -288,47 +335,52 @@ void MeasureGUI_DistanceDlg::LineEditReturnPressed() //================================================================================= SALOME_Prs* MeasureGUI_DistanceDlg::buildPrs() { - double aDist = 0.; - gp_Pnt aPnt1(0, 0, 0), aPnt2(0, 0, 0); - SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow(); - if (myObj->_is_nil() || myObj2->_is_nil() || - !getParameters(aDist, aPnt1, aPnt2) || - vw->getViewManager()->getType() != OCCViewer_Viewer::Type()) + int currSol = myGrp->ComboBox1->currentIndex(); + + if (myObj1->_is_nil() || myObj2->_is_nil() || + currSol == -1 || (currSol+1)*6 > myDbls->length() || + vw->getViewManager()->getType() != OCCViewer_Viewer::Type()) return 0; + gp_Pnt aPnt1 (myDbls[currSol*6 + 0], myDbls[currSol*6 + 1], myDbls[currSol*6 + 2]); + gp_Pnt aPnt2 (myDbls[currSol*6 + 3], myDbls[currSol*6 + 4], myDbls[currSol*6 + 5]); + + double aDist = aPnt1.Distance(aPnt2); + try { if (aDist <= 1.e-9) { - BRepBuilderAPI_MakeVertex aMaker(aPnt1); + BRepBuilderAPI_MakeVertex aMaker (aPnt1); return getDisplayer()->BuildPrs(aMaker.Vertex()); } else { - BRepBuilderAPI_MakeEdge MakeEdge(aPnt1, aPnt2); + BRepBuilderAPI_MakeEdge MakeEdge (aPnt1, aPnt2); TopoDS_Vertex aVert1 = BRepBuilderAPI_MakeVertex(aPnt1); TopoDS_Vertex aVert2 = BRepBuilderAPI_MakeVertex(aPnt2); QString aLabel; aLabel.sprintf("%.1f", aDist); - gp_Pnt aPnt3((aPnt1.X() + aPnt2.X()) / 2, + gp_Pnt aPnt3 ((aPnt1.X() + aPnt2.X()) / 2, (aPnt1.Y() + aPnt2.Y()) / 2, (aPnt1.Z() + aPnt2.Z()) / 2); - gp_Vec va(aPnt3, aPnt1); - gp_Vec vb(aPnt3, aPnt2); + gp_Vec va (aPnt3, aPnt1); + gp_Vec vb (aPnt3, aPnt2); if (va.IsParallel(vb, Precision::Angular())) { aPnt3.SetY((aPnt1.Y() + aPnt2.Y()) / 2 + 100); aPnt3.SetZ((aPnt1.Z() + aPnt2.Z()) / 2); } - gce_MakePln gce_MP(aPnt1, aPnt2, aPnt3); - Handle(Geom_Plane) P = new Geom_Plane(gce_MP.Value()); + gce_MakePln gce_MP (aPnt1, aPnt2, aPnt3); + Handle(Geom_Plane) P = new Geom_Plane (gce_MP.Value()); - Handle(AIS_LengthDimension) anIO = new AIS_LengthDimension( - aVert1, aVert2, P, aDist, TCollection_ExtendedString((Standard_CString)aLabel.toLatin1().constData())); + Handle(AIS_LengthDimension) anIO = new AIS_LengthDimension + (aVert1, aVert2, P, aDist, + TCollection_ExtendedString((Standard_CString)aLabel.toLatin1().constData())); anIO->SetArrowSize(aDist/20); SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); @@ -345,16 +397,172 @@ SALOME_Prs* MeasureGUI_DistanceDlg::buildPrs() return aPrs; } } - catch(Standard_Failure) { + catch (Standard_Failure) { return 0; } } +//================================================================================= +// function : createOperation +// purpose : +//================================================================================= +GEOM::GEOM_IOperations_ptr MeasureGUI_DistanceDlg::createOperation() +{ + return getGeomEngine()->GetIMeasureOperations(getStudyId()); +} + //================================================================================= // function : isValid() // purpose : //================================================================================= bool MeasureGUI_DistanceDlg::isValid (QString& msg) { - return MeasureGUI_Skeleton::isValid(msg) && !myObj2->_is_nil(); + return !myObj1->_is_nil() && !myObj2->_is_nil(); +} + +//================================================================================= +// function : execute +// purpose : +//================================================================================= +bool MeasureGUI_DistanceDlg::execute (ObjectList& objects) +{ + GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow(getOperation()); + GEOM::GEOM_IBasicOperations_var aBasicOper = getGeomEngine()->GetIBasicOperations(getStudyId()); + + GEOM::ListOfDouble_var aDbls; + int nbSols = anOper->ClosestPoints(myObj1, myObj2, aDbls); + + if (anOper->IsDone()) { + for (int i = 0; i < nbSols; i++) { + GEOM::GEOM_Object_var anObj1 = aBasicOper->MakePointXYZ(aDbls[i*6 + 0], aDbls[i*6 + 1], aDbls[i*6 + 2]); + GEOM::GEOM_Object_var anObj2 = aBasicOper->MakePointXYZ(aDbls[i*6 + 3], aDbls[i*6 + 4], aDbls[i*6 + 5]); + + if (!anObj1->_is_nil() && !anObj2->_is_nil()) { + objects.push_back(anObj1._retn()); + objects.push_back(anObj2._retn()); + } + } + } + + return true; +} + +//================================================================================= +// function : redisplayPreview() +// purpose : +//================================================================================= +void MeasureGUI_DistanceDlg::redisplayPreview() +{ + QString aMess; + if (!isValid(aMess)) { + erasePreview(true); + return; + } + + erasePreview(false); + + try { + SUIT_OverrideCursor(); + + getDisplayer()->SetColor(Quantity_NOC_VIOLET); + getDisplayer()->SetToActivate(false); + + if (SALOME_Prs* aPrs = buildPrs()) + displayPreview(aPrs); + } + catch (const SALOME::SALOME_Exception& e) { + SalomeApp_Tools::QtCatchCorbaException(e); + } +} + +//================================================================ +// Function : getNewObjectName +// Purpose : Redefine this method to return proper name for a new object +//================================================================ +QString MeasureGUI_DistanceDlg::getNewObjectName (int currObj) const +{ + QString aName = tr("GEOM_MINDIST_NAME") + QString("_%1_").arg((currObj+1)/2); + aName += GEOMBase::GetName(currObj%2 ? myObj1 : myObj2); + + return aName; +} + +//================================================================================= +// function : MeasureGUI_DistanceGroup +// purpose : +//================================================================================= +MeasureGUI_DistanceGroup::MeasureGUI_DistanceGroup (QWidget *parent) +{ + gridLayout = new QGridLayout (parent); + gridLayout->setSpacing(6); + gridLayout->setContentsMargins(11, 11, 11, 11); + gridLayout->setHorizontalSpacing(0); + gridLayout->setVerticalSpacing(0); + gridLayout->setContentsMargins(0, 0, 0, 0); + + GroupBox1 = new QGroupBox (parent); + + gridLayout1 = new QGridLayout (GroupBox1); + gridLayout1->setSpacing(6); + gridLayout1->setContentsMargins(11, 11, 11, 11); + gridLayout1->setHorizontalSpacing(6); + gridLayout1->setVerticalSpacing(6); + gridLayout1->setContentsMargins(9, 9, 9, 9); + + // 2Sel + TextLabel1 = new QLabel(GroupBox1); + TextLabel2 = new QLabel(GroupBox1); + + PushButton1 = new QPushButton (GroupBox1); + PushButton2 = new QPushButton (GroupBox1); + + LineEdit1 = new QLineEdit(GroupBox1); + LineEdit2 = new QLineEdit(GroupBox1); + + gridLayout1->addWidget(TextLabel1, 0, 0, 1, 1); + gridLayout1->addWidget(TextLabel2, 1, 0, 1, 1); + gridLayout1->addWidget(PushButton1, 0, 1, 1, 1); + gridLayout1->addWidget(PushButton2, 1, 1, 1, 1); + gridLayout1->addWidget(LineEdit1, 0, 2, 1, 1); + gridLayout1->addWidget(LineEdit2, 1, 2, 1, 1); + + // 1Combo + TextLabel7 = new QLabel (GroupBox1); + + ComboBox1 = new QComboBox (GroupBox1); + + gridLayout1->addWidget(TextLabel7, 2, 0, 1, 1); + gridLayout1->addWidget(ComboBox1, 2, 1, 1, 2); + + // 4Text + TextLabel3 = new QLabel (GroupBox1); + TextLabel4 = new QLabel (GroupBox1); + TextLabel5 = new QLabel (GroupBox1); + TextLabel6 = new QLabel (GroupBox1); + + LineEdit3 = new QLineEdit(GroupBox1); + LineEdit4 = new QLineEdit(GroupBox1); + LineEdit5 = new QLineEdit(GroupBox1); + LineEdit6 = new QLineEdit(GroupBox1); + + gridLayout1->addWidget(TextLabel3, 3, 0, 1, 1); + gridLayout1->addWidget(TextLabel4, 4, 0, 1, 1); + gridLayout1->addWidget(TextLabel5, 5, 0, 1, 1); + gridLayout1->addWidget(TextLabel6, 6, 0, 1, 1); + + gridLayout1->addWidget(LineEdit3, 3, 1, 1, 2); + gridLayout1->addWidget(LineEdit4, 4, 1, 1, 2); + gridLayout1->addWidget(LineEdit5, 5, 1, 1, 2); + gridLayout1->addWidget(LineEdit6, 6, 1, 1, 2); + + gridLayout->addWidget(GroupBox1, 0, 0, 1, 1); +} + +//================================================================================= +// function : ~MeasureGUI_DistanceGroup() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +MeasureGUI_DistanceGroup::~MeasureGUI_DistanceGroup() +{ + // no need to delete child widgets, Qt does it all for us } diff --git a/src/MeasureGUI/MeasureGUI_DistanceDlg.h b/src/MeasureGUI/MeasureGUI_DistanceDlg.h index 2c4e9c56d..9f4c7992c 100644 --- a/src/MeasureGUI/MeasureGUI_DistanceDlg.h +++ b/src/MeasureGUI/MeasureGUI_DistanceDlg.h @@ -18,54 +18,110 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : MeasureGUI_DistanceDlg.h // Author : Nicolas REJNERI, Open CASCADE S.A.S. -// + #ifndef MEASUREGUI_DISTANCEDLG_H #define MEASUREGUI_DISTANCEDLG_H -#include "MeasureGUI_Skeleton.h" +#include + +// IDL Headers +#include +#include CORBA_SERVER_HEADER(GEOM_Gen) + +#include +#include +#include +#include +#include +#include -class MeasureGUI_2Sel4LineEdit; class gp_Pnt; //================================================================================= -// class : MeasureGUI_DistanceDlg +// class : MeasureGUI_DistanceGroup // purpose : //================================================================================= +class MeasureGUI_DistanceGroup : public QWidget +{ + Q_OBJECT + + public: + MeasureGUI_DistanceGroup (QWidget *parent); + ~MeasureGUI_DistanceGroup(); + + public: + QGridLayout *gridLayout; + QGroupBox *GroupBox1; + QGridLayout *gridLayout1; + + // 2Sel + QLabel *TextLabel1; + QLabel *TextLabel2; + QPushButton *PushButton1; + QPushButton *PushButton2; + QLineEdit *LineEdit1; + QLineEdit *LineEdit2; + + // 1Combo + QLabel *TextLabel7; + QComboBox *ComboBox1; -class MeasureGUI_DistanceDlg : public MeasureGUI_Skeleton -{ + // 4Text + QLabel *TextLabel3; + QLabel *TextLabel4; + QLabel *TextLabel5; + QLabel *TextLabel6; + QLineEdit *LineEdit3; + QLineEdit *LineEdit4; + QLineEdit *LineEdit5; + QLineEdit *LineEdit6; +}; + +//================================================================================= +// class : MeasureGUI_DistanceDlg +// purpose : +//================================================================================= +class MeasureGUI_DistanceDlg : public GEOMBase_Skeleton +{ Q_OBJECT - + public: - MeasureGUI_DistanceDlg( GeometryGUI*, QWidget* ); + MeasureGUI_DistanceDlg (GeometryGUI*, QWidget*); ~MeasureGUI_DistanceDlg(); protected: - // redefined from GEOMBase_Helper and MeasureGUI_Skeleton + // redefined from GEOMBase_Helper and GEOMBase_Skeleton + virtual GEOM::GEOM_IOperations_ptr createOperation(); + virtual bool isValid (QString&); + virtual bool execute (ObjectList&); + virtual QString getNewObjectName (int CurrObj = -1) const; + + void redisplayPreview(); virtual void processObject(); virtual SALOME_Prs* buildPrs(); - virtual void SelectionIntoArgument(); - virtual void LineEditReturnPressed(); - virtual void SetEditCurrentArgument(); - virtual bool isValid( QString& ); private: void Init(); - bool getParameters( double&, - gp_Pnt&, - gp_Pnt& ); + void enterEvent (QEvent*); + private: - QLineEdit* myEditCurrentArgument; - QLineEdit* mySelEdit2; - QPushButton* mySelBtn2; - - MeasureGUI_2Sel4LineEdit* myGrp; + GEOM::GEOM_Object_var myObj1; GEOM::GEOM_Object_var myObj2; + + MeasureGUI_DistanceGroup* myGrp; + GEOM::ListOfDouble_var myDbls; + +private slots: + void ClickOnOk(); + bool ClickOnApply(); + void ActivateThisDialog(); + void SelectionIntoArgument(); + void SetEditCurrentArgument(); + void SolutionSelected (int i); }; #endif // MEASUREGUI_DISTANCEDLG_H diff --git a/src/MeasureGUI/MeasureGUI_Widgets.cxx b/src/MeasureGUI/MeasureGUI_Widgets.cxx index 5cb2936fd..d9b93cf1e 100644 --- a/src/MeasureGUI/MeasureGUI_Widgets.cxx +++ b/src/MeasureGUI/MeasureGUI_Widgets.cxx @@ -15,11 +15,10 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File : MeasureGUI_Widgets.cxx // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// + #include "MeasureGUI_Widgets.h" ////////////////////////////////////////// @@ -121,20 +120,6 @@ MeasureGUI_2Sel1LineEdit::~MeasureGUI_2Sel1LineEdit() { } -////////////////////////////////////////// -// MeasureGUI_2Sel4LineEdit -////////////////////////////////////////// - -MeasureGUI_2Sel4LineEdit::MeasureGUI_2Sel4LineEdit( QWidget* parent, Qt::WindowFlags f ) -: QWidget( parent, f ) -{ - setupUi( this ); -} - -MeasureGUI_2Sel4LineEdit::~MeasureGUI_2Sel4LineEdit() -{ -} - ////////////////////////////////////////// // MeasureGUI_SkeletonBox ////////////////////////////////////////// diff --git a/src/MeasureGUI/MeasureGUI_Widgets.h b/src/MeasureGUI/MeasureGUI_Widgets.h index 17067d067..651b65298 100644 --- a/src/MeasureGUI/MeasureGUI_Widgets.h +++ b/src/MeasureGUI/MeasureGUI_Widgets.h @@ -15,11 +15,10 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File : MeasureGUI_Widgets.h // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// + #ifndef MEASUREGUI_WIDGETS_H #define MEASUREGUI_WIDGETS_H @@ -135,22 +134,6 @@ public: ~MeasureGUI_2Sel1LineEdit(); }; -////////////////////////////////////////// -// MeasureGUI_2Sel4LineEdit -////////////////////////////////////////// - -#include "ui_MeasureGUI_2Sel4LineEdit_QTD.h" - -class MeasureGUI_2Sel4LineEdit : public QWidget, - public Ui::MeasureGUI_2Sel4LineEdit_QTD -{ - Q_OBJECT - -public: - MeasureGUI_2Sel4LineEdit( QWidget* = 0, Qt::WindowFlags = 0 ); - ~MeasureGUI_2Sel4LineEdit(); -}; - ////////////////////////////////////////// // MeasureGUI_SkeletonBox ////////////////////////////////////////// diff --git a/src/OBJECT/GEOM_AISShape.cxx b/src/OBJECT/GEOM_AISShape.cxx index 4b5b686e4..63e8d187b 100644 --- a/src/OBJECT/GEOM_AISShape.cxx +++ b/src/OBJECT/GEOM_AISShape.cxx @@ -166,7 +166,6 @@ GEOM_AISShape::GEOM_AISShape(const TopoDS_Shape& shape, myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(aMatAspect); myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(aMatAspect); } - myCurrentMaterial = myDrawer->ShadingAspect()->Aspect()->FrontMaterial(); } void GEOM_AISShape::setIO(const Handle(SALOME_InteractiveObject)& io){ @@ -206,7 +205,7 @@ void GEOM_AISShape::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresent Handle(AIS_InteractiveContext) anIC = GetContext(); // StdSelect_DisplayMode d = (StdSelect_DisplayMode) aMode; - bool isTopLev = (isTopLevel() && topLevelDisplayMode() != TopShowAdditionalWActor); + bool isTopLev = isTopLevel() && switchTopLevel(); switch (aMode) { case 0://StdSelect_DM_Wireframe: { @@ -316,24 +315,6 @@ void GEOM_AISShape::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresent // aPrs->ReCompute(); // for hidden line recomputation if necessary... } -void GEOM_AISShape::SetTransparency(const Standard_Real aValue) -{ - if(aValue<0.0 || aValue>1.0) return; - - if(aValue<=0.05) - { - UnsetTransparency(); - return; - } - - Graphic3d_MaterialAspect FMat = myDrawer->ShadingAspect()->Aspect()->FrontMaterial(); - FMat.SetTransparency(aValue); - myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial(FMat); - myDrawer->ShadingAspect()->Aspect()->SetBackMaterial(FMat); - myCurrentMaterial = FMat; - myTransparency = aValue; -} - void GEOM_AISShape::SetShadingColor(const Quantity_Color &aCol) { myShadingColor = aCol; @@ -387,16 +368,13 @@ void GEOM_AISShape::shadingMode(const Handle(PrsMgr_PresentationManager3d)& aPre myDrawer->ShadingAspect()->Aspect()->SetDistinguishOn(); Graphic3d_MaterialAspect aMatAspect(Graphic3d_NOM_PLASTIC); - aMatAspect.SetTransparency(myTransparency); - myCurrentMaterial = myDrawer->ShadingAspect()->Aspect()->FrontMaterial(); - myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial( isTopLevel() ? aMatAspect : myCurrentMaterial ); - myDrawer->ShadingAspect()->Aspect()->SetBackMaterial( isTopLevel() ? aMatAspect : myCurrentMaterial ); - - //Handle(Graphic3d_AspectFillArea3d) a4bis = myDrawer->ShadingAspect()->Aspect(); - // P->SetPrimitivesAspect(a4bis); - // G->SetGroupPrimitivesAspect(a4bis); - //a4bis->SetInteriorColor(myShadingColor); - if( isTopLevel() && topLevelDisplayMode() != TopShowAdditionalWActor ) + aMatAspect.SetTransparency(Transparency()); + Graphic3d_MaterialAspect currentFrontMaterial = myDrawer->ShadingAspect()->Aspect()->FrontMaterial(); + Graphic3d_MaterialAspect currentBackMaterial = myDrawer->ShadingAspect()->Aspect()->BackMaterial(); + myDrawer->ShadingAspect()->Aspect()->SetFrontMaterial( isTopLevel() ? aMatAspect : currentFrontMaterial ); + myDrawer->ShadingAspect()->Aspect()->SetBackMaterial ( isTopLevel() ? aMatAspect : currentBackMaterial ); + + if( isTopLevel() && switchTopLevel() ) myDrawer->ShadingAspect()->SetColor( topLevelColor() ); else { if(myDrawer->ShadingAspect()->Aspect()->FrontMaterial().MaterialType( Graphic3d_MATERIAL_ASPECT )) diff --git a/src/OBJECT/GEOM_AISShape.hxx b/src/OBJECT/GEOM_AISShape.hxx index eec1ef7bf..5bd38ac77 100644 --- a/src/OBJECT/GEOM_AISShape.hxx +++ b/src/OBJECT/GEOM_AISShape.hxx @@ -116,7 +116,6 @@ public: void highlightSubShapes(const TColStd_IndexedMapOfInteger& aIndexMap, const Standard_Boolean aHighlight ); ~GEOM_AISShape(); - void SetTransparency(const Standard_Real aValue); void SetShadingColor(const Quantity_Color &aCol); void SetEdgesInShadingColor(const Quantity_Color &aCol); void SetDisplayVectors(bool isShow); @@ -172,7 +171,6 @@ private: TCollection_AsciiString myName; bool myDisplayVectors; Standard_Boolean myTopLevel; - Graphic3d_MaterialAspect myCurrentMaterial; Standard_Integer myPrevDisplayMode; static TopLevelDispMode myTopLevelDm; diff --git a/src/OBJECT/GEOM_AISVector.cxx b/src/OBJECT/GEOM_AISVector.cxx index 051b875cc..542837d39 100644 --- a/src/OBJECT/GEOM_AISVector.cxx +++ b/src/OBJECT/GEOM_AISVector.cxx @@ -23,7 +23,6 @@ // GEOM OBJECT : interactive object for Geometry entities visualization // File : GEOM_AISVector.cxx // Author : Julia DOROVSKIKH -// $Header$ // #include diff --git a/src/OBJECT/GEOM_Actor.cxx b/src/OBJECT/GEOM_Actor.cxx index a68e25b0e..1552ee794 100644 --- a/src/OBJECT/GEOM_Actor.cxx +++ b/src/OBJECT/GEOM_Actor.cxx @@ -24,7 +24,6 @@ // File : GEOM_Actor.cxx // Author : Christophe ATTANASIO // Module : GEOM -// $Header$ // /*! \class GEOM_Actor GEOM_Actor.h @@ -113,7 +112,8 @@ GEOM_Actor::GEOM_Actor(): myHighlightProp(vtkProperty::New()), myPreHighlightProp(vtkProperty::New()), - myShadingFaceProp(vtkProperty::New()) + myShadingFaceProp(vtkProperty::New()), + myShadingBackFaceProp(vtkProperty::New()) { #ifdef MYDEBUG MESSAGE (this<< " GEOM_Actor::GEOM_Actor"); @@ -150,19 +150,22 @@ GEOM_Actor::GEOM_Actor(): myIsolatedEdgeActor->SetInput(myIsolatedEdgeSource->GetOutput(),false); aProperty = myIsolatedEdgeActor->GetProperty(); aProperty->SetRepresentation(VTK_WIREFRAME); - aProperty->SetColor(1, 0, 0); + myIsolatedEdgeColor[0] = 1; myIsolatedEdgeColor[1] = 0; myIsolatedEdgeColor[2] = 0; + aProperty->SetColor(myIsolatedEdgeColor[0], myIsolatedEdgeColor[1], myIsolatedEdgeColor[2]); myAppendFilter->AddInput(myOneFaceEdgeSource->GetOutput()); myOneFaceEdgeActor->SetInput(myOneFaceEdgeSource->GetOutput(),false); aProperty = myOneFaceEdgeActor->GetProperty(); aProperty->SetRepresentation(VTK_WIREFRAME); - aProperty->SetColor(0, 1, 0); + myOneFaceEdgeColor[0] = 0; myOneFaceEdgeColor[1] = 1; myOneFaceEdgeColor[2] = 0; + aProperty->SetColor(myOneFaceEdgeColor[0], myOneFaceEdgeColor[1], myOneFaceEdgeColor[2]); myAppendFilter->AddInput(mySharedEdgeSource->GetOutput()); mySharedEdgeActor->SetInput(mySharedEdgeSource->GetOutput(),false); aProperty = mySharedEdgeActor->GetProperty(); aProperty->SetRepresentation(VTK_WIREFRAME); - aProperty->SetColor(1, 1, 0); + mySharedEdgeColor[0] = 1; mySharedEdgeColor[1] = 1; mySharedEdgeColor[2] = 0; + aProperty->SetColor(mySharedEdgeColor[0], mySharedEdgeColor[1], mySharedEdgeColor[2]); myAppendFilter->AddInput(myWireframeFaceSource->GetOutput()); myWireframeFaceActor->SetInput(myWireframeFaceSource->GetOutput(),false); @@ -183,8 +186,6 @@ GEOM_Actor::GEOM_Actor(): myShadingFaceActor->SetProperty(myShadingFaceProp.GetPointer()); - StoreBoundaryColors(); - myNbIsos[0] = -1; myNbIsos[1] = -1; @@ -202,6 +203,7 @@ GEOM_Actor::~GEOM_Actor() myHighlightProp->Delete(); myPreHighlightProp->Delete(); myShadingFaceProp->Delete(); + myShadingBackFaceProp->Delete(); } GEOM_Actor* @@ -295,40 +297,42 @@ setDisplayMode(int theMode) MESSAGE ( "GEOM_Actor::setDisplayMode = "<GetProperty()->SetColor(myEdgesInShadingColor[0], - myEdgesInShadingColor[1], - myEdgesInShadingColor[2]); - myOneFaceEdgeActor->GetProperty()->SetColor(myEdgesInShadingColor[0], - myEdgesInShadingColor[1], - myEdgesInShadingColor[2]); - mySharedEdgeActor->GetProperty()->SetColor(myEdgesInShadingColor[0], + if ( theMode == (int)eShadingWithEdges ) { + // Coloring edges + myIsolatedEdgeActor->GetProperty()->SetColor(myEdgesInShadingColor[0], myEdgesInShadingColor[1], myEdgesInShadingColor[2]); - //SetModified(); - } else { - myIsolatedEdgeActor->GetProperty()->SetColor(myEdgesInWireframeColor[0], - myEdgesInWireframeColor[1], - myEdgesInWireframeColor[2]); - } + myOneFaceEdgeActor->GetProperty()->SetColor(myEdgesInShadingColor[0], + myEdgesInShadingColor[1], + myEdgesInShadingColor[2]); + mySharedEdgeActor->GetProperty()->SetColor(myEdgesInShadingColor[0], + myEdgesInShadingColor[1], + myEdgesInShadingColor[2]); + } + else { + // Restore number of iso-lines + RestoreIsoNumbers(); + + // Coloring edges + myIsolatedEdgeActor->GetProperty()->SetColor(myIsolatedEdgeColor[0], + myIsolatedEdgeColor[1], + myIsolatedEdgeColor[2]); + mySharedEdgeActor->GetProperty()->SetColor(myIsolatedEdgeColor[0], + myIsolatedEdgeColor[1], + myIsolatedEdgeColor[2]); + myOneFaceEdgeActor->GetProperty()->SetColor(myOneFaceEdgeColor[0], + myOneFaceEdgeColor[1], + myOneFaceEdgeColor[2]); } VTKViewer_Actor::setDisplayMode(theMode); @@ -501,6 +505,26 @@ vtkProperty* GEOM_Actor::GetWireframeProperty() return myWireframeFaceActor->GetProperty(); } +vtkProperty* GEOM_Actor::GetIsolatedEdgeProperty() +{ + return myIsolatedEdgeActor->GetProperty(); +} + +vtkProperty* GEOM_Actor::GetVertexProperty() +{ + return myVertexActor->GetProperty(); +} + +vtkProperty* GEOM_Actor::GetSharedEdgeProperty() +{ + return mySharedEdgeActor->GetProperty(); +} + +vtkProperty* GEOM_Actor::GetFaceEdgeProperty() +{ + return myOneFaceEdgeActor->GetProperty(); +} + void GEOM_Actor::SetShadingProperty(vtkProperty* Prop) { #ifdef MYDEBUG @@ -547,6 +571,7 @@ void GEOM_Actor::Render(vtkRenderer *ren, vtkMapper *theMapper) myPreHighlightProp->SetRepresentationToSurface(); myHighlightProp->SetRepresentationToSurface(); myShadingFaceProp->SetRepresentationToSurface(); + myShadingBackFaceProp->SetRepresentationToSurface(); break; } @@ -554,14 +579,17 @@ void GEOM_Actor::Render(vtkRenderer *ren, vtkMapper *theMapper) if(myIsPreselected){ this->myHighlightActor->SetProperty(myPreHighlightProp.GetPointer()); myShadingFaceActor->SetProperty(myPreHighlightProp.GetPointer()); + myShadingFaceActor->SetBackfaceProperty(myPreHighlightProp.GetPointer()); } else { this->myHighlightActor->SetProperty(myShadingFaceProp.GetPointer()); myShadingFaceActor->SetProperty(myShadingFaceProp.GetPointer()); + myShadingFaceActor->SetBackfaceProperty(myShadingBackFaceProp.GetPointer()); } } else{ this->myHighlightActor->SetProperty(myHighlightProp.GetPointer()); myShadingFaceActor->SetProperty(myHighlightProp.GetPointer()); + myShadingFaceActor->SetBackfaceProperty(myHighlightProp.GetPointer()); } this->Property->Render(this, ren); @@ -672,6 +700,7 @@ void GEOM_Actor::SetOpacity(vtkFloatingPointType opa) { // enk:tested OK myShadingFaceProp->SetOpacity(opa); + myShadingBackFaceProp->SetOpacity(opa); myHighlightProp->SetOpacity(opa); myPreHighlightProp->SetOpacity(opa); myVertexActor->GetProperty()->SetOpacity(opa); @@ -685,21 +714,22 @@ vtkFloatingPointType GEOM_Actor::GetOpacity() void GEOM_Actor::SetColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b) { - // enk:tested OK - myShadingFaceProp->SetColor(r,g,b); // shading color (Shading) - myVertexActor->GetProperty()->SetColor(r,g,b); // vertex actor (Shading/Wireframe) - if ( myDisplayMode != (int)eShadingWithEdges ) { - myIsolatedEdgeActor->GetProperty()->SetColor(r,g,b); // standalone edge color (Wireframe) - myOneFaceEdgeActor->GetProperty()->SetColor(r,g,b); // standalone face edge color (Wireframe) - mySharedEdgeActor->GetProperty()->SetColor(r,g,b); // share edge color (Wireframe) - } - - StoreBoundaryColors(); + // set the same color to all sub-actors: + // - points + // - standalone edges + // - shared edges + // - free edges + // - shading color (front and back faces) + SetPointColor(r, g, b); + SetIsolatedEdgeColor(r, g, b); + SetSharedEdgeColor(r, g, b); + SetFreeEdgeColor(r, g, b); + myShadingFaceProp->SetColor(r,g,b); // shading color + myShadingBackFaceProp->SetColor(r,g,b); // back face shading color } void GEOM_Actor::GetColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b) { - // enk:tested OK vtkFloatingPointType aRGB[3]; myShadingFaceProp->GetColor(aRGB); r = aRGB[0]; @@ -707,25 +737,97 @@ void GEOM_Actor::GetColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFlo b = aRGB[2]; } +/*! + \brief Set color of points + Points actor is shown in Wireframe mode only, see SetVisibility() +*/ +void GEOM_Actor::SetPointColor(vtkFloatingPointType r, vtkFloatingPointType g, vtkFloatingPointType b) +{ + myVertexActor->GetProperty()->SetColor(r, g, b); +} + +/*! + \brief Set color of standalone edges, wires, vectors + This actor is shown in all display mode, see SetVisibility() + TODO: check - this color seems to be used not only for standalone edges +*/ +void GEOM_Actor::SetIsolatedEdgeColor(vtkFloatingPointType r, vtkFloatingPointType g, vtkFloatingPointType b) +{ + myIsolatedEdgeColor[0] = r; myIsolatedEdgeColor[1] = g; myIsolatedEdgeColor[2] = b; + if ( myDisplayMode != (int)eShadingWithEdges ) + myIsolatedEdgeActor->GetProperty()->SetColor(r, g, b); +} + +/*! + \brief Set color of shared edges + This actor is shown only in wireframe and shading+edges display modes, see SetVisibility() + TODO: check - this seems to be not working currently +*/ +void GEOM_Actor::SetSharedEdgeColor(vtkFloatingPointType r, vtkFloatingPointType g, vtkFloatingPointType b) +{ + mySharedEdgeColor[0] = r; mySharedEdgeColor[1] = g; mySharedEdgeColor[2] = b; + if ( myDisplayMode != (int)eShadingWithEdges ) + mySharedEdgeActor->GetProperty()->SetColor(r, g, b); +} + +/*! + \brief Set color of edges for standalone faces + This actor is shown only in wireframe and shading+edges display modes, see SetVisibility() + TODO: this color should be used not only for faces +*/ +void GEOM_Actor::SetFreeEdgeColor(vtkFloatingPointType r, vtkFloatingPointType g, vtkFloatingPointType b) +{ + myOneFaceEdgeColor[0] = r; myOneFaceEdgeColor[1] = g; myOneFaceEdgeColor[2] = b; + if ( myDisplayMode != (int)eShadingWithEdges ) + myOneFaceEdgeActor->GetProperty()->SetColor(r, g, b); +} + +/*! + \brief Set color of iso-lines + This actor is shown only in wireframe display mode, see SetVisibility() +*/ +void GEOM_Actor::SetIsosColor(vtkFloatingPointType r, vtkFloatingPointType g, vtkFloatingPointType b) +{ + myWireframeFaceActor->GetProperty()->SetColor(r, g, b); +} + void GEOM_Actor::SetMaterial(std::vector theProps) { // we set material properties as back and front material + int aSize = theProps.size(); + + if ( aSize < 1 || aSize > 2) + return; + + // theProps[0] -- front material properties + // theProps[1] -- back material properties (if exist) + double aCoefnt; // Set reflection coefficients aCoefnt = theProps[0]->GetAmbient(); myShadingFaceProp->SetAmbient(aCoefnt); myVertexActor->GetProperty()->SetAmbient(aCoefnt); + if ( aSize == 2 ) + aCoefnt = theProps[1]->GetAmbient(); + myShadingBackFaceProp->SetAmbient(aCoefnt); // Set diffuse coefficients aCoefnt = theProps[0]->GetDiffuse(); myShadingFaceProp->SetDiffuse(aCoefnt); myVertexActor->GetProperty()->SetDiffuse(aCoefnt); + if ( aSize == 2 ) + aCoefnt = theProps[1]->GetDiffuse(); + myShadingBackFaceProp->SetDiffuse(aCoefnt); // Set specular coefficients aCoefnt = theProps[0]->GetSpecular(); myShadingFaceProp->SetSpecular(aCoefnt); myVertexActor->GetProperty()->SetSpecular(aCoefnt); + if ( aSize == 2 ) + aCoefnt = theProps[1]->GetSpecular(); + myShadingBackFaceProp->SetSpecular(aCoefnt); + double* aColor; @@ -733,28 +835,48 @@ void GEOM_Actor::SetMaterial(std::vector theProps) aColor = theProps[0]->GetAmbientColor(); myShadingFaceProp->SetAmbientColor(aColor[0], aColor[1], aColor[2]); myVertexActor->GetProperty()->SetAmbientColor(aColor[0], aColor[1], aColor[2]); + if ( aSize == 2 ) + aColor = theProps[1]->GetAmbientColor(); + myShadingBackFaceProp->SetAmbientColor(aColor[0], aColor[1], aColor[2]); // Set diffuse colors aColor = theProps[0]->GetDiffuseColor(); myShadingFaceProp->SetDiffuseColor(aColor[0], aColor[1], aColor[2]); myVertexActor->GetProperty()->SetDiffuseColor(aColor[0], aColor[1], aColor[2]); + if ( aSize == 2 ) + aColor = theProps[1]->GetDiffuseColor(); + myShadingBackFaceProp->SetDiffuseColor(aColor[0], aColor[1], aColor[2]); // Set specular colors aColor = theProps[0]->GetSpecularColor(); myShadingFaceProp->SetSpecularColor(aColor[0], aColor[1], aColor[2]); myVertexActor->GetProperty()->SetSpecularColor(aColor[0], aColor[1], aColor[2]); + if ( aSize == 2 ) + aColor = theProps[1]->GetSpecularColor(); + myShadingBackFaceProp->SetSpecularColor(aColor[0], aColor[1], aColor[2]); // Set shininess aCoefnt = theProps[0]->GetSpecularPower(); myShadingFaceProp->SetSpecularPower(aCoefnt); myVertexActor->GetProperty()->SetSpecularPower(aCoefnt); + if ( aSize == 2 ) + aCoefnt = theProps[1]->GetSpecularPower(); + myShadingBackFaceProp->SetSpecularPower(aCoefnt); + + // Set back face material property + myShadingFaceActor->SetBackfaceProperty(myShadingBackFaceProp.GetPointer()); } -vtkProperty* GEOM_Actor::GetMaterial() +vtkProperty* GEOM_Actor::GetFrontMaterial() { return myShadingFaceProp; } +vtkProperty* GEOM_Actor::GetBackMaterial() +{ + return myShadingBackFaceProp; +} + bool GEOM_Actor::IsInfinitive() { return ((bool)myShape.Infinite() || isOnlyVertex); @@ -995,22 +1117,3 @@ void GEOM_Actor::ResetIsoNumbers() int aNb[2] = {0, 0}; myWireframeFaceSource->SetNbIso(aNb); } - -void GEOM_Actor::StoreBoundaryColors() -{ - myShadingFaceProp->GetColor(myEdgesInWireframeColor); - -} - -void GEOM_Actor::RestoreBoundaryColors() -{ - myIsolatedEdgeActor->GetProperty()->SetColor(myEdgesInWireframeColor[0], - myEdgesInWireframeColor[1], - myEdgesInWireframeColor[2]); - myOneFaceEdgeActor->GetProperty()->SetColor(myEdgesInWireframeColor[0], - myEdgesInWireframeColor[1], - myEdgesInWireframeColor[2]); - mySharedEdgeActor->GetProperty()->SetColor(myEdgesInWireframeColor[0], - myEdgesInWireframeColor[1], - myEdgesInWireframeColor[2]); -} diff --git a/src/OBJECT/GEOM_Actor.h b/src/OBJECT/GEOM_Actor.h index 28df32d67..d773b6cf6 100644 --- a/src/OBJECT/GEOM_Actor.h +++ b/src/OBJECT/GEOM_Actor.h @@ -24,7 +24,6 @@ // File : GEOM_Actor.h // Author : Christophe ATTANASIO // Module : GEOM -// $Header$ // #ifndef GEOM_ACTOR_H #define GEOM_ACTOR_H @@ -88,6 +87,10 @@ public: vtkProperty* GetWireframeProperty(); vtkProperty* GetShadingProperty(); + vtkProperty* GetIsolatedEdgeProperty(); + vtkProperty* GetVertexProperty(); + vtkProperty* GetSharedEdgeProperty(); + vtkProperty* GetFaceEdgeProperty(); void setDeflection(double adef); virtual void setDisplayMode(int thenewmode); @@ -121,14 +124,27 @@ public: void SetOpacity(vtkFloatingPointType opa); vtkFloatingPointType GetOpacity(); - // Color - void SetColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b); - void GetColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b); + // Color (same to all sub-actors/display modes) + void SetColor(vtkFloatingPointType r, vtkFloatingPointType g, vtkFloatingPointType b); + void GetColor(vtkFloatingPointType& r, vtkFloatingPointType& g, vtkFloatingPointType& b); + // Color of points + void SetPointColor(vtkFloatingPointType r, vtkFloatingPointType g, vtkFloatingPointType b); + // Color of standalone edges, wires, vectors + void SetIsolatedEdgeColor(vtkFloatingPointType r, vtkFloatingPointType g, vtkFloatingPointType b); + // Color of shared edges + void SetSharedEdgeColor(vtkFloatingPointType r, vtkFloatingPointType g, vtkFloatingPointType b); + // Color of free edges + void SetFreeEdgeColor(vtkFloatingPointType r, vtkFloatingPointType g, vtkFloatingPointType b); + // Color of edges in shading+edges display mode + void SetEdgesInShadingColor(vtkFloatingPointType r, vtkFloatingPointType g, vtkFloatingPointType b); + // Color of iso-lines + void SetIsosColor(vtkFloatingPointType r, vtkFloatingPointType g, vtkFloatingPointType b); + // Material void SetMaterial(std::vector theProps); - vtkProperty* GetMaterial(); - + vtkProperty* GetFrontMaterial(); + vtkProperty* GetBackMaterial(); virtual bool IsInfinitive(); // overloaded functions @@ -186,9 +202,6 @@ public: bool GetVectorMode(); - //! Edges in shading color management - void SetEdgesInShadingColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b); - void StoreIsoNumbers(); @@ -203,9 +216,6 @@ protected: void GetMatrix(vtkCamera* theCam, vtkMatrix4x4 *result); - void StoreBoundaryColors(); - void RestoreBoundaryColors(); - GEOM_Actor(); ~GEOM_Actor(); @@ -243,6 +253,7 @@ private: vtkSmartPointer myHighlightProp; vtkSmartPointer myPreHighlightProp; vtkSmartPointer myShadingFaceProp; + vtkSmartPointer myShadingBackFaceProp; PAppendFilter myAppendFilter; PPolyGeomPainterDataMapper myPolyDataMapper; @@ -254,6 +265,9 @@ private: vtkFloatingPointType myEdgesInWireframeColor[3]; vtkFloatingPointType myEdgesInShadingColor[3]; + vtkFloatingPointType myIsolatedEdgeColor[3]; + vtkFloatingPointType mySharedEdgeColor[3]; + vtkFloatingPointType myOneFaceEdgeColor[3]; }; #endif //GEOM_ACTOR_H diff --git a/src/OBJECT/GEOM_Constants.cxx b/src/OBJECT/GEOM_Constants.cxx new file mode 100644 index 000000000..aa1b7ec04 --- /dev/null +++ b/src/OBJECT/GEOM_Constants.cxx @@ -0,0 +1,102 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : GEOM_Constants.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + +#include "GEOM_Constants.h" + +namespace GEOM +{ + + /*! + \brief Get minimal allowed value for deflection coefficient + */ + double minDeflection() + { + return 1e-06; // DEFLECTION_MIN + } + + /*! + \brief Get character used to separate parameter names + */ + QString sectionSeparator() + { + return "_"; // NAME_SEPARATOR + } + + /*! + \brief Get character used to separate numeric parameter values (color = r:g:b) + */ + QString subSectionSeparator() + { + return ":"; // DIGIT_SEPARATOR + } + + QString propertyName( Property type ) + { + static const char* names[] = { + // visibility + "Visibility", // VISIBILITY_PROP + // transparency + "Transparency", // TRANSPARENCY_PROP + // display mode + "DisplayMode", // DISPLAY_MODE_PROP + // number of the iso lines (along u and v directions) + "Isos", // ISOS_PROP + // main / shading color + "Color", // COLOR_PROP + // "show edges direction" flag + "VectorMode", // VECTOR_MODE_PROP + // deflection coefficient + "DeflectionCoeff", // DEFLECTION_COEFF_PROP + // point marker data + "MarkerType", // MARKER_TYPE_PROP + // material + "Material", // MATERIAL_PROP + // general line width + "EdgeWidth", // EDGE_WIDTH_PROP + // isos width + "IsosWidth", // ISOS_WIDTH_PROP + // top-level flag + "TopLevelFlag", // TOP_LEVEL_PROP + // opacity + "Opacity", // OPACITY_PROP + // shading color + "ShadingColor", // - + // wireframe color + "WireframeColor", // - + // standalone edges color + "LineColor", // - + // free boundaries color + "FreeBndColor", // - + // points color + "PointColor", // - + // isos color + "IsosColor", // - + // outlines color + "OutlineColor", // - + }; + return ( type >= GEOM::Visibility && type <= GEOM::LastProperty ) ? names[type] : QString(); + } + +} // namespace GEOM diff --git a/src/OBJECT/GEOM_Constants.h b/src/OBJECT/GEOM_Constants.h index b890379e3..50474475a 100644 --- a/src/OBJECT/GEOM_Constants.h +++ b/src/OBJECT/GEOM_Constants.h @@ -21,31 +21,49 @@ // // File : GEOM_Constants.h -// Author : Margarita KARPUNINA -// Module : GEOM -// +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + #ifndef GEOM_CONSTANTS_H #define GEOM_CONSTANTS_H -// minimum allowed value for deflection coefficient -#define DEFLECTION_MIN 1e-06 - -//Define separators -#define NAME_SEPARATOR '_' // character used to separate parameter names -#define DIGIT_SEPARATOR ':' // character used to separate numeric parameter values (color = r:g:b) - -#define VISIBILITY_PROP "Visibility" //Object visibility property -#define OPACITY_PROP "Opacity" //Object opacity property -#define TRANSPARENCY_PROP "Transparency" //Object transparency property -#define DISPLAY_MODE_PROP "DisplayMode" //Object display mode property -#define ISOS_PROP "Isos" //Number of the Isos property of the object -#define COLOR_PROP "Color" //Color of the object -#define VECTOR_MODE_PROP "VectorMode" //Vector mode property -#define DEFLECTION_COEFF_PROP "DeflectionCoeff" //Deflection coeff property -#define MARKER_TYPE_PROP "MarkerType" //Marker type property -#define MATERIAL_PROP "Material" //Object material property -#define EDGE_WIDTH_PROP "EdgeWidth" //Width of the edge -#define ISOS_WIDTH_PROP "IsosWidth" //Width of the iso-lines -#define TOP_LEVEL_PROP "TopLevelFlag" //Top level flag +#include + +#include "GEOM_OBJECT_defs.hxx" + +namespace GEOM +{ + enum Property { + Visibility, + Transparency, + DisplayMode, + NbIsos, + Color, + EdgesDirection, + Deflection, + PointMarker, + Material, + LineWidth, + IsosWidth, + TopLevel, + LastStudyProperty = TopLevel, + Opacity, + ShadingColor, + WireframeColor, + LineColor, + FreeBndColor, + PointColor, + IsosColor, + OutlineColor, + LastProperty = OutlineColor, + }; + + GEOM_OBJECT_EXPORT double minDeflection(); + + GEOM_OBJECT_EXPORT QString sectionSeparator(); + GEOM_OBJECT_EXPORT QString subSectionSeparator(); + + GEOM_OBJECT_EXPORT QString propertyName( Property ); +} + #endif //GEOM_CONSTANTS_H diff --git a/src/OBJECT/GEOM_DeviceActor.cxx b/src/OBJECT/GEOM_DeviceActor.cxx index 266814569..9a25e86e5 100755 --- a/src/OBJECT/GEOM_DeviceActor.cxx +++ b/src/OBJECT/GEOM_DeviceActor.cxx @@ -73,6 +73,20 @@ GetProperty() return myActor->GetProperty(); } +void +GEOM_DeviceActor:: +SetBackfaceProperty(vtkProperty* theProperty) +{ + myActor->SetBackfaceProperty(theProperty); +} + +vtkProperty* +GEOM_DeviceActor:: +GetBackfaceProperty() +{ + return myActor->GetBackfaceProperty(); +} + void GEOM_DeviceActor:: SetVisibility(int theVisibility) diff --git a/src/OBJECT/GEOM_DeviceActor.h b/src/OBJECT/GEOM_DeviceActor.h index 8b36ab7ae..67edada94 100755 --- a/src/OBJECT/GEOM_DeviceActor.h +++ b/src/OBJECT/GEOM_DeviceActor.h @@ -52,7 +52,10 @@ public: void SetProperty(vtkProperty* theProperty); vtkProperty* GetProperty(); - + + void SetBackfaceProperty(vtkProperty* theProperty); + vtkProperty* GetBackfaceProperty(); + void SetVisibility(int theVisibility); int GetVisibility(); diff --git a/src/OBJECT/GEOM_InteractiveObject.cxx b/src/OBJECT/GEOM_InteractiveObject.cxx index d108c1735..caa18d7b7 100644 --- a/src/OBJECT/GEOM_InteractiveObject.cxx +++ b/src/OBJECT/GEOM_InteractiveObject.cxx @@ -24,7 +24,6 @@ // File : GEOM_InteractiveObject.cxx // Author : Christophe ATTANASIO // Module : GEOM -// $Header$ // /*! \class GEOM_InteractiveObject GEOM_InteractiveObject.hxx diff --git a/src/OBJECT/GEOM_OCCReader.h b/src/OBJECT/GEOM_OCCReader.h index 3be818b36..c69b67d35 100644 --- a/src/OBJECT/GEOM_OCCReader.h +++ b/src/OBJECT/GEOM_OCCReader.h @@ -24,7 +24,6 @@ // File : GEOM_OCCReader.h // Author : Christophe ATTANASIO // Module : GEOM -// $Header$ // /*! \class GEOM_OCCReader GEOM_OCCReader.h diff --git a/src/OBJECT/GEOM_TopWireframeShape.cxx b/src/OBJECT/GEOM_TopWireframeShape.cxx index f22b3197f..4729ecfda 100755 --- a/src/OBJECT/GEOM_TopWireframeShape.cxx +++ b/src/OBJECT/GEOM_TopWireframeShape.cxx @@ -56,6 +56,10 @@ GEOM_TopWireframeShape::GEOM_TopWireframeShape(const TopoDS_Shape& shape) SetColor(GEOM_AISShape::topLevelColor()); } +GEOM_TopWireframeShape::~GEOM_TopWireframeShape() +{ +} + Handle(SALOME_InteractiveObject) GEOM_TopWireframeShape::getIO(){ Handle(SALOME_InteractiveObject) IO; if ( !GetOwner().IsNull() ) diff --git a/src/OBJECT/GEOM_TopWireframeShape.ixx b/src/OBJECT/GEOM_TopWireframeShape.ixx index 1fd891967..a4f1408d6 100755 --- a/src/OBJECT/GEOM_TopWireframeShape.ixx +++ b/src/OBJECT/GEOM_TopWireframeShape.ixx @@ -30,8 +30,6 @@ #include #endif -GEOM_TopWireframeShape::~GEOM_TopWireframeShape() {} - Standard_EXPORT Handle_Standard_Type& GEOM_TopWireframeShape_Type_() { diff --git a/src/OBJECT/GEOM_VTKTrihedron.cxx b/src/OBJECT/GEOM_VTKTrihedron.cxx index a57f359d1..5c5259745 100644 --- a/src/OBJECT/GEOM_VTKTrihedron.cxx +++ b/src/OBJECT/GEOM_VTKTrihedron.cxx @@ -24,7 +24,6 @@ // File : GEOM_VTKTrihedron.cxx // Author : Sergey LITONIN // Module : SALOME -// $Header: // #include "GEOM_VTKTrihedron.hxx" @@ -117,11 +116,15 @@ void GEOM_VTKTrihedronAxis::SetSize( vtkFloatingPointType theSize ) gp_Mat aRot = aTrsf.VectorialPart(); for ( int i = 1; i <= 3; i++ ) + { for ( int j = 1; j <= 3; j++ ) myMatrix->SetElement( i - 1, j - 1, aRot( i, j ) ); + + // Set Arrow Position + myMatrix->SetElement( i - 1 , 3, aPosition[ i - 1 ] ); + } myArrowActor->SetUserMatrix( myMatrix ); - myArrowActor->SetPosition( aPosition ); #ifdef IPAL21440 if( vtkCoordinate* aCoord = myLabelActor->GetPositionCoordinate()->GetReferenceCoordinate() ) @@ -429,3 +432,4 @@ void GEOM_VTKTrihedron::SetAxesColors( vtkFloatingPointType theColor[3], bool th myAxis[ 1 ]->SetColor( theIsDiffuse ? 0.0 : theColor[0], theColor[1], theIsDiffuse ? 0.0 : theColor[2] ); myAxis[ 2 ]->SetColor( theIsDiffuse ? 0.0 : theColor[0], theIsDiffuse ? 0.0 : theColor[1], theColor[2] ); } + diff --git a/src/OBJECT/GEOM_VTKTrihedron.hxx b/src/OBJECT/GEOM_VTKTrihedron.hxx index 99a3ab60c..897312ae0 100644 --- a/src/OBJECT/GEOM_VTKTrihedron.hxx +++ b/src/OBJECT/GEOM_VTKTrihedron.hxx @@ -24,7 +24,6 @@ // File : GEOM_VTKTrihedron.h // Author : Sergey LITONIN // Module : SALOME -// $Header: // #ifndef GEOM_VTKTrihedron_H #define GEOM_VTKTrihedron_H diff --git a/src/OBJECT/Makefile.am b/src/OBJECT/Makefile.am index ae48a97f8..b59d98914 100644 --- a/src/OBJECT/Makefile.am +++ b/src/OBJECT/Makefile.am @@ -65,7 +65,8 @@ dist_libGEOMObject_la_SOURCES = \ GEOM_VTKPropertyMaterial.cxx \ GEOM_AISVector.cxx \ GEOM_PainterPolyDataMapper.cxx \ - GEOM_DeviceActor.cxx + GEOM_DeviceActor.cxx \ + GEOM_Constants.cxx libGEOMObject_la_CPPFLAGS = \ diff --git a/src/RepairGUI/RepairGUI_FreeBoundDlg.cxx b/src/RepairGUI/RepairGUI_FreeBoundDlg.cxx index 3ef492fcc..6f76359f6 100644 --- a/src/RepairGUI/RepairGUI_FreeBoundDlg.cxx +++ b/src/RepairGUI/RepairGUI_FreeBoundDlg.cxx @@ -18,15 +18,16 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : RepairGUI_FreeBoundDlg.cxx // Author : Sergey LITONIN, Open CASCADE S.A.S. (sergey.litonin@opencascade.com) -// + #include "RepairGUI_FreeBoundDlg.h" #include +#include + #include #include #include @@ -51,7 +52,7 @@ #include #define SPACING 6 -#define MARGIN 9 +#define MARGIN 0 /*! Class : RepairGUI_FreeBoundDlg @@ -62,59 +63,55 @@ // function : RepairGUI_FreeBoundDlg // purpose : Constructor //================================================================================= -RepairGUI_FreeBoundDlg::RepairGUI_FreeBoundDlg( GeometryGUI* theGUI, QWidget* theParent ) - : QDialog( theParent, 0 ), - GEOMBase_Helper( dynamic_cast( theParent ) ), - myGeomGUI( theGUI ) +RepairGUI_FreeBoundDlg::RepairGUI_FreeBoundDlg (GeometryGUI* theGUI, QWidget* theParent) + : GEOMBase_Skeleton(theGUI, theParent) { - setAttribute( Qt::WA_DeleteOnClose ); - - setWindowTitle( tr( "CAPTION" ) ); - - QPixmap iconSelect( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) ); - - QGroupBox* aMainGrp = new QGroupBox( tr( "FREE_BOUND" ), this ); - - QLabel* lab = new QLabel( tr( "GEOM_OBJECT" ), aMainGrp ); - QPushButton* btn = new QPushButton( aMainGrp ); - btn->setIcon( iconSelect ); - myEdit = new QLineEdit( aMainGrp ); - myEdit->setReadOnly( true ); - myEdit->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - - myClosedLbl = new QLabel( tr( "NUMBER_CLOSED" ), aMainGrp ); - myOpenLbl = new QLabel( tr( "NUMBER_OPEN" ), aMainGrp ); - myClosedLbl->setMinimumWidth( 150 ); - myOpenLbl->setMinimumWidth( 150 ); - - QGridLayout* aMainGrpLayout = new QGridLayout( aMainGrp ); - aMainGrpLayout->setMargin( MARGIN ); aMainGrpLayout->setSpacing( SPACING ); - aMainGrpLayout->addWidget( lab, 0, 0 ); - aMainGrpLayout->addWidget( btn, 0, 1 ); - aMainGrpLayout->addWidget( myEdit, 0, 2 ); - aMainGrpLayout->addWidget( myClosedLbl, 1, 0, 1, 3 ); - aMainGrpLayout->addWidget( myOpenLbl, 2, 0, 1, 3 ); - - QFrame* aFrame = new QFrame( this ); - aFrame->setFrameStyle( QFrame::Box | QFrame::Sunken ); - QPushButton* aCloseBtn = new QPushButton( tr( "GEOM_BUT_CLOSE" ), aFrame ); - QPushButton* aHelpBtn = new QPushButton( tr( "GEOM_BUT_HELP" ), aFrame ); - QHBoxLayout* aBtnLay = new QHBoxLayout( aFrame ); - aBtnLay->setMargin( MARGIN ); aBtnLay->setSpacing( SPACING ); - aBtnLay->addWidget( aCloseBtn ); - aBtnLay->addSpacing( SPACING ); aBtnLay->addStretch(); - aBtnLay->addWidget( aHelpBtn ); - - QVBoxLayout* aLay = new QVBoxLayout( this ); - aLay->setSpacing( SPACING ); - aLay->setMargin( MARGIN ); - aLay->addWidget( aMainGrp ); - aLay->addWidget( aFrame ); - - myHelpFileName = "using_measurement_tools_page.html#boundaries_anchor"; - - connect( aCloseBtn, SIGNAL( clicked() ), SLOT( onClose() ) ); - connect( aHelpBtn, SIGNAL( clicked() ), SLOT( onHelp() ) ); + QPixmap image0 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_FREE_BOUNDS"))); + QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT"))); + + setWindowTitle(tr("CAPTION")); + + /***************************************************************/ + + mainFrame()->GroupConstructors->setTitle(tr("FREE_BOUND")); + mainFrame()->RadioButton1->setIcon(image0); + mainFrame()->RadioButton2->setAttribute(Qt::WA_DeleteOnClose); + mainFrame()->RadioButton2->close(); + mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose); + mainFrame()->RadioButton3->close(); + + mainFrame()->GroupBoxName->hide(); + + QGroupBox* aMainGrp = new QGroupBox (tr("FREE_BOUND"), this); + + QLabel* lab = new QLabel (tr("GEOM_OBJECT"), aMainGrp); + QPushButton* btn = new QPushButton (aMainGrp); + btn->setIcon(image1); + myEdit = new QLineEdit (aMainGrp); + myEdit->setReadOnly(true); + myEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + + myClosedLbl = new QLabel (tr("NUMBER_CLOSED"), aMainGrp); + myOpenLbl = new QLabel (tr("NUMBER_OPEN"), aMainGrp); + myClosedLbl->setMinimumWidth(150); + myOpenLbl->setMinimumWidth(150); + + QGridLayout* aMainGrpLayout = new QGridLayout (aMainGrp); + aMainGrpLayout->addWidget(lab, 0, 0); + aMainGrpLayout->addWidget(btn, 0, 1); + aMainGrpLayout->addWidget(myEdit, 0, 2); + aMainGrpLayout->addWidget(myClosedLbl, 1, 0, 1, 3); + aMainGrpLayout->addWidget(myOpenLbl, 2, 0, 1, 3); + + QVBoxLayout* aLay = new QVBoxLayout (centralWidget()); + aLay->setSpacing(SPACING); + aLay->setMargin(MARGIN); + aLay->addWidget(aMainGrp); + + resize(minimumSizeHint()); + /***************************************************************/ + + myHelpFileName = "boundaries_page.html"; Init(); } @@ -128,126 +125,99 @@ RepairGUI_FreeBoundDlg::~RepairGUI_FreeBoundDlg() } //================================================================================= -// function : onClose -// purpose : SLOT. Called when "close" button pressed. Close dialog +// function : Init +// purpose : Initialize dialog fields //================================================================================= -void RepairGUI_FreeBoundDlg::onClose() +void RepairGUI_FreeBoundDlg::Init() { - globalSelection(); - disconnect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr(), 0, this, 0 ); - myGeomGUI->SetActiveDialogBox( 0 ); - reject(); - erasePreview(); + myNbClosed = myNbOpen = 0; + myObj = GEOM::GEOM_Object::_nil(); + + myEditCurrentArgument = myEdit; + + connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); + + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + + activateSelection(); + SelectionIntoArgument(); } //================================================================================= -// function : onHelp() +// function : ClickOnOk() // purpose : //================================================================================= -void RepairGUI_FreeBoundDlg::onHelp() +void RepairGUI_FreeBoundDlg::ClickOnOk() { - LightApp_Application* app = (LightApp_Application*)( SUIT_Session::session()->activeApplication() ); - if ( app ) - app->onHelpContextModule( myGeomGUI ? app->moduleName( myGeomGUI->moduleName() ) : QString(""), myHelpFileName ); - else { - QString platform; -#ifdef WIN32 - platform = "winapplication"; -#else - platform = "application"; -#endif - SUIT_MessageBox::warning( this, - tr( "WRN_WARNING" ), - tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg( app->resourceMgr()->stringValue( "ExternalBrowser", - platform ) ).arg( myHelpFileName ) ); - } + if (ClickOnApply()) + ClickOnCancel(); } //================================================================================= -// function : onDeactivate -// purpose : Deactivate this dialog +// function : ClickOnApply() +// purpose : //================================================================================= -void RepairGUI_FreeBoundDlg::onDeactivate() +bool RepairGUI_FreeBoundDlg::ClickOnApply() { - setEnabled( false ); - globalSelection(); - disconnect( myGeomGUI->getApp()->selectionMgr(), 0, this, 0 ); - myGeomGUI->SetActiveDialogBox( 0 ); + if (!onAccept()) + return false; + return true; } //================================================================================= -// function : onActivate -// purpose : Activate this dialog +// function : ActivateThisDialog() +// purpose : //================================================================================= -void RepairGUI_FreeBoundDlg::onActivate() +void RepairGUI_FreeBoundDlg::ActivateThisDialog() { - myGeomGUI->EmitSignalDeactivateDialog(); - setEnabled( true ); - myGeomGUI->SetActiveDialogBox( this ); - connect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr(), - SIGNAL( currentSelectionChanged() ), SLOT( onSelectionDone() ) ); + GEOMBase_Skeleton::ActivateThisDialog(); + + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + activateSelection(); - onSelectionDone(); + displayPreview(true); } //================================================================================= -// function : onSelectionDone -// purpose : SLOT. Called when selection changed. +// function : enterEvent() +// purpose : //================================================================================= -void RepairGUI_FreeBoundDlg::onSelectionDone() +void RepairGUI_FreeBoundDlg::enterEvent(QEvent*) { - LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); - SALOME_ListIO aSelList; - aSelMgr->selectedObjects(aSelList); - - if ( aSelList.Extent() != 1 ) - return; - - GEOM::GEOM_Object_var anObj = - GEOMBase::ConvertIOinGEOMObject( aSelList.First() ); - - if ( !GEOMBase::IsShape( anObj ) ) - return; - else { - myObj = anObj; - displayPreview( true, false, true, true, 3 ); - } + if (!mainFrame()->GroupConstructors->isEnabled()) + ActivateThisDialog(); } //================================================================================= -// function : Init -// purpose : Initialize dialog fields +// function : SelectionIntoArgument +// purpose : SLOT. Called when selection changed. //================================================================================= -void RepairGUI_FreeBoundDlg::Init() +void RepairGUI_FreeBoundDlg::SelectionIntoArgument() { - myNbClosed = myNbOpen = 0; + myEditCurrentArgument->setText(""); + myClosedLbl->setText(tr("NUMBER_CLOSED")); + myOpenLbl->setText(tr("NUMBER_OPEN")); myObj = GEOM::GEOM_Object::_nil(); + erasePreview(); - connect( myGeomGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT ( onDeactivate() ) ); - connect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr(), - SIGNAL( currentSelectionChanged() ), SLOT( onSelectionDone() ) ); + LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); + SALOME_ListIO aSelList; + aSelMgr->selectedObjects(aSelList); - activateSelection(); - onSelectionDone(); -} + if (aSelList.Extent() != 1) + return; -//================================================================================= -// function : enterEvent -// purpose : Activate dialog -//================================================================================= -void RepairGUI_FreeBoundDlg::enterEvent( QEvent* ) -{ - onActivate(); -} + GEOM::GEOM_Object_var anObj = GEOMBase::ConvertIOinGEOMObject(aSelList.First()); -//================================================================================= -// function : closeEvent -// purpose : Close dialog -//================================================================================= -void RepairGUI_FreeBoundDlg::closeEvent( QCloseEvent* ) -{ - onClose(); + if (!GEOMBase::IsShape(anObj)) + return; + + myObj = anObj; + myEditCurrentArgument->setText(GEOMBase::GetName(myObj)); + displayPreview(true, false, true, true, 3); } //================================================================================= @@ -257,11 +227,11 @@ void RepairGUI_FreeBoundDlg::closeEvent( QCloseEvent* ) void RepairGUI_FreeBoundDlg::activateSelection() { TColStd_MapOfInteger aMap; - aMap.Add( GEOM_FACE ); - aMap.Add( GEOM_SHELL ); - aMap.Add( GEOM_SOLID ); - aMap.Add( GEOM_COMPOUND ); - globalSelection( aMap ); + aMap.Add(GEOM_FACE); + aMap.Add(GEOM_SHELL); + aMap.Add(GEOM_SOLID); + aMap.Add(GEOM_COMPOUND); + globalSelection(aMap); } //================================================================================= @@ -270,14 +240,14 @@ void RepairGUI_FreeBoundDlg::activateSelection() //================================================================================= GEOM::GEOM_IOperations_ptr RepairGUI_FreeBoundDlg::createOperation() { - return getGeomEngine()->GetIHealingOperations( getStudyId() ); + return getGeomEngine()->GetIHealingOperations(getStudyId()); } //================================================================================= // function : isValid // purpose : //================================================================================= -bool RepairGUI_FreeBoundDlg::isValid( QString& ) +bool RepairGUI_FreeBoundDlg::isValid (QString&) { return !myObj->_is_nil(); } @@ -286,52 +256,50 @@ bool RepairGUI_FreeBoundDlg::isValid( QString& ) // function : execute // purpose : Get free boundaries //================================================================================= -bool RepairGUI_FreeBoundDlg::execute( ObjectList& objects ) +bool RepairGUI_FreeBoundDlg::execute (ObjectList& objects) { - if ( !IsPreview() || myObj->_is_nil() ) - return false; - GEOM::ListOfGO_var aClosed, anOpen; - GEOM::GEOM_IHealingOperations_var anOper = GEOM::GEOM_IHealingOperations::_narrow( getOperation() ); - bool result = anOper->GetFreeBoundary( myObj, aClosed, anOpen ); + GEOM::GEOM_IHealingOperations_var anOper = GEOM::GEOM_IHealingOperations::_narrow(getOperation()); + bool result = anOper->GetFreeBoundary(myObj, aClosed, anOpen); - if ( result ) { + if (result) { myNbClosed = aClosed->length(); myNbOpen = anOpen->length(); int i; - for ( i = 0; i < myNbClosed; i++ ) - objects.push_back( aClosed[i]._retn() ); - for ( i = 0; i < myNbOpen; i++ ) - objects.push_back( anOpen[i]._retn() ); - - myEdit->setText( GEOMBase::GetName( myObj ) ); - QString aLabelText = tr( "NUMBER_CLOSED" ) + QString( "%1" ).arg( myNbClosed ); - myClosedLbl->setText( aLabelText ); - aLabelText = tr( "NUMBER_OPEN" ) + QString( "%1" ).arg( myNbOpen ); - myOpenLbl->setText( aLabelText ); - } - else { - myEdit->setText( GEOMBase::GetName( myObj ) ); - myClosedLbl->setText( tr( "NUMBER_CLOSED" ) ); - myOpenLbl->setText( tr( "NUMBER_OPEN" ) ); + for (i = 0; i < myNbClosed; i++) + objects.push_back(aClosed[i]._retn()); + for (i = 0; i < myNbOpen; i++) + objects.push_back(anOpen[i]._retn()); + + QString aLabelText = tr("NUMBER_CLOSED") + QString("%1").arg(myNbClosed); + myClosedLbl->setText(aLabelText); + aLabelText = tr("NUMBER_OPEN") + QString("%1").arg(myNbOpen); + myOpenLbl->setText(aLabelText); } + myCurrObj = 1; return result; } -//================================================================================= -// function : keyPressEvent() -// purpose : -//================================================================================= -void RepairGUI_FreeBoundDlg::keyPressEvent( QKeyEvent* e ) +//================================================================ +// Function : getNewObjectName +// Purpose : Redefine this method to return proper name for a new object +//================================================================ +QString RepairGUI_FreeBoundDlg::getNewObjectName (int currObj) const { - QDialog::keyPressEvent( e ); - if ( e->isAccepted() ) - return; + QString aName = tr("NAME_CLOSED").arg(currObj); + if (currObj > myNbClosed) + aName = tr("NAME_OPEN").arg(currObj); + return aName; +} - if ( e->key() == Qt::Key_F1 ) { - e->accept(); - onHelp(); - } +//================================================================ +// Function : getFather +// Purpose : Get father object for object to be added in study +// (called with addInStudy method) +//================================================================ +GEOM::GEOM_Object_ptr RepairGUI_FreeBoundDlg::getFather (GEOM::GEOM_Object_ptr) +{ + return myObj; } diff --git a/src/RepairGUI/RepairGUI_FreeBoundDlg.h b/src/RepairGUI/RepairGUI_FreeBoundDlg.h index af65e1602..f9ac7bc7c 100644 --- a/src/RepairGUI/RepairGUI_FreeBoundDlg.h +++ b/src/RepairGUI/RepairGUI_FreeBoundDlg.h @@ -18,17 +18,16 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : RepairGUI_FreeBoundDlg.h // Author : Sergey LITONIN, Open CASCADE S.A.S. (sergey.litonin@opencascade.com) -// + #ifndef REPAIRGUI_FREEBOUNDDLG_H #define REPAIRGUI_FREEBOUNDDLG_H #include -#include +#include class QLineEdit; class QLabel; @@ -38,42 +37,42 @@ class GeometryGUI; // class : RepairGUI_FreeBoundDlg // purpose : Dialog for displaying free boundaries of selected face, shell or solid //================================================================================= -class RepairGUI_FreeBoundDlg : public QDialog, - public GEOMBase_Helper +class RepairGUI_FreeBoundDlg : public GEOMBase_Skeleton { Q_OBJECT public: - RepairGUI_FreeBoundDlg( GeometryGUI*, QWidget* ); + RepairGUI_FreeBoundDlg (GeometryGUI*, QWidget*); ~RepairGUI_FreeBoundDlg(); -private slots: - void onClose(); - void onHelp(); - void onDeactivate(); - void onActivate(); - void onSelectionDone(); +protected: + // redefined from GEOMBase_Helper + virtual GEOM::GEOM_IOperations_ptr createOperation(); + virtual bool isValid (QString&); + virtual bool execute (ObjectList&); + virtual GEOM::GEOM_Object_ptr getFather (GEOM::GEOM_Object_ptr); + virtual QString getNewObjectName (int CurrObj = -1) const; private: void Init(); - void enterEvent( QEvent* ); - void closeEvent( QCloseEvent* ); - void keyPressEvent( QKeyEvent* ); + void enterEvent (QEvent*); void activateSelection(); - - virtual GEOM::GEOM_IOperations_ptr createOperation(); - virtual bool execute( ObjectList& ); - virtual bool isValid( QString& ); private: QLineEdit* myEdit; QLabel* myClosedLbl; QLabel* myOpenLbl; + GEOM::GEOM_Object_var myObj; - GeometryGUI* myGeomGUI; int myNbClosed; int myNbOpen; - QString myHelpFileName; + int myCurrObj; + +private slots: + void ClickOnOk(); + bool ClickOnApply(); + void SelectionIntoArgument(); + void ActivateThisDialog(); }; #endif // REPAIRGUI_FREEBOUNDDLG_H diff --git a/src/SKETCHER/Makefile.am b/src/SKETCHER/Makefile.am index 503d0b9b5..1836cfde3 100644 --- a/src/SKETCHER/Makefile.am +++ b/src/SKETCHER/Makefile.am @@ -22,7 +22,6 @@ # Author : Patrick GOLDBRONN (CEA) # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : GEOM -# $Header$ # include $(top_srcdir)/adm_local/unix/make_common_starter.am diff --git a/src/SKETCHER/Sketcher_Profile.hxx b/src/SKETCHER/Sketcher_Profile.hxx index f323a058e..ed3bb0037 100644 --- a/src/SKETCHER/Sketcher_Profile.hxx +++ b/src/SKETCHER/Sketcher_Profile.hxx @@ -24,7 +24,6 @@ // File : Sketcher_Profile.h // Author : Damien COQUERET // Module : GEOM -// $Header: // #include #include diff --git a/src/STEPExport/Makefile.am b/src/STEPExport/Makefile.am index 96bf0e2b5..39ef12d5b 100644 --- a/src/STEPExport/Makefile.am +++ b/src/STEPExport/Makefile.am @@ -21,7 +21,6 @@ # Author : Pavel TELKOV # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : GEOM -# $Header$ # include $(top_srcdir)/adm_local/unix/make_common_starter.am diff --git a/src/STEPExport/STEPExport.cxx b/src/STEPExport/STEPExport.cxx index abe5c310a..e911cd01e 100644 --- a/src/STEPExport/STEPExport.cxx +++ b/src/STEPExport/STEPExport.cxx @@ -61,8 +61,9 @@ extern "C" { - STEPEXPORT_EXPORT - int Export(const TopoDS_Shape& theShape, const TCollection_AsciiString& theFileName) + STEPEXPORT_EXPORT int Export (const TopoDS_Shape& theShape, + const TCollection_AsciiString& theFileName, + const TCollection_AsciiString& /*theFormatName*/) { MESSAGE("Export STEP into file " << theFileName.ToCString()); diff --git a/src/STLExport/Makefile.am b/src/STLExport/Makefile.am index d482d48fe..0f94bda86 100644 --- a/src/STLExport/Makefile.am +++ b/src/STLExport/Makefile.am @@ -17,8 +17,6 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -# $Header$ -# include $(top_srcdir)/adm_local/unix/make_common_starter.am # header files diff --git a/src/ShHealOper/Makefile.am b/src/ShHealOper/Makefile.am index d2f1cd4ae..b7c55a1e2 100644 --- a/src/ShHealOper/Makefile.am +++ b/src/ShHealOper/Makefile.am @@ -22,7 +22,6 @@ # Author : Alexander SLADKOV # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : GEOM -# $Header: # include $(top_srcdir)/adm_local/unix/make_common_starter.am diff --git a/src/TransformationGUI/TransformationGUI_MultiRotationDlg.cxx b/src/TransformationGUI/TransformationGUI_MultiRotationDlg.cxx index f450a2f8c..5f22ed33a 100644 --- a/src/TransformationGUI/TransformationGUI_MultiRotationDlg.cxx +++ b/src/TransformationGUI/TransformationGUI_MultiRotationDlg.cxx @@ -69,34 +69,25 @@ TransformationGUI_MultiRotationDlg::TransformationGUI_MultiRotationDlg mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose); mainFrame()->RadioButton3->close(); - GroupPoints = new DlgRef_2Sel1SpinInt(centralWidget()); - GroupPoints->GroupBox1->setTitle(tr("GEOM_MULTIROTATION_SIMPLE")); - GroupPoints->TextLabel1->setText(tr("GEOM_MAIN_OBJECT")); - GroupPoints->TextLabel2->setText(tr("GEOM_VECTOR")); - GroupPoints->TextLabel3->setText(tr("GEOM_NB_TIMES")); - GroupPoints->PushButton1->setIcon(image2); - GroupPoints->PushButton2->setIcon(image2); - GroupPoints->LineEdit1->setReadOnly(true); - GroupPoints->LineEdit2->setReadOnly(true); - - GroupDimensions = new DlgRef_2Sel4Spin1Check(centralWidget()); - GroupDimensions->GroupBox1->setTitle(tr("GEOM_MULTIROTATION_DOUBLE")); - GroupDimensions->TextLabel1->setText(tr("GEOM_MAIN_OBJECT")); - GroupDimensions->TextLabel2->setText(tr("GEOM_VECTOR")); - GroupDimensions->TextLabel3->setText(tr("GEOM_ANGLE")); - GroupDimensions->TextLabel4->setText(tr("GEOM_NB_TIMES")); - GroupDimensions->TextLabel5->setText(tr("GEOM_STEP")); - GroupDimensions->TextLabel6->setText(tr("GEOM_NB_TIMES")); - GroupDimensions->CheckButton1->setText(tr("GEOM_REVERSE")); - GroupDimensions->PushButton1->setIcon(image2); - GroupDimensions->PushButton2->setIcon(image2); - GroupDimensions->LineEdit1->setReadOnly(true); - GroupDimensions->LineEdit2->setReadOnly(true); - - QVBoxLayout* layout = new QVBoxLayout(centralWidget()); - layout->setMargin(0); layout->setSpacing(6); - layout->addWidget(GroupPoints); - layout->addWidget(GroupDimensions); + bool isAngleStep = false; + + GroupArgs = new TransformationGUI_2Sel4Spin1Check (centralWidget()); + GroupArgs->GroupBox1->setTitle(tr("GEOM_MULTIROTATION_DOUBLE")); + GroupArgs->TextLabel1->setText(tr("GEOM_MAIN_OBJECT")); + GroupArgs->TextLabel2->setText(tr("GEOM_VECTOR")); + //GroupArgs->TextLabel3->setText(tr("GEOM_ANGLE_STEP")); + GroupArgs->CheckAngleStep->setText(tr("GEOM_ANGLE_STEP")); + GroupArgs->CheckAngleStep->setChecked(isAngleStep); + GroupArgs->TextLabel4->setText(tr("GEOM_NB_TIMES")); + GroupArgs->TextLabel5->setText(tr("GEOM_STEP_R")); + GroupArgs->TextLabel6->setText(tr("GEOM_NB_TIMES")); + GroupArgs->CheckButton1->setText(tr("GEOM_REVERSE")); + GroupArgs->PushButton1->setIcon(image2); + GroupArgs->PushButton2->setIcon(image2); + GroupArgs->LineEdit1->setReadOnly(true); + GroupArgs->LineEdit2->setReadOnly(true); + GroupArgs->SpinBox_DX1->setEnabled(isAngleStep); + GroupArgs->CheckButton1->setEnabled(isAngleStep); /***************************************************************/ setHelpFileName("multi_rotation_operation_page.html"); @@ -119,38 +110,23 @@ TransformationGUI_MultiRotationDlg::~TransformationGUI_MultiRotationDlg() //================================================================================= void TransformationGUI_MultiRotationDlg::Init() { + // init variables + myAng = 45.0; + myStep = 50.0; + myNbTimes1 = myNbTimes2 = 3; + // Get setting of step value from file configuration SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); double step = resMgr->doubleValue("Geometry", "SettingsGeomStep", 100); int SpecificStep1 = 5; int SpecificStep2 = 1; - // init variables - myAng = 45.0; - myStep = 50.0; - myNbTimes1 = myNbTimes2 = 2; // min, max, step and decimals for spin boxes & initial values - initSpinBox(GroupPoints->SpinBox_DX, 1, 999, SpecificStep2); - GroupPoints->SpinBox_DX->setValue(myNbTimes1); - - initSpinBox(GroupDimensions->SpinBox_DX1, COORD_MIN, COORD_MAX, SpecificStep1, "angle_precision" ); - initSpinBox(GroupDimensions->SpinBox_DY1, 1, 999, SpecificStep2); - initSpinBox(GroupDimensions->SpinBox_DX2, COORD_MIN, COORD_MAX, step,"length_precision" ); - initSpinBox(GroupDimensions->SpinBox_DY2, 1, 999, SpecificStep2); - GroupDimensions->SpinBox_DX1->setValue(myAng); - GroupDimensions->SpinBox_DY1->setValue(myNbTimes1); - GroupDimensions->SpinBox_DX2->setValue(myStep); - GroupDimensions->SpinBox_DY2->setValue(myNbTimes2); - - GroupPoints->LineEdit1->setText(""); - GroupPoints->LineEdit2->setText(""); - - GroupDimensions->LineEdit1->setText(""); - GroupDimensions->LineEdit2->setText(""); - - myBase.nullify(); - myVector.nullify(); + initSpinBox(GroupArgs->SpinBox_DX1, COORD_MIN, COORD_MAX, SpecificStep1, "angle_precision"); + initSpinBox(GroupArgs->SpinBox_DY1, 1, 999, SpecificStep2); + initSpinBox(GroupArgs->SpinBox_DX2, COORD_MIN, COORD_MAX, step, "length_precision"); + initSpinBox(GroupArgs->SpinBox_DY2, 1, 999, SpecificStep2); mainFrame()->GroupBoxPublish->show(); @@ -158,25 +134,23 @@ void TransformationGUI_MultiRotationDlg::Init() connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk())); connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply())); - connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int))); + connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int))); - connect(GroupPoints->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); - connect(GroupPoints->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); - connect(GroupDimensions->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); - connect(GroupDimensions->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(GroupArgs->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(GroupArgs->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); - connect(GroupPoints->SpinBox_DX, SIGNAL(valueChanged(int)), this, SLOT(ValueChangedInSpinBox(int))); - connect(GroupDimensions->SpinBox_DX1, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); - connect(GroupDimensions->SpinBox_DY1, SIGNAL(valueChanged(int)), this, SLOT(ValueChangedInSpinBox(int))); - connect(GroupDimensions->SpinBox_DX2, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); - connect(GroupDimensions->SpinBox_DY2, SIGNAL(valueChanged(int)), this, SLOT(ValueChangedInSpinBox(int))); + connect(GroupArgs->SpinBox_DX1, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(GroupArgs->SpinBox_DY1, SIGNAL(valueChanged(int)), this, SLOT(ValueChangedInSpinBox(int))); + connect(GroupArgs->SpinBox_DX2, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(GroupArgs->SpinBox_DY2, SIGNAL(valueChanged(int)), this, SLOT(ValueChangedInSpinBox(int))); - connect(GroupDimensions->SpinBox_DX1,SIGNAL(textChanged( const QString& )), - this, SLOT(TextValueChangedInSpinBox( const QString& ))); + connect(GroupArgs->SpinBox_DX1, SIGNAL(textChanged(const QString&)), + this, SLOT(TextValueChangedInSpinBox(const QString&))); connect(myGeomGUI, SIGNAL(SignalDefaultStepValueChanged(double)), this, SLOT(SetDoubleSpinBoxStep(double))); - connect(GroupDimensions->CheckButton1, SIGNAL(toggled(bool)), this, SLOT(ReverseAngle())); + connect(GroupArgs->CheckAngleStep, SIGNAL(toggled(bool)), this, SLOT(CheckAngleStep(bool))); + connect(GroupArgs->CheckButton1, SIGNAL(toggled(bool)), this, SLOT(ReverseAngle())); initName(tr("GEOM_MULTIROTATION")); @@ -189,13 +163,7 @@ void TransformationGUI_MultiRotationDlg::Init() //================================================================================= void TransformationGUI_MultiRotationDlg::SetDoubleSpinBoxStep (double step) { - GroupDimensions->SpinBox_DX2->setSingleStep(step); - - // san: Commented so as not to override specific step settings - //GroupPoints->SpinBox_DX->setSingleStep((int)step); - //GroupDimensions->SpinBox_DX1->setSingleStep(step); - //GroupDimensions->SpinBox_DY1->setSingleStep((int)step); - //GroupDimensions->SpinBox_DY2->setSingleStep((int)step); + GroupArgs->SpinBox_DX2->setSingleStep(step); } //================================================================================= @@ -206,42 +174,42 @@ void TransformationGUI_MultiRotationDlg::ConstructorsClicked (int constructorId) { disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); - switch (constructorId) { - case 0: // Rotate simple - { - GroupDimensions->hide(); - GroupPoints->show(); + myBase.nullify(); + myVector.nullify(); - GroupPoints->LineEdit1->setText(""); - GroupPoints->LineEdit2->setText(""); - myBase.nullify(); - myVector.nullify(); + GroupArgs->LineEdit1->setText(""); + GroupArgs->LineEdit2->setText(""); - GroupPoints->SpinBox_DX->setValue(myNbTimes1); + GroupArgs->SpinBox_DX1->setValue(myAng); + GroupArgs->SpinBox_DY1->setValue(myNbTimes1); + GroupArgs->SpinBox_DX2->setValue(myStep); + GroupArgs->SpinBox_DY2->setValue(myNbTimes2); - GroupPoints->PushButton1->click(); + switch (constructorId) { + case 0: // Rotate simple + { + GroupArgs->GroupBox1->setTitle(tr("GEOM_MULTIROTATION_SIMPLE")); + GroupArgs->TextLabel5->hide(); + GroupArgs->TextLabel6->hide(); + GroupArgs->SpinBox_DX2->hide(); + GroupArgs->SpinBox_DY2->hide(); + GroupArgs->CheckButton1->hide(); } break; case 1: // Rotate double { - GroupPoints->hide(); - GroupDimensions->show(); - - GroupDimensions->LineEdit1->setText(""); - GroupDimensions->LineEdit2->setText(""); - myBase.nullify(); - myVector.nullify(); - - GroupDimensions->SpinBox_DX1->setValue(myAng); - GroupDimensions->SpinBox_DY1->setValue(myNbTimes1); - GroupDimensions->SpinBox_DX2->setValue(myStep); - GroupDimensions->SpinBox_DY2->setValue(myNbTimes2); - - GroupDimensions->PushButton1->click(); + GroupArgs->GroupBox1->setTitle(tr("GEOM_MULTIROTATION_DOUBLE")); + GroupArgs->TextLabel5->show(); + GroupArgs->TextLabel6->show(); + GroupArgs->SpinBox_DX2->show(); + GroupArgs->SpinBox_DY2->show(); + GroupArgs->CheckButton1->show(); } break; } + GroupArgs->PushButton1->click(); + qApp->processEvents(); updateGeometry(); resize(minimumSizeHint()); @@ -289,33 +257,39 @@ void TransformationGUI_MultiRotationDlg::SelectionIntoArgument() { erasePreview(); - TopAbs_ShapeEnum aNeedType = ( myEditCurrentArgument == GroupPoints->LineEdit2 || - myEditCurrentArgument == GroupDimensions->LineEdit2 ) ? + TopAbs_ShapeEnum aNeedType = ( myEditCurrentArgument == GroupArgs->LineEdit2 ) ? TopAbs_EDGE : TopAbs_SHAPE; GEOM::GeomObjPtr aSelectedObject = getSelected( aNeedType ); TopoDS_Shape aShape; if ( aSelectedObject && GEOMBase::GetShape( aSelectedObject.get(), aShape ) && !aShape.IsNull() ) { QString aName = GEOMBase::GetName( aSelectedObject.get() ); myEditCurrentArgument->setText( aName ); - if ( myEditCurrentArgument == GroupPoints->LineEdit1 ) { - myBase = aSelectedObject; - if ( !myVector ) - GroupPoints->PushButton2->click(); - } - else if ( myEditCurrentArgument == GroupPoints->LineEdit2) { - myVector = aSelectedObject; - if ( !myBase ) - GroupPoints->PushButton1->click(); - } - else if ( myEditCurrentArgument == GroupDimensions->LineEdit1 ) { + if ( myEditCurrentArgument == GroupArgs->LineEdit1 ) { myBase = aSelectedObject; + + // recompute myAng and myStep (Mantis issue 0021718) + GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId()); + double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax; + anOper->GetBoundingBox(myBase.get(), Xmin, Xmax, Ymin, Ymax, Zmin, Zmax); + if (anOper->IsDone()) { + // angular step + double diag = sqrt((Xmax-Xmin)*(Xmax-Xmin) + (Ymax-Ymin)*(Ymax-Ymin)); + double d = sqrt((0.5*(Xmax+Xmin))*(0.5*(Xmax+Xmin)) + (0.5*(Ymax+Ymin))*(0.5*(Ymax+Ymin))); + myAng = floor(2.0 * atan(diag/d) * 180.0 / M_PI); + GroupArgs->SpinBox_DX1->setValue(myAng); + + // radial step + myStep = Max(floor(1.5*(Xmax-Xmin)), floor(1.5*(Ymax-Ymin))); + GroupArgs->SpinBox_DX2->setValue(myStep); + } + if ( !myVector ) - GroupDimensions->PushButton2->click(); + GroupArgs->PushButton2->click(); } - else if ( myEditCurrentArgument == GroupDimensions->LineEdit2 ) { + else if ( myEditCurrentArgument == GroupArgs->LineEdit2 ) { myVector = aSelectedObject; if ( !myBase ) - GroupDimensions->PushButton1->click(); + GroupArgs->PushButton1->click(); } // clear selection @@ -325,11 +299,9 @@ void TransformationGUI_MultiRotationDlg::SelectionIntoArgument() this, SLOT(SelectionIntoArgument())); } else { - if ( myEditCurrentArgument == GroupPoints->LineEdit1 || - myEditCurrentArgument == GroupDimensions->LineEdit1 ) + if ( myEditCurrentArgument == GroupArgs->LineEdit1 ) myBase.nullify(); - else if ( myEditCurrentArgument == GroupPoints->LineEdit2 || - myEditCurrentArgument == GroupDimensions->LineEdit2 ) + else if ( myEditCurrentArgument == GroupArgs->LineEdit2 ) myVector.nullify(); myEditCurrentArgument->setText(""); } @@ -348,33 +320,19 @@ void TransformationGUI_MultiRotationDlg::SetEditCurrentArgument() disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); globalSelection(GEOM_ALLSHAPES); - if (send == GroupPoints->PushButton1) { - myEditCurrentArgument = GroupPoints->LineEdit1; - - GroupPoints->PushButton2->setDown(false); - GroupPoints->LineEdit2->setEnabled(false); - } - else if (send == GroupPoints->PushButton2) { - myEditCurrentArgument = GroupPoints->LineEdit2; - - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); - - GroupPoints->PushButton1->setDown(false); - GroupPoints->LineEdit1->setEnabled(false); - } - else if (send == GroupDimensions->PushButton1) { - myEditCurrentArgument = GroupDimensions->LineEdit1; + if (send == GroupArgs->PushButton1) { + myEditCurrentArgument = GroupArgs->LineEdit1; - GroupDimensions->PushButton2->setDown(false); - GroupDimensions->LineEdit2->setEnabled(false); + GroupArgs->PushButton2->setDown(false); + GroupArgs->LineEdit2->setEnabled(false); } - else if (send == GroupDimensions->PushButton2) { - myEditCurrentArgument = GroupDimensions->LineEdit2; + else if (send == GroupArgs->PushButton2) { + myEditCurrentArgument = GroupArgs->LineEdit2; localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); - GroupDimensions->PushButton1->setDown(false); - GroupDimensions->LineEdit1->setEnabled(false); + GroupArgs->PushButton1->setDown(false); + GroupArgs->LineEdit1->setEnabled(false); } connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); @@ -416,12 +374,13 @@ void TransformationGUI_MultiRotationDlg::enterEvent (QEvent*) // function : TextValueChangedInSpinBox() // purpose : //================================================================================= -void TransformationGUI_MultiRotationDlg::TextValueChangedInSpinBox(const QString& s){ +void TransformationGUI_MultiRotationDlg::TextValueChangedInSpinBox (const QString& s) +{ bool isDigit; s.toDouble(&isDigit); - if(!isDigit) - GroupDimensions->CheckButton1->setChecked(false); - GroupDimensions->CheckButton1->setEnabled(isDigit); + if (!isDigit) + GroupArgs->CheckButton1->setChecked(false); + GroupArgs->CheckButton1->setEnabled(isDigit); } //================================================================================= @@ -432,9 +391,9 @@ void TransformationGUI_MultiRotationDlg::ValueChangedInSpinBox (double newValue) { QObject* send = (QObject*)sender(); - if (send == GroupDimensions->SpinBox_DX1) + if (send == GroupArgs->SpinBox_DX1) myAng = newValue; - else if (send == GroupDimensions->SpinBox_DX2) + else if (send == GroupArgs->SpinBox_DX2) myStep = newValue; processPreview(); @@ -448,9 +407,9 @@ void TransformationGUI_MultiRotationDlg::ValueChangedInSpinBox (int newValue) { QObject* send = (QObject*)sender(); - if (send == GroupPoints->SpinBox_DX || send == GroupDimensions->SpinBox_DY1) + if (send == GroupArgs->SpinBox_DY1) myNbTimes1 = newValue; - else if (send == GroupDimensions->SpinBox_DY2) + else if (send == GroupArgs->SpinBox_DY2) myNbTimes2 = newValue; processPreview(); @@ -458,7 +417,7 @@ void TransformationGUI_MultiRotationDlg::ValueChangedInSpinBox (int newValue) //================================================================================= // function : ReverseAngle() -// purpose : 'state' not used here +// purpose : //================================================================================= void TransformationGUI_MultiRotationDlg::ReverseAngle() { @@ -467,11 +426,22 @@ void TransformationGUI_MultiRotationDlg::ReverseAngle() int aConstructorId = getConstructorId(); if (aConstructorId == 1) - GroupDimensions->SpinBox_DX1->setValue(myAng); + GroupArgs->SpinBox_DX1->setValue(myAng); processPreview(); } +//================================================================================= +// function : CheckAngleStep() +// purpose : +//================================================================================= +void TransformationGUI_MultiRotationDlg::CheckAngleStep (bool isOn) +{ + GroupArgs->SpinBox_DX1->setEnabled(isOn); + GroupArgs->CheckButton1->setEnabled(isOn); + processPreview(); +} + //================================================================================= // function : createOperation // purpose : @@ -488,16 +458,20 @@ GEOM::GEOM_IOperations_ptr TransformationGUI_MultiRotationDlg::createOperation() bool TransformationGUI_MultiRotationDlg::isValid (QString& msg) { bool ok = false; - switch(getConstructorId()){ + switch (getConstructorId()) { case 0: - ok = GroupPoints->SpinBox_DX->isValid( msg, !IsPreview() ) && myBase && myVector; + ok = (GroupArgs->SpinBox_DX1->isValid( msg, !IsPreview() ) && + GroupArgs->SpinBox_DY1->isValid( msg, !IsPreview() ) && + //myBase && myVector); // myVector = DZ by default + myBase); break; case 1: - ok = GroupDimensions->SpinBox_DX1->isValid( msg, !IsPreview() ) && - GroupDimensions->SpinBox_DY1->isValid( msg, !IsPreview() ) && - GroupDimensions->SpinBox_DX2->isValid( msg, !IsPreview() ) && - GroupDimensions->SpinBox_DY2->isValid( msg, !IsPreview() ) && - myBase && myVector; + ok = (GroupArgs->SpinBox_DX1->isValid( msg, !IsPreview() ) && + GroupArgs->SpinBox_DY1->isValid( msg, !IsPreview() ) && + GroupArgs->SpinBox_DX2->isValid( msg, !IsPreview() ) && + GroupArgs->SpinBox_DY2->isValid( msg, !IsPreview() ) && + //myBase && myVector); // myVector = DZ by default + myBase); break; default: break; @@ -520,29 +494,38 @@ bool TransformationGUI_MultiRotationDlg::execute (ObjectList& objects) switch (getConstructorId()) { case 0: - if ( myBase && myVector ) { + if (GroupArgs->CheckAngleStep->isChecked()) + anObj = anOper->MultiRotate1DByStep(myBase.get(), myVector.get(), myAng * M_PI / 180., myNbTimes1); + else anObj = anOper->MultiRotate1D(myBase.get(), myVector.get(), myNbTimes1); - if(!IsPreview()) - aParameters<SpinBox_DX->text(); - res = true; + + if (!IsPreview()) { + if (GroupArgs->CheckAngleStep->isChecked()) + aParameters << GroupArgs->SpinBox_DX1->text(); + aParameters << GroupArgs->SpinBox_DY1->text(); } + res = true; break; case 1: - if ( myBase && myVector ) { - anObj = anOper->MultiRotate2D(myBase.get(), myVector.get(), myAng, myNbTimes1, myStep, myNbTimes2); - if(!IsPreview()) { - aParameters<SpinBox_DX1->text(); - aParameters<SpinBox_DY1->text(); - aParameters<SpinBox_DX2->text(); - aParameters<SpinBox_DY2->text(); - } - res = true; + if (GroupArgs->CheckAngleStep->isChecked()) + anObj = anOper->MultiRotate2DByStep(myBase.get(), myVector.get(), myAng * M_PI / 180., myNbTimes1, + myStep, myNbTimes2); + else + anObj = anOper->MultiRotate2DNbTimes(myBase.get(), myVector.get(), myNbTimes1, myStep, myNbTimes2); + + if (!IsPreview()) { + if (GroupArgs->CheckAngleStep->isChecked()) + aParameters << GroupArgs->SpinBox_DX1->text(); + aParameters << GroupArgs->SpinBox_DY1->text(); + aParameters << GroupArgs->SpinBox_DX2->text(); + aParameters << GroupArgs->SpinBox_DY2->text(); } + res = true; break; } if (!anObj->_is_nil()) { - if(!IsPreview()) + if (!IsPreview()) anObj->SetParameters(aParameters.join(":").toLatin1().constData()); objects.push_back(anObj._retn()); } @@ -586,3 +569,82 @@ void TransformationGUI_MultiRotationDlg::restoreSubShapes (SALOMEDS::Study_ptr mainFrame()->CheckBoxAddPrefix->isChecked()); } } + +//================================================================================= +// function : TransformationGUI_2Sel4Spin1Check +// purpose : +//================================================================================= +TransformationGUI_2Sel4Spin1Check::TransformationGUI_2Sel4Spin1Check (QWidget *parent) +{ + gridLayout = new QGridLayout (parent); + gridLayout->setSpacing(6); + gridLayout->setContentsMargins(11, 11, 11, 11); + gridLayout->setHorizontalSpacing(0); + gridLayout->setVerticalSpacing(0); + gridLayout->setContentsMargins(0, 0, 0, 0); + + GroupBox1 = new QGroupBox (parent); + + gridLayout1 = new QGridLayout (GroupBox1); + gridLayout1->setSpacing(6); + gridLayout1->setContentsMargins(11, 11, 11, 11); + gridLayout1->setHorizontalSpacing(6); + gridLayout1->setVerticalSpacing(6); + gridLayout1->setContentsMargins(9, 9, 9, 9); + + // 2Sel + TextLabel1 = new QLabel(GroupBox1); + TextLabel2 = new QLabel(GroupBox1); + + PushButton1 = new QPushButton (GroupBox1); + PushButton2 = new QPushButton (GroupBox1); + + LineEdit2 = new QLineEdit(GroupBox1); + LineEdit1 = new QLineEdit(GroupBox1); + + gridLayout1->addWidget(TextLabel1, 0, 0, 1, 1); + gridLayout1->addWidget(TextLabel2, 1, 0, 1, 1); + gridLayout1->addWidget(PushButton1, 0, 1, 1, 1); + gridLayout1->addWidget(PushButton2, 1, 1, 1, 1); + gridLayout1->addWidget(LineEdit1, 0, 2, 1, 1); + gridLayout1->addWidget(LineEdit2, 1, 2, 1, 1); + + // 4Spin (double-int-double-int) + //TextLabel3 = new QLabel (GroupBox1); + CheckAngleStep = new QCheckBox (GroupBox1); + TextLabel4 = new QLabel (GroupBox1); + TextLabel5 = new QLabel (GroupBox1); + TextLabel6 = new QLabel (GroupBox1); + + SpinBox_DX1 = new SalomeApp_DoubleSpinBox (GroupBox1); + SpinBox_DY1 = new SalomeApp_IntSpinBox (GroupBox1); + SpinBox_DX2 = new SalomeApp_DoubleSpinBox (GroupBox1); + SpinBox_DY2 = new SalomeApp_IntSpinBox (GroupBox1); + + //gridLayout1->addWidget(TextLabel3, 2, 0, 1, 1); + gridLayout1->addWidget(CheckAngleStep, 2, 0, 1, 1); + gridLayout1->addWidget(TextLabel4, 3, 0, 1, 1); + gridLayout1->addWidget(TextLabel5, 5, 0, 1, 1); + gridLayout1->addWidget(TextLabel6, 6, 0, 1, 1); + + gridLayout1->addWidget(SpinBox_DX1, 2, 1, 1, 2); + gridLayout1->addWidget(SpinBox_DY1, 3, 1, 1, 2); + gridLayout1->addWidget(SpinBox_DX2, 5, 1, 1, 2); + gridLayout1->addWidget(SpinBox_DY2, 6, 1, 1, 2); + + // 1Check + CheckButton1 = new QCheckBox (GroupBox1); + + gridLayout1->addWidget(CheckButton1, 4, 0, 1, 3); + + gridLayout->addWidget(GroupBox1, 0, 0, 1, 1); +} + +//================================================================================= +// function : ~TransformationGUI_2Sel4Spin1Check() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +TransformationGUI_2Sel4Spin1Check::~TransformationGUI_2Sel4Spin1Check() +{ + // no need to delete child widgets, Qt does it all for us +} diff --git a/src/TransformationGUI/TransformationGUI_MultiRotationDlg.h b/src/TransformationGUI/TransformationGUI_MultiRotationDlg.h index fac7bd502..ed4268145 100644 --- a/src/TransformationGUI/TransformationGUI_MultiRotationDlg.h +++ b/src/TransformationGUI/TransformationGUI_MultiRotationDlg.h @@ -18,34 +18,78 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // GEOM GEOMGUI : GUI for Geometry component // File : TransformationGUI_MultiRotationDlg.h // Author : Damien COQUERET, Open CASCADE S.A.S. -// + #ifndef TRANSFORMATIONGUI_MULTIROTATIONDLG_H #define TRANSFORMATIONGUI_MULTIROTATIONDLG_H #include "GEOMBase_Skeleton.h" #include "GEOM_GenericObjPtr.h" -class DlgRef_2Sel4Spin1Check; -class DlgRef_2Sel1SpinInt; +#include + +#include +#include +#include +#include +#include +#include + +//================================================================================= +// class : TransformationGUI_2Sel4Spin1Check +// purpose : +//================================================================================= +class TransformationGUI_2Sel4Spin1Check : public QWidget +{ + Q_OBJECT + + public: + TransformationGUI_2Sel4Spin1Check (QWidget *parent); + ~TransformationGUI_2Sel4Spin1Check(); + + public: + QGridLayout *gridLayout; + QGroupBox *GroupBox1; + QGridLayout *gridLayout1; + + // 2Sel + QLabel *TextLabel1; + QLabel *TextLabel2; + QPushButton *PushButton1; + QPushButton *PushButton2; + QLineEdit *LineEdit1; + QLineEdit *LineEdit2; + + // 4Spin (double-int-double-int) + QCheckBox *CheckAngleStep; + QLabel *TextLabel4; + QLabel *TextLabel5; + QLabel *TextLabel6; + SalomeApp_DoubleSpinBox *SpinBox_DX1; + SalomeApp_IntSpinBox *SpinBox_DY1; + SalomeApp_DoubleSpinBox *SpinBox_DX2; + SalomeApp_IntSpinBox *SpinBox_DY2; + + // 1Check + QCheckBox *CheckButton1; +}; //================================================================================= // class : TransformationGUI_MultiRotationDlg // purpose : //================================================================================= class TransformationGUI_MultiRotationDlg : public GEOMBase_Skeleton -{ +{ Q_OBJECT public: - TransformationGUI_MultiRotationDlg( GeometryGUI*, QWidget* = 0, - bool = false, Qt::WindowFlags = 0 ); + TransformationGUI_MultiRotationDlg (GeometryGUI*, QWidget* = 0, + bool = false, Qt::WindowFlags = 0); ~TransformationGUI_MultiRotationDlg(); - + protected: // redefined from GEOMBase_Helper virtual GEOM::GEOM_IOperations_ptr createOperation(); @@ -57,7 +101,7 @@ protected: private: void Init(); void enterEvent( QEvent* ); - + private: GEOM::GeomObjPtr myBase, myVector; int myNbTimes1; @@ -67,9 +111,8 @@ private: // to initialize the first selection field with a selected object on the dialog creation bool myInitial; - - DlgRef_2Sel1SpinInt* GroupPoints; - DlgRef_2Sel4Spin1Check* GroupDimensions; + + TransformationGUI_2Sel4Spin1Check* GroupArgs; private slots: void ClickOnOk(); @@ -77,6 +120,7 @@ private slots: void ActivateThisDialog(); void SelectionIntoArgument(); void SetEditCurrentArgument(); + void CheckAngleStep (bool); void ReverseAngle(); void ValueChangedInSpinBox( double ); void ValueChangedInSpinBox( int ); diff --git a/src/TransformationGUI/TransformationGUI_MultiTranslationDlg.cxx b/src/TransformationGUI/TransformationGUI_MultiTranslationDlg.cxx index 352f88c2e..60eb1f981 100644 --- a/src/TransformationGUI/TransformationGUI_MultiTranslationDlg.cxx +++ b/src/TransformationGUI/TransformationGUI_MultiTranslationDlg.cxx @@ -82,10 +82,10 @@ TransformationGUI_MultiTranslationDlg::TransformationGUI_MultiTranslationDlg GroupPoints = new DlgRef_2Sel2Spin1Check(centralWidget()); GroupPoints->GroupBox1->setTitle(tr("GEOM_MULTITRANSLATION_SIMPLE")); GroupPoints->TextLabel1->setText(tr("GEOM_MAIN_OBJECT")); - GroupPoints->TextLabel2->setText(tr("GEOM_VECTOR_U")); - GroupPoints->TextLabel3->setText(tr("GEOM_STEP_U")); - GroupPoints->TextLabel4->setText(tr("GEOM_NB_TIMES_U")); - GroupPoints->CheckButton1->setText(tr("GEOM_REVERSE_U")); + GroupPoints->TextLabel2->setText(tr("GEOM_VECTOR")); + GroupPoints->TextLabel3->setText(tr("GEOM_STEP")); + GroupPoints->TextLabel4->setText(tr("GEOM_NB_TIMES")); + GroupPoints->CheckButton1->setText(tr("GEOM_REVERSE_DIRECTION")); GroupPoints->PushButton1->setIcon(image2); GroupPoints->PushButton2->setIcon(image2); GroupPoints->LineEdit1->setReadOnly(true); @@ -142,7 +142,7 @@ void TransformationGUI_MultiTranslationDlg::Init() int SpecificStep = 1; // init variables myStepU = myStepV = 50.0; - myNbTimesU = myNbTimesV = 2; + myNbTimesU = myNbTimesV = 3; // min, max, step and decimals for spin boxes & initial values initSpinBox(GroupPoints->SpinBox_DX, COORD_MIN, COORD_MAX, step, "length_precision" ); @@ -328,9 +328,20 @@ void TransformationGUI_MultiTranslationDlg::SelectionIntoArgument() if ( aSelectedObject && GEOMBase::GetShape( aSelectedObject.get(), aShape ) && !aShape.IsNull() ) { QString aName = GEOMBase::GetName( aSelectedObject.get() ); myEditCurrentArgument->setText( aName ); + if ( myEditCurrentArgument == GroupPoints->LineEdit1 ) { myBase = aSelectedObject; - if ( !myVectorU ) + + // recompute myStepU (Mantis issue 0021718) + GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId()); + double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax; + anOper->GetBoundingBox(myBase.get(), Xmin, Xmax, Ymin, Ymax, Zmin, Zmax); + if (anOper->IsDone()) { + myStepU = floor(1.5 * (Xmax - Xmin)); + GroupPoints->SpinBox_DX->setValue(myStepU); + } + + if (!myVectorU) GroupPoints->PushButton2->click(); } else if ( myEditCurrentArgument == GroupPoints->LineEdit2 ) { @@ -340,6 +351,18 @@ void TransformationGUI_MultiTranslationDlg::SelectionIntoArgument() } else if ( myEditCurrentArgument == GroupDimensions->LineEdit1 ) { myBase = aSelectedObject; + + // recompute myStepU and myStepV (Mantis issue 0021718) + GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId()); + double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax; + anOper->GetBoundingBox(myBase.get(), Xmin, Xmax, Ymin, Ymax, Zmin, Zmax); + if (anOper->IsDone()) { + myStepU = floor(1.5 * (Xmax - Xmin)); + myStepV = floor(1.5 * (Ymax - Ymin)); + GroupDimensions->SpinBox_DX1->setValue(myStepU); + GroupDimensions->SpinBox_DX2->setValue(myStepV); + } + if ( !myVectorU ) GroupDimensions->PushButton2->click(); else if ( !myVectorV ) @@ -597,18 +620,20 @@ GEOM::GEOM_IOperations_ptr TransformationGUI_MultiTranslationDlg::createOperatio bool TransformationGUI_MultiTranslationDlg::isValid (QString& msg) { bool ok = false; - switch ( getConstructorId() ) { + switch (getConstructorId()) { case 0: ok = GroupPoints->SpinBox_DX->isValid( msg, !IsPreview() ) && GroupPoints->SpinBox_DY->isValid( msg, !IsPreview() ) && - myBase && myVectorU; + myBase; + //myBase && myVectorU; // Mantis issue 0021718 break; case 1: ok = GroupDimensions->SpinBox_DX1->isValid( msg, !IsPreview() ) && GroupDimensions->SpinBox_DY1->isValid( msg, !IsPreview() ) && GroupDimensions->SpinBox_DX2->isValid( msg, !IsPreview() ) && GroupDimensions->SpinBox_DY2->isValid( msg, !IsPreview() ) && - myBase && myVectorU && myVectorV; + myBase; + //myBase && myVectorU && myVectorV; // Mantis issue 0021718 break; default: break; @@ -625,43 +650,38 @@ bool TransformationGUI_MultiTranslationDlg::execute (ObjectList& objects) bool res = false; GEOM::GEOM_Object_var anObj; - QStringList aParameters; GEOM::GEOM_ITransformOperations_var anOper = GEOM::GEOM_ITransformOperations::_narrow(getOperation()); switch (getConstructorId()) { case 0: - if ( myBase && myVectorU ) { - createPathPreview ( myVectorU.get() ); - anObj = anOper->MultiTranslate1D(myBase.get(), myVectorU.get(), myStepU, myNbTimesU); - if(!IsPreview()) { - aParameters<SpinBox_DX->text(); - aParameters<SpinBox_DY->text(); - } - res = true; + createPathPreview(myVectorU.get()); + anObj = anOper->MultiTranslate1D(myBase.get(), myVectorU.get(), myStepU, myNbTimesU); + if (!IsPreview()) { + aParameters << GroupPoints->SpinBox_DX->text(); + aParameters << GroupPoints->SpinBox_DY->text(); } + res = true; break; case 1: - if ( myBase && myVectorU && myVectorV ) { - createPathPreview ( myVectorU.get() ); - createPathPreview ( myVectorV.get() ); - anObj = anOper->MultiTranslate2D(myBase.get(), - myVectorU.get(), myStepU, myNbTimesU, - myVectorV.get(), myStepV, myNbTimesV); - if(!IsPreview()) { - aParameters<SpinBox_DX1->text(); - aParameters<SpinBox_DY1->text(); - aParameters<SpinBox_DX2->text(); - aParameters<SpinBox_DY2->text(); - } - res = true; + createPathPreview(myVectorU.get()); + createPathPreview(myVectorV.get()); + anObj = anOper->MultiTranslate2D(myBase.get(), + myVectorU.get(), myStepU, myNbTimesU, + myVectorV.get(), myStepV, myNbTimesV); + if (!IsPreview()) { + aParameters << GroupDimensions->SpinBox_DX1->text(); + aParameters << GroupDimensions->SpinBox_DY1->text(); + aParameters << GroupDimensions->SpinBox_DX2->text(); + aParameters << GroupDimensions->SpinBox_DY2->text(); } + res = true; break; } if (!anObj->_is_nil()) { - if(!IsPreview()) + if (!IsPreview()) anObj->SetParameters(aParameters.join(":").toLatin1().constData()); objects.push_back(anObj._retn()); } @@ -716,6 +736,7 @@ void TransformationGUI_MultiTranslationDlg::restoreSubShapes (SALOMEDS::Study_pt void TransformationGUI_MultiTranslationDlg::createPathPreview ( GEOM::GEOM_Object_ptr thePath ) { if ( IsPreview() ) { + if (thePath->_is_nil()) return; TopoDS_Shape aShape; GEOMBase::GetShape( thePath, aShape, TopAbs_SHAPE ); TopoDS_Edge anEdge = TopoDS::Edge( aShape ); diff --git a/src/VTKExport/Makefile.am b/src/VTKExport/Makefile.am index a3485f69e..976cfbab2 100644 --- a/src/VTKExport/Makefile.am +++ b/src/VTKExport/Makefile.am @@ -17,8 +17,6 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -# $Header$ -# include $(top_srcdir)/adm_local/unix/make_common_starter.am # header files -- 2.30.2