From 59b5446863dc5eea40bbc83261d976760cdc395d Mon Sep 17 00:00:00 2001 From: akl Date: Thu, 23 Apr 2015 12:42:06 +0400 Subject: [PATCH 01/54] 22853: EDF 9924 GEOM: Dimension histogram --- doc/salome/gui/GEOM/images/editgroup.png | Bin 38874 -> 1753014 bytes .../gui/GEOM/images/geomcreategroup.png | Bin 33690 -> 1269739 bytes .../gui/GEOM/images/shape_statistics.png | Bin 0 -> 389143 bytes .../GEOM/images/shape_statistics_simple.png | Bin 0 -> 246293 bytes .../GEOM/input/shape_statistics_operation.doc | 28 + .../GEOM/input/using_measurement_tools.doc | 1 + .../gui/GEOM/input/working_with_groups.doc | 7 +- src/CMakeLists.txt | 4 +- src/EntityGUI/CMakeLists.txt | 2 + src/EntityGUI/EntityGUI_SubShapeDlg.cxx | 21 + src/EntityGUI/EntityGUI_SubShapeDlg.h | 2 + src/GEOMBase/GEOMBase.cxx | 6 +- src/GEOMBase/GEOMBase.h | 2 +- src/GEOMGUI/GEOM_msg_en.ts | 87 ++- src/GEOMGUI/GEOM_msg_fr.ts | 89 ++- src/GEOMGUI/GEOM_msg_ja.ts | 93 ++- src/GEOMGUI/GeometryGUI.cxx | 3 + src/GEOMGUI/GeometryGUI_Operations.h | 1 + src/GEOMUtils/CMakeLists.txt | 2 + src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx | 145 +++++ src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx | 61 ++ src/GroupGUI/CMakeLists.txt | 2 + src/GroupGUI/GroupGUI_GroupDlg.cxx | 27 + src/GroupGUI/GroupGUI_GroupDlg.h | 2 + src/MeasureGUI/CMakeLists.txt | 2 + src/MeasureGUI/MeasureGUI.cxx | 4 + .../MeasureGUI_ShapeStatisticsDlg.cxx | 533 ++++++++++++++++++ .../MeasureGUI_ShapeStatisticsDlg.h | 92 +++ 28 files changed, 1199 insertions(+), 17 deletions(-) create mode 100644 doc/salome/gui/GEOM/images/shape_statistics.png create mode 100644 doc/salome/gui/GEOM/images/shape_statistics_simple.png create mode 100644 doc/salome/gui/GEOM/input/shape_statistics_operation.doc create mode 100644 src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx create mode 100644 src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx create mode 100644 src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx create mode 100644 src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h diff --git a/doc/salome/gui/GEOM/images/editgroup.png b/doc/salome/gui/GEOM/images/editgroup.png index c7f55074e27ea482a3fe678945ae82c6b0ea61e4..4501fa61ff4701073ab349387730f3f9ec365f1d 100755 GIT binary patch literal 1753014 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 literal 38874 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 D@P^m% diff --git a/doc/salome/gui/GEOM/images/geomcreategroup.png b/doc/salome/gui/GEOM/images/geomcreategroup.png index 0f67a625c1f772ed7a469793c067a109ff01e0e1..c982f0bc93886bc8de8acdf5d47824c77bc3c99b 100755 GIT binary patch literal 1269739 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�kl~T8bDC0w4ea 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 literal 33690 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 diff --git a/doc/salome/gui/GEOM/images/shape_statistics.png b/doc/salome/gui/GEOM/images/shape_statistics.png new file mode 100644 index 0000000000000000000000000000000000000000..2aaaa9ad37fc46b510b88f13d812e7d05d3cbeb8 GIT binary patch literal 389143 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 b|9s;I`XAc5{%S^J(RGX8^ytFdKKB0s_+vqw literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/images/shape_statistics_simple.png b/doc/salome/gui/GEOM/images/shape_statistics_simple.png new file mode 100644 index 0000000000000000000000000000000000000000..bc2c0767b8f6f143d7a2f0a197447ebd27a4256f GIT binary patch literal 246293 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�ljhpS;NZ>Tq3{ts0?;v7}(?7!C4+$vMUGcOP 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 Statistics dialog box, in the Main Menu select Inspection - > Shape Statistics. + +\image html shape_statistics.png + +In this dialog: +- "Selected objects" standard selection box allows selecting one or more geometrical objects. + +- "Type" combo-box with the following items: "Edges length", "Faces area", "Solids volume". +\note "Type" combo-box includes only parameters applied to the currently selected shape (e.g. "Solids volume" will not be available for face or shell being selected); multiple selection is processed correspondingly (i.e. only types applicable for all selected shapes will be available). + +- "Number of intervals" spin box is used to specify number of distribution histogram ranges. + +- "Scalar range" checkable group box that, when switched ON, allows specifying custom values range used for plotting and creating groups. +\note By default, "Scalar range" controls is empty; pressing "Compute" button allows automatic computing initial range of the chosen parameter. This is needed as computation of the parameters range can be time-consuming for large or complex models. In case of multiple selection, scalar range is computed as common from all selected shapes. + +- "Plot" button opens or uses an opened Plot2d viewer and plots the distribution histogram for the selected shape(s). + +- "Create groups" button allows creating a groups according to the currently specified parameters. The groups names will include numerical values of the range, e.g. "Edges_length_0-20", "Edges_length_20-40", etc. Empty groups are not created. + +- Close dialog box, by pressing Close button. + +*/ diff --git a/doc/salome/gui/GEOM/input/using_measurement_tools.doc b/doc/salome/gui/GEOM/input/using_measurement_tools.doc index 77a5ee4b3..515a94ce4 100644 --- a/doc/salome/gui/GEOM/input/using_measurement_tools.doc +++ b/doc/salome/gui/GEOM/input/using_measurement_tools.doc @@ -19,6 +19,7 @@
  • \subpage managing_dimensions_page "Dimensions"
  • \subpage whatis_page "WhatIs"
  • \subpage inspect_object_operation_page "Inspect Object"
  • +
  • \subpage shape_statistics_operation_page "Shape Statistics"
  • \n To check their integrity: diff --git a/doc/salome/gui/GEOM/input/working_with_groups.doc b/doc/salome/gui/GEOM/input/working_with_groups.doc index 36a0d49a3..df36fd6a2 100644 --- a/doc/salome/gui/GEOM/input/working_with_groups.doc +++ b/doc/salome/gui/GEOM/input/working_with_groups.doc @@ -24,7 +24,7 @@ This functionality is available in OCC viewer only. To create a group of sub-shapes of a geometrical object in the main menu select New entity > Group > Create -\n The following menu will appear: +\n The following dialog box will appear: \image html geomcreategroup.png @@ -101,6 +101,11 @@ In order to filter out some entities: The entities which satisfy entered filtering parameters will be automatically highlighted in the 3D viewer. +\b Plot button into "Filter" group box provides an access +to the \ref shape_statistics_operation_page "Shape Statistics" functionality with simplified look-n-feel: + +\image html shape_statistics_simple.png + \n TUI Command: geompy.CreateGroup(MainShape, ShapeType), where MainShape is a shape for which the group is created, ShapeType is a type of shapes in the created group. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d271e268e..6f830743b 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -43,8 +43,8 @@ IF(SALOME_BUILD_GUI) SET(SUBDIRS_GUI OBJECT DlgRef GEOMFiltersSelection Material GEOMGUI GEOMBase DependencyTree GEOMToolsGUI DisplayGUI BasicGUI PrimitiveGUI GenerationGUI - CurveCreator EntityGUI BuildGUI BooleanGUI TransformationGUI OperationGUI - RepairGUI MeasureGUI GroupGUI BlocksGUI AdvancedGUI + CurveCreator MeasureGUI EntityGUI BuildGUI BooleanGUI TransformationGUI OperationGUI + RepairGUI GroupGUI BlocksGUI AdvancedGUI GEOM_SWIG_WITHIHM ) ENDIF() diff --git a/src/EntityGUI/CMakeLists.txt b/src/EntityGUI/CMakeLists.txt index ecfc09a2d..0bb93f921 100755 --- a/src/EntityGUI/CMakeLists.txt +++ b/src/EntityGUI/CMakeLists.txt @@ -39,6 +39,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/GEOMImpl ${PROJECT_SOURCE_DIR}/src/GEOMGUI ${PROJECT_SOURCE_DIR}/src/GEOMBase + ${PROJECT_SOURCE_DIR}/src/MeasureGUI ${PROJECT_SOURCE_DIR}/src/SKETCHER ${PROJECT_SOURCE_DIR}/src/CurveCreator ${PROJECT_SOURCE_DIR}/src/ShapeRecognition @@ -67,6 +68,7 @@ SET(_link_LIBRARIES DlgRef GEOMSketcher CurveCreator + MeasureGUI ) # optional sources diff --git a/src/EntityGUI/EntityGUI_SubShapeDlg.cxx b/src/EntityGUI/EntityGUI_SubShapeDlg.cxx index 9db5fbab0..598d05de6 100644 --- a/src/EntityGUI/EntityGUI_SubShapeDlg.cxx +++ b/src/EntityGUI/EntityGUI_SubShapeDlg.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -165,6 +166,7 @@ EntityGUI_SubShapeDlg::EntityGUI_SubShapeDlg(GeometryGUI* theGeometryGUI, QWidge myLessFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp); myGreaterFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp); myApplyFilterButton = new QPushButton(tr("GEOM_BUT_APPLY"), myFilterGrp); + myPlotDistributionButton = new QPushButton(tr("GEOM_PLOT_DISTRIBUTION"), myFilterGrp); QGridLayout* filterLayout = new QGridLayout(myFilterGrp); filterLayout->addWidget(myLessFilterCheck, 0, 0); @@ -174,6 +176,7 @@ EntityGUI_SubShapeDlg::EntityGUI_SubShapeDlg(GeometryGUI* theGeometryGUI, QWidge filterLayout->addWidget(myGreaterFilterCombo, 1, 1); filterLayout->addWidget(myGreaterFilterSpin, 1, 2); filterLayout->addWidget(myApplyFilterButton, 0, 3); + filterLayout->addWidget(myPlotDistributionButton, 1, 3); QVBoxLayout* layout = new QVBoxLayout(centralWidget()); layout->setMargin(0); layout->setSpacing(6); @@ -250,6 +253,7 @@ void EntityGUI_SubShapeDlg::Init() connect(GroupPoints->PushButton4, SIGNAL(clicked()), this, SLOT(showOnlySelected())); connect(myApplyFilterButton, SIGNAL(clicked()), this, SLOT(ClickOnOkFilter())); + connect(myPlotDistributionButton, SIGNAL(clicked()), this, SLOT(ClickOnPlot())); connect(myLessFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled())); connect(myGreaterFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled())); @@ -491,6 +495,11 @@ void EntityGUI_SubShapeDlg::SubShapeToggled() GroupPoints->CheckButton1->isChecked() && shapeType() < GEOM::VERTEX); + myPlotDistributionButton->setEnabled( myFilterGrp->isEnabled() && + ( shapeType() == TopAbs_EDGE || + shapeType() == TopAbs_FACE || + shapeType() == TopAbs_SOLID ) ); + activateSelection(); } @@ -936,6 +945,18 @@ void EntityGUI_SubShapeDlg::ClickOnOkFilter() updateButtonState(); } +//================================================================================= +// function : ClickOnPlot() +// purpose : opens "Shape Statistics" dialog box in order to plot sub-shapes distribution. +//================================================================================= +void EntityGUI_SubShapeDlg::ClickOnPlot() +{ + QDialog* dlg = new MeasureGUI_ShapeStatisticsDlg( this, myShape, (TopAbs_ShapeEnum)shapeType() ); + if ( dlg ) { + dlg->show(); + } +} + //================================================================================= // function : MeasureToggled() // purpose : diff --git a/src/EntityGUI/EntityGUI_SubShapeDlg.h b/src/EntityGUI/EntityGUI_SubShapeDlg.h index e3618ac41..c2f14e66e 100644 --- a/src/EntityGUI/EntityGUI_SubShapeDlg.h +++ b/src/EntityGUI/EntityGUI_SubShapeDlg.h @@ -73,6 +73,7 @@ private slots: void showOnlySelected(); void ClickOnOkFilter(); + void ClickOnPlot(); void MeasureToggled(); private: @@ -102,6 +103,7 @@ private: SalomeApp_DoubleSpinBox* myLessFilterSpin; SalomeApp_DoubleSpinBox* myGreaterFilterSpin; QPushButton* myApplyFilterButton; + QPushButton* myPlotDistributionButton; QGroupBox* myFilterGrp; }; diff --git a/src/GEOMBase/GEOMBase.cxx b/src/GEOMBase/GEOMBase.cxx index e10909ddc..0cfe8f6ae 100644 --- a/src/GEOMBase/GEOMBase.cxx +++ b/src/GEOMBase/GEOMBase.cxx @@ -859,7 +859,7 @@ QString GEOMBase::GetEntry( GEOM::GEOM_Object_ptr object ) // Function : PublishSubObject // Purpose : Publish sub-shape under the main object //================================================================ -void GEOMBase::PublishSubObject( GEOM::GEOM_Object_ptr object ) +void GEOMBase::PublishSubObject( GEOM::GEOM_Object_ptr object, const QString& name ) { SalomeApp_Study* study = dynamic_cast( SUIT_Session::session()->activeApplication()->activeStudy() ); if ( study && !CORBA::is_nil( object ) ) { @@ -868,9 +868,9 @@ void GEOMBase::PublishSubObject( GEOM::GEOM_Object_ptr object ) GEOM::GEOM_Object_var father = object->GetMainShape(); QString fatherEntry = GetEntry( father ); if ( entry.isEmpty() && !CORBA::is_nil( father ) && !fatherEntry.isEmpty() ) { - QString name = GetName( object ); + QString aName = !name.isEmpty() ? name : GetName( object ); GeometryGUI::GetGeomGen()->AddInStudy( GeometryGUI::ClientStudyToStudy( studyDS ), - object, name.toLatin1().data(), father.in() ); + object, aName.toLatin1().data(), father.in() ); } } } diff --git a/src/GEOMBase/GEOMBase.h b/src/GEOMBase/GEOMBase.h index 242e5fdcd..69e21e778 100644 --- a/src/GEOMBase/GEOMBase.h +++ b/src/GEOMBase/GEOMBase.h @@ -133,7 +133,7 @@ public : static QString GetEntry( GEOM::GEOM_Object_ptr object ); /* Publish sub-shape under the main object */ - static void PublishSubObject( GEOM::GEOM_Object_ptr object ); + static void PublishSubObject( GEOM::GEOM_Object_ptr object, const QString& name = QString() ); static void Synchronize( QList& left, QList& right ); }; diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index c1e7addb1..c67b290fe 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -431,6 +431,10 @@ Please, select face, shell or solid and try again GEOM_FAST_CHECK_INTERSECTIONS Fast intersection + + GEOM_SHAPE_STATISTICS + Shape Statistics + GEOM_CIRCLE Circle @@ -2556,6 +2560,10 @@ Please, select face, shell or solid and try again MEN_FAST_CHECK_INTERSECTIONS Fast intersection + + MEN_SHAPE_STATISTICS + Shape Statistics + MEN_CHECK_FREE_BNDS Check Free Boundaries @@ -2838,7 +2846,7 @@ Please, select face, shell or solid and try again MEN_MEASURES - Measures + Inspection MEN_MIN_DIST @@ -3591,6 +3599,10 @@ Please, select face, shell or solid and try again STB_FAST_CHECK_INTERSECTIONS Fast intersection + + + STB_SHAPE_STATISTICS + Shape Statistics STB_CHECK_FREE_BNDS @@ -4224,6 +4236,10 @@ Please, select face, shell or solid and try again TOP_FAST_CHECK_INTERSECTIONS Fast intersection + + TOP_SHAPE_STATISTICS + Shape Statistics + TOP_CHECK_FREE_BNDS Check free boundaries @@ -5384,6 +5400,10 @@ shells and solids on the other hand. GEOM_HEALING_STATS_COL_2 Modification + + GEOM_PLOT_DISTRIBUTION + Plot + GeometryGUI @@ -5433,7 +5453,7 @@ shells and solids on the other hand. TOOL_MEASURES - Measures + Inspection TOOL_IMPORTEXPORT @@ -7335,6 +7355,69 @@ Do you want to create new material? Objects And Results + + MeasureGUI_ShapeStatisticsDlg + + GEOM_SHAPE_STATISTICS_TYPE + Type + + + GEOM_SHAPE_STATISTICS_LENGTH + Edges length + + + GEOM_SHAPE_STATISTICS_AREA + Faces area + + + GEOM_SHAPE_STATISTICS_VOLUME + Solids volume + + + GEOM_SHAPE_STATISTICS_NB_INTERVALS + Number of intervals + + + GEOM_SHAPE_STATISTICS_SCALAR_RANGE + Scalar range + + + GEOM_SHAPE_STATISTICS_COMPUTE + Compute + + + GEOM_SHAPE_STATISTICS_MIN + Min + + + GEOM_SHAPE_STATISTICS_MAX + Max + + + GEOM_SHAPE_STATISTICS_CREATE_GROUPS + Create Groups + + + GEOM_SHAPE_STATISTICS_DISTRIBUTION_NB_ENT + Number of entities + + + GEOM_SHAPE_STATISTICS_MIN_ERROR + Set minimal range value or switch-off Scalar range + + + GEOM_SHAPE_STATISTICS_MAX_ERROR + Set maximal range value or switch-off Scalar range + + + GEOM_SHAPE_STATISTICS_MIN_MAX_ERROR + Minimal range value can not be more than maximal + + + GEOM_MSG_GROUPS_CREATED + %1 groups created + + TransformationGUI_ExtensionDlg diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 69786b158..0ab7e34fc 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -431,6 +431,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau GEOM_FAST_CHECK_INTERSECTIONS Intersection rapide + + GEOM_SHAPE_STATISTICS + Shape Statistics + GEOM_CIRCLE Cercle @@ -2512,6 +2516,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau MEN_FAST_CHECK_INTERSECTIONS Intersection rapide + + MEN_SHAPE_STATISTICS + Shape Statistics + MEN_CHECK_FREE_BNDS Contrôler les contours libres @@ -2794,7 +2802,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau MEN_MEASURES - Mesures + Inspection MEN_MIN_DIST @@ -3539,7 +3547,11 @@ Choisissez une face, une coque ou un solide et essayez de nouveau STB_FAST_CHECK_INTERSECTIONS Intersection rapide - + + + STB_SHAPE_STATISTICS + Shape Statistics + STB_CHECK_FREE_BNDS Vérifier les contours libres @@ -4164,6 +4176,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau TOP_FAST_CHECK_INTERSECTIONS Intersection rapide + + TOP_SHAPE_STATISTICS + Shape Statistics + TOP_CHECK_FREE_BNDS Valider les contours libres @@ -5316,6 +5332,10 @@ le paramètre '%1' aux préférences du module Géométrie.GEOM_HEALING_STATS_COL_2 Modification + + GEOM_PLOT_DISTRIBUTION + Plot + GeometryGUI @@ -5365,7 +5385,7 @@ le paramètre '%1' aux préférences du module Géométrie. TOOL_MEASURES - Informations + Inspection TOOL_IMPORTEXPORT @@ -7268,6 +7288,69 @@ Voulez-vous en créer un nouveau ? Objets et résultats + + MeasureGUI_ShapeStatisticsDlg + + GEOM_SHAPE_STATISTICS_TYPE + Type + + + GEOM_SHAPE_STATISTICS_LENGTH + Edges length + + + GEOM_SHAPE_STATISTICS_AREA + Faces area + + + GEOM_SHAPE_STATISTICS_VOLUME + Solids volume + + + GEOM_SHAPE_STATISTICS_NB_INTERVALS + Number of intervals + + + GEOM_SHAPE_STATISTICS_SCALAR_RANGE + Scalar range + + + GEOM_SHAPE_STATISTICS_COMPUTE + Compute + + + GEOM_SHAPE_STATISTICS_MIN + Min + + + GEOM_SHAPE_STATISTICS_MAX + Max + + + GEOM_SHAPE_STATISTICS_CREATE_GROUPS + Create Groups + + + GEOM_SHAPE_STATISTICS_DISTRIBUTION_NB_ENT + Number of entities + + + GEOM_SHAPE_STATISTICS_MIN_ERROR + Set minimal range value or switch-off Scalar range + + + GEOM_SHAPE_STATISTICS_MAX_ERROR + Set maximal range value or switch-off Scalar range + + + GEOM_SHAPE_STATISTICS_MIN_MAX_ERROR + Minimal range value can not be more than maximal + + + GEOM_MSG_GROUPS_CREATED + %1 groups created + + TransformationGUI_ExtensionDlg diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts index 6b5668ec8..75807fcc7 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -415,6 +415,10 @@ GEOM_FAST_CHECK_INTERSECTIONS Fast intersection + + GEOM_SHAPE_STATISTICS + Shape Statistics + GEOM_CHECK_SELF_INTERSECTIONS_FAILED 自己交差の検出に失敗しました @@ -2467,6 +2471,10 @@ MEN_FAST_CHECK_INTERSECTIONS Fast intersection + + MEN_SHAPE_STATISTICS + Shape Statistics + MEN_CHECK_FREE_BNDS 自由境界の確認 @@ -2749,7 +2757,7 @@ MEN_MEASURES - 計測 + Inspection MEN_MIN_DIST @@ -3482,7 +3490,11 @@ STB_FAST_CHECK_INTERSECTIONS Fast intersection - + + + STB_SHAPE_STATISTICS + Shape Statistics + STB_CHECK_FREE_BNDS 自由境界をチェック @@ -4100,8 +4112,12 @@ 自己交差の確認 - TOP_FAST_CHECK_INTERSECTIONS - Fast intersection + TOP_FAST_CHECK_INTERSECTIONS + Fast intersection + + + TOP_SHAPE_STATISTICS + Shape Statistics TOP_CHECK_FREE_BNDS @@ -5211,6 +5227,10 @@ GEOM_NO_SHAPES_SELECTED There are no shapes that meet filtering parameters + + GEOM_PLOT_DISTRIBUTION + Plot + GeometryGUI @@ -5260,7 +5280,7 @@ TOOL_MEASURES - Measures + Inspection TOOL_IMPORTEXPORT @@ -7153,6 +7173,69 @@ Objects And Results + + MeasureGUI_ShapeStatisticsDlg + + GEOM_SHAPE_STATISTICS_TYPE + Type + + + GEOM_SHAPE_STATISTICS_LENGTH + Edges length + + + GEOM_SHAPE_STATISTICS_AREA + Faces area + + + GEOM_SHAPE_STATISTICS_VOLUME + Solids volume + + + GEOM_SHAPE_STATISTICS_NB_INTERVALS + Number of intervals + + + GEOM_SHAPE_STATISTICS_SCALAR_RANGE + Scalar range + + + GEOM_SHAPE_STATISTICS_COMPUTE + Compute + + + GEOM_SHAPE_STATISTICS_MIN + Min + + + GEOM_SHAPE_STATISTICS_MAX + Max + + + GEOM_SHAPE_STATISTICS_CREATE_GROUPS + Create Groups + + + GEOM_SHAPE_STATISTICS_DISTRIBUTION_NB_ENT + Number of entities + + + GEOM_SHAPE_STATISTICS_MIN_ERROR + Set minimal range value or switch-off Scalar range + + + GEOM_SHAPE_STATISTICS_MAX_ERROR + Set maximal range value or switch-off Scalar range + + + GEOM_SHAPE_STATISTICS_MIN_MAX_ERROR + Minimal range value can not be more than maximal + + + GEOM_MSG_GROUPS_CREATED + %1 groups created + + TransformationGUI_ExtensionDlg diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 790e65a7d..25832ed53 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -644,6 +644,7 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam ) case GEOMOp::OpCheckSelfInters: // MENU MEASURE - CHECK SELF INTERSECTIONS case GEOMOp::OpFastCheckInters: // MENU MEASURE - FAST CHECK INTERSECTIONS case GEOMOp::OpManageDimensions: // MENU MEASURE - MANAGE DIMENSIONS + case GEOMOp::OpShapeStatistics: // MENU MEASURE - SHAPE STATISTICS case GEOMOp::OpShowAllDimensions: // POPUP MENU - SHOW ALL DIMENSIONS case GEOMOp::OpHideAllDimensions: // POPUP MENU - HIDE ALL DIMENSIONS libName = "MeasureGUI"; @@ -1025,6 +1026,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( GEOMOp::OpGetNonBlocks, "GET_NON_BLOCKS" ); createGeomAction( GEOMOp::OpCheckSelfInters, "CHECK_SELF_INTERSECTIONS" ); createGeomAction( GEOMOp::OpFastCheckInters, "FAST_CHECK_INTERSECTIONS" ); + createGeomAction( GEOMOp::OpShapeStatistics, "SHAPE_STATISTICS" ); #ifdef _DEBUG_ // PAL16821 createGeomAction( GEOMOp::OpCheckGeom, "CHECK_GEOMETRY" ); @@ -1288,6 +1290,7 @@ void GeometryGUI::initialize( CAM_Application* app ) createMenu( GEOMOp::OpCheckSelfInters, measurId, -1 ); createMenu( GEOMOp::OpFastCheckInters, measurId, -1 ); createMenu( GEOMOp::OpInspectObj, measurId, -1 ); + createMenu( GEOMOp::OpShapeStatistics, measurId, -1 ); int toolsId = createMenu( tr( "MEN_TOOLS" ), -1, -1, 50 ); #if defined(_DEBUG_) || defined(_DEBUG) // PAL16821 diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h index 915f5d1f1..865ac91d9 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -200,6 +200,7 @@ namespace GEOMOp { OpHideAllDimensions = 5016, // POPUP MENU - HIDE ALL DIMENSIONS OpFastCheckInters = 5017, // MENU MEASURES - FAST CHECK INTERSECTIONS OpInspectObj = 5018, // MENU MEASURES - INSPECT OBJECT + OpShapeStatistics = 5019, // MENU MEASURES - SHAPE STATISTICS // GroupGUI --------------------//-------------------------------- OpGroupCreate = 6000, // MENU GROUP - CREATE OpGroupEdit = 6001, // MENU GROUP - EDIT diff --git a/src/GEOMUtils/CMakeLists.txt b/src/GEOMUtils/CMakeLists.txt index 039990ab7..a2bbfd9d0 100755 --- a/src/GEOMUtils/CMakeLists.txt +++ b/src/GEOMUtils/CMakeLists.txt @@ -53,6 +53,7 @@ SET(GEOMUtils_HEADERS GEOMUtils.hxx GEOMUtils_Hatcher.hxx GEOMUtils_HTrsfCurve2d.hxx + GEOMUtils_ShapeStatistics.hxx GEOMUtils_Trsf2d.hxx GEOMUtils_TrsfCurve2d.hxx GEOMUtils_XmlHandler.hxx @@ -63,6 +64,7 @@ SET(GEOMUtils_SOURCES GEOMUtils.cxx GEOMUtils_Hatcher.cxx GEOMUtils_HTrsfCurve2d.cxx + GEOMUtils_ShapeStatistics.cxx GEOMUtils_Trsf2d.cxx GEOMUtils_TrsfCurve2d.cxx GEOMUtils_XmlHandler.cxx diff --git a/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx b/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx new file mode 100644 index 000000000..81ae5aeba --- /dev/null +++ b/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx @@ -0,0 +1,145 @@ +// Copyright (C) 2015 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, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : GEOMUtils_ShapeStatisticsDlg.cxx +// Author : Alexander KOVALEV, OPEN CASCADE S.A.S. + +#include "GEOMUtils_ShapeStatistics.hxx" + +#include +#include +#include +#include +#include + +namespace GEOMUtils +{ +//================================================================================= +// function : ComputeMeasures() +// purpose : gets measures of the given type for list of shapes in the range +//================================================================================= + std::map ComputeMeasures( std::list shapes, + TopAbs_ShapeEnum entity, + Range &range) +{ + bool hasRange = (range.min != -1.0); // -1.0 means that range must not be used + if ( !hasRange ) + range.min = 1e+32, range.max = 0.0; + // list of measures of entities + std::map measures; + + std::list::const_iterator it; + for ( it = shapes.begin(); it != shapes.end(); ++it ) { + double aMeasure; + TopTools_IndexedMapOfShape aSubShapesMap; + TopExp::MapShapes(*it, aSubShapesMap); // map of all global indices + TopTools_IndexedMapOfShape aMx; + TopExp::MapShapes( *it, entity, aMx ); // map of current type sub-shape indices + int aNbS = aMx.Extent(); + int index = -1; + for ( int i = 1; i <= aNbS; ++i ) { + aMeasure = 0.0; + const TopoDS_Shape& aSubShape = aMx( i ); + //Get the measure: length, area or volume + GProp_GProps LProps, SProps, VProps; + if ( entity == TopAbs_EDGE ) { + BRepGProp::LinearProperties( aSubShape, LProps ); + aMeasure = LProps.Mass(); + } else if ( entity == TopAbs_FACE ) { + BRepGProp::SurfaceProperties( aSubShape, SProps ); + aMeasure = SProps.Mass(); + } else if ( entity == TopAbs_SOLID ) { + BRepGProp::VolumeProperties( aSubShape, VProps ); + aMeasure = VProps.Mass(); + } + // Don't pass sub-shapes with out of range measure, if range is used + if ( hasRange ) { + if ( aMeasure < range.min || aMeasure > range.max ) + continue; + } else { + // get range min and max + if ( aMeasure < range.min ) range.min = aMeasure; + if ( aMeasure > range.max ) range.max = aMeasure; + } + // get global index of sub-shape + index = aSubShapesMap.FindIndex( aSubShape ); + // keep measures to distribute it + measures[index] = aMeasure; + } + } + return measures; +} + +//================================================================================= +// function : ComputeDistribution() +// purpose : gets distribution data for single shape +//================================================================================= +Distribution ComputeDistribution( TopoDS_Shape shape, + TopAbs_ShapeEnum entity, + int intervals, + Range range) +{ + std::list aShapes; + aShapes.push_back( shape ); + return ComputeDistribution( aShapes, entity, intervals, range ); +} + +//================================================================================= +// function : ComputeDistribution() +// purpose : gets distribution data for list of shapes +//================================================================================= +Distribution ComputeDistribution( std::list shapes, + TopAbs_ShapeEnum entity, + int nbIntervals, + Range range) +{ + // get list of measures and compute range (if it was not specified) + std::map measures = ComputeMeasures( shapes, entity, range ); + + // compute a step + double aStep = (range.max - range.min) / nbIntervals; + + // compute distribution in intervals + Distribution aDistr; + std::map::iterator dit; + for ( int i = 0; i < nbIntervals; i++ ) { + Range localRange; // range of current interval + localRange.min = range.min + ( i * aStep ); + localRange.max = range.min + ( (i+1) * aStep ); + localRange.count = 0; + + std::vector indicesToErase; + for ( dit = measures.begin(); dit != measures.end(); dit++ ) { + if ( ( dit->second >= localRange.min && dit->second < localRange.max ) || + ( i == nbIntervals-1 && dit->second == localRange.max ) ) { + localRange.count++; + localRange.indices.push_back( dit->first ); + // measure is in interval, so remove it from map of search + indicesToErase.push_back( dit->first ); + } + } + aDistr.push_back( localRange ); + for( int j=0; j < indicesToErase.size(); j++ ) + measures.erase( indicesToErase[j] ); + } + + return aDistr; +} + +} //namespace GEOMUtils diff --git a/src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx b/src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx new file mode 100644 index 000000000..703050e51 --- /dev/null +++ b/src/GEOMUtils/GEOMUtils_ShapeStatistics.hxx @@ -0,0 +1,61 @@ +// Copyright (C) 2015 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, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : GEOMUtils_ShapeStatisticsDlg.hxx +// Author : Alexander KOVALEV, OPEN CASCADE S.A.S. + +#ifndef _GEOMUtils_ShapeStatistics_HXX_ +#define _GEOMUtils_ShapeStatistics_HXX_ + +#include +#include +#include + +#include + +namespace GEOMUtils +{ + // struct to store range data + typedef struct { double min; double max; long count; std::list indices; } Range; + // distribution is a set of ranges + typedef std::vector Distribution; + + // function to get measures of entities and compute range for list of shapes + Standard_EXPORT std::map ComputeMeasures( + std::list shapes, + TopAbs_ShapeEnum entity, + Range &range ); + + // function to get distribution data for single shape + Standard_EXPORT Distribution ComputeDistribution( + TopoDS_Shape shape, + TopAbs_ShapeEnum entity, + int intervals, + Range range ); + + // function to get distribution data for list of shapes + Standard_EXPORT Distribution ComputeDistribution( + std::list shapes, + TopAbs_ShapeEnum entity, + int intervals, + Range range ); + +} + +#endif // _GEOMUtils_ShapeStatistics_HXX_ diff --git a/src/GroupGUI/CMakeLists.txt b/src/GroupGUI/CMakeLists.txt index acf593702..73e18271b 100755 --- a/src/GroupGUI/CMakeLists.txt +++ b/src/GroupGUI/CMakeLists.txt @@ -39,6 +39,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/GEOMImpl ${PROJECT_SOURCE_DIR}/src/GEOMGUI ${PROJECT_SOURCE_DIR}/src/GEOMBase + ${PROJECT_SOURCE_DIR}/src/MeasureGUI ${PROJECT_SOURCE_DIR}/src/DlgRef ${PROJECT_BINARY_DIR}/src/DlgRef ${CMAKE_CURRENT_SOURCE_DIR} @@ -56,6 +57,7 @@ ADD_DEFINITIONS( SET(_link_LIBRARIES GEOMBase GEOMUtils + MeasureGUI ) # --- resources --- diff --git a/src/GroupGUI/GroupGUI_GroupDlg.cxx b/src/GroupGUI/GroupGUI_GroupDlg.cxx index 82a51075e..a13977ef6 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.cxx +++ b/src/GroupGUI/GroupGUI_GroupDlg.cxx @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -200,6 +201,7 @@ GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QW myLessFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp); myGreaterFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp); myApplyFilterButton = new QPushButton(tr("GEOM_BUT_APPLY"), myFilterGrp); + myPlotDistributionButton = new QPushButton(tr("GEOM_PLOT_DISTRIBUTION"), myFilterGrp); QGridLayout* filterLayout = new QGridLayout(myFilterGrp); filterLayout->addWidget(myLessFilterCheck, 0, 0); @@ -209,6 +211,7 @@ GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QW filterLayout->addWidget(myGreaterFilterCombo, 1, 1); filterLayout->addWidget(myGreaterFilterSpin, 1, 2); filterLayout->addWidget(myApplyFilterButton, 0, 3); + filterLayout->addWidget(myPlotDistributionButton, 1, 3); QVBoxLayout* layout = new QVBoxLayout(centralWidget()); layout->setMargin(0); layout->setSpacing(6); @@ -326,6 +329,7 @@ void GroupGUI_GroupDlg::Init() connect(myIdList, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged())); connect(myApplyFilterButton, SIGNAL(clicked()), this, SLOT(ClickOnOkFilter())); + connect(myPlotDistributionButton, SIGNAL(clicked()), this, SLOT(ClickOnPlot())); connect(myLessFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled())); connect(myGreaterFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled())); @@ -1135,6 +1139,16 @@ void GroupGUI_GroupDlg::updateState (bool isAdd) subSelectionWay() == ALL_SUBSHAPES && myIsShapeType && getShapeType() != TopAbs_VERTEX); + // manage of 'Plot' button access + GEOM::GEOM_IShapesOperations_var aShOp = getGeomEngine()->GetIShapesOperations( getStudyId() ); + GEOM::ListOfLong_var aSubShapes = aShOp->SubShapeAllIDs( myMainObj, getShapeType(), false ); + bool hasCurrentEntities = aSubShapes->length() > 0; + myPlotDistributionButton->setEnabled( myFilterGrp->isEnabled() && + myIsShapeType && + ( getShapeType() == TopAbs_EDGE || + getShapeType() == TopAbs_FACE || + getShapeType() == TopAbs_SOLID ) && + hasCurrentEntities ); if (subSelectionWay() == ALL_SUBSHAPES) setInPlaceObj(GEOM::GEOM_Object::_nil()); } @@ -1423,6 +1437,19 @@ void GroupGUI_GroupDlg::ClickOnOkFilter() updateState(true); } +//================================================================================= +// function : ClickOnPlot() +// purpose : opens "Shape Statistics" dialog box in order to plot sub-shapes distribution. +//================================================================================= +void GroupGUI_GroupDlg::ClickOnPlot() +{ + TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj); + QDialog* dlg = new MeasureGUI_ShapeStatisticsDlg( this, aMainShape, getShapeType() ); + if ( dlg ) { + dlg->show(); + } +} + void GroupGUI_GroupDlg::MeasureToggled() { myLessFilterSpin->setEnabled(myLessFilterCheck->isChecked()); diff --git a/src/GroupGUI/GroupGUI_GroupDlg.h b/src/GroupGUI/GroupGUI_GroupDlg.h index ad8f4e159..231ea033a 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.h +++ b/src/GroupGUI/GroupGUI_GroupDlg.h @@ -83,6 +83,7 @@ private slots: void showOnlySelected(); void selectionChanged(); void ClickOnOkFilter(); + void ClickOnPlot(); void MeasureToggled(); private: @@ -133,6 +134,7 @@ private: SalomeApp_DoubleSpinBox* myLessFilterSpin; SalomeApp_DoubleSpinBox* myGreaterFilterSpin; QPushButton* myApplyFilterButton; + QPushButton* myPlotDistributionButton; QGroupBox* myFilterGrp; }; diff --git a/src/MeasureGUI/CMakeLists.txt b/src/MeasureGUI/CMakeLists.txt index c7ab327c1..31e2375ac 100755 --- a/src/MeasureGUI/CMakeLists.txt +++ b/src/MeasureGUI/CMakeLists.txt @@ -129,6 +129,7 @@ SET(_moc_HEADERS MeasureGUI_ManageDimensionsDlg.h MeasureGUI_CreateDimensionDlg.h MeasureGUI_DimensionInteractor.h + MeasureGUI_ShapeStatisticsDlg.h ) # header files / uic wrappings @@ -163,6 +164,7 @@ SET(MeasureGUI_SOURCES MeasureGUI_DimensionCreateTool.cxx MeasureGUI_DimensionInteractor.cxx MeasureGUI_DimensionFilter.cxx + MeasureGUI_ShapeStatisticsDlg.cxx ${_moc_SOURCES} ${_uic_files} ) diff --git a/src/MeasureGUI/MeasureGUI.cxx b/src/MeasureGUI/MeasureGUI.cxx index 37c8ed4b2..1ab692d32 100644 --- a/src/MeasureGUI/MeasureGUI.cxx +++ b/src/MeasureGUI/MeasureGUI.cxx @@ -53,6 +53,7 @@ #include "MeasureGUI_FastCheckIntersectionsDlg.h" // Method FAST CHECK INTERSCTIONS #include "MeasureGUI_PointDlg.h" // Method POINTCOORDINATES #include "MeasureGUI_ManageDimensionsDlg.h" // Method MANAGEDIMENSIONS +#include "MeasureGUI_ShapeStatisticsDlg.h" // Method SHAPE STATISTICS #include @@ -129,6 +130,9 @@ bool MeasureGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent ) case GEOMOp::OpFastCheckInters: dlg = new MeasureGUI_FastCheckIntersectionsDlg( getGeometryGUI(), parent ); break; // FAST CHECK INTERSCTIONS + case GEOMOp::OpShapeStatistics: + dlg = new MeasureGUI_ShapeStatisticsDlg( parent ); + break; // FAST CHECK INTERSCTIONS case GEOMOp::OpPointCoordinates: dlg = new MeasureGUI_PointDlg( getGeometryGUI(), parent ); break; // POINT COORDINATES diff --git a/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx new file mode 100644 index 000000000..9387cf4a8 --- /dev/null +++ b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.cxx @@ -0,0 +1,533 @@ +// Copyright (C) 2015 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, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : MeasureGUI_ShapeStatisticsDlg.cxx +// Author : Alexander KOVALEV, OPEN CASCADE S.A.S. + +// internal includes +#include "MeasureGUI_ShapeStatisticsDlg.h" + +// GEOM includes +#include +#include +#include +#include + +// GUI includes +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +// Qt includes +#include +#include +#include +#include + +// Qtx includes +#include + +// OCC includes +#include + +#include + +//=========================================================================== +// class : MeasureGUI_ShapeStatisticsDlg() +//=========================================================================== +MeasureGUI_ShapeStatisticsDlg::MeasureGUI_ShapeStatisticsDlg( QWidget* parent, TopoDS_Shape aShape, TopAbs_ShapeEnum aSubShapeType ) + : GEOMBase_Helper( SUIT_Session::session()->activeApplication()->desktop() ), + QDialog( parent ), + myHistogram ( 0 ) +{ + myShapes.push_back( aShape ); + + QIcon iconSelect( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) ); + + setWindowTitle( tr( "GEOM_SHAPE_STATISTICS" ) ); + setAttribute( Qt::WA_DeleteOnClose ); + + myApp = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() ); + + QVBoxLayout* topLayout = new QVBoxLayout( this ); + + QGridLayout* settingsLayout = new QGridLayout(); + + /********************** Selected Objects **********************/ + + QLabel* objsLabel = new QLabel( tr( "GEOM_SELECTED_OBJECTS" ), this ); + QPushButton* selBtn = new QPushButton( this ); + selBtn->setIcon( iconSelect ); + myEditMainShape = new QLineEdit( this ); + myEditMainShape->setReadOnly(true); + + settingsLayout->addWidget( objsLabel, 0, 0 ); + settingsLayout->addWidget( selBtn, 0, 1 ); + settingsLayout->addWidget( myEditMainShape, 0, 2 ); + + if ( !aShape.IsNull() ) { + objsLabel->hide(); + selBtn->hide(); + myEditMainShape->hide(); + } + + /********************** Type **********************/ + + QLabel* typeLabel = new QLabel( tr( "GEOM_SHAPE_STATISTICS_TYPE" ), this ); + myCBTypes = new QtxComboBox( this ); + myCBTypes->setCleared( true ); + if ( aSubShapeType != TopAbs_SHAPE ) { + fillTypes( aSubShapeType == TopAbs_EDGE, + aSubShapeType == TopAbs_FACE, + aSubShapeType == TopAbs_SOLID ); + myCBTypes->setEnabled( false ); + } + + settingsLayout->addWidget( typeLabel, 1, 0 ); + settingsLayout->addWidget( myCBTypes, 1, 2 ); + + /********************** Number of intervals **********************/ + + QLabel* nbIntervalsLabel = new QLabel( tr( "GEOM_SHAPE_STATISTICS_NB_INTERVALS" ), this ); + myNbIntervals = new QtxIntSpinBox( 1, 1000, 1, this ); + myNbIntervals->setValue( 10 ); + + settingsLayout->addWidget( nbIntervalsLabel, 2, 0 ); + settingsLayout->addWidget( myNbIntervals, 2, 2 ); + + /********************** Scalar Range **********************/ + + myScalarRangeBox = new QGroupBox( tr( "GEOM_SHAPE_STATISTICS_SCALAR_RANGE" ), this ); + myScalarRangeBox->setCheckable( true ); + myScalarRangeBox->setChecked( false ); + QLabel* minLabel = new QLabel( tr( "GEOM_SHAPE_STATISTICS_MIN" ), this ); + myMin = new QLineEdit( this ); + QtxDoubleValidator* aValid = new QtxDoubleValidator( this ); + aValid->setBottom( 0.0 ); + myMin->setValidator( aValid ); + QLabel* maxLabel = new QLabel( tr( "GEOM_SHAPE_STATISTICS_MAX" ), this ); + myMax = new QLineEdit( this ); + myMax->setValidator( aValid ); + + QPushButton* buttonCompute = new QPushButton( tr( "GEOM_SHAPE_STATISTICS_COMPUTE" ), this ); + connect( buttonCompute, SIGNAL( clicked() ), this, SLOT( clickOnCompute() ) ); + + QGridLayout* scalarRangeLayout = new QGridLayout(); + scalarRangeLayout->setMargin( 11 ); settingsLayout->setSpacing( 6 ); + + scalarRangeLayout->addWidget( minLabel, 0, 0 ); + scalarRangeLayout->addWidget( myMin, 0, 1 ); + scalarRangeLayout->addWidget( maxLabel, 1, 0 ); + scalarRangeLayout->addWidget( myMax, 1, 1 ); + scalarRangeLayout->addWidget( buttonCompute, 0, 2, 2, 1 ); + + myScalarRangeBox->setLayout( scalarRangeLayout ); + + /********************** Buttons **********************/ + + myButtonPlot = new QPushButton( tr( "GEOM_PLOT_DISTRIBUTION" ), this ); + myButtonPlot->setDefault( true ); + myButtonCreateGr = new QPushButton( tr( "GEOM_SHAPE_STATISTICS_CREATE_GROUPS" ), this ); + QPushButton* buttonClose = new QPushButton( tr( "GEOM_BUT_CLOSE" ), this ); + QPushButton* buttonHelp = new QPushButton( tr( "GEOM_BUT_HELP" ), this ); + + QHBoxLayout* buttonsLayout = new QHBoxLayout(); + buttonsLayout->addWidget( myButtonPlot ); + buttonsLayout->addWidget( myButtonCreateGr ); + buttonsLayout->addWidget( buttonClose ); + buttonsLayout->addWidget( buttonHelp ); + + if ( !aShape.IsNull() ) { + myButtonCreateGr->hide(); + } + /********************** Layouting **********************/ + + topLayout->addLayout( settingsLayout ); + topLayout->addWidget( myScalarRangeBox ); + topLayout->addLayout( buttonsLayout ); + + // Signals and slots connections + + connect( selBtn, SIGNAL( clicked() ), this, SLOT( onEditMainShape() ) ); + + connect( myButtonPlot, SIGNAL( clicked() ), this, SLOT( clickOnPlot() ) ); + connect( myButtonCreateGr, SIGNAL( clicked() ), this, SLOT( clickOnCreateGroups() ) ); + + connect( buttonClose, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( clickOnHelp() ) ); + + connect(myApp->selectionMgr(), + SIGNAL(currentSelectionChanged()), this, SLOT(onEditMainShape())); + + if ( aShape.IsNull() ) + onEditMainShape(); +} + +//=========================================================================== +// function : ~MeasureGUI_ShapeStatisticsDlg() +// purpose : Destroys the object and frees any allocated resources +//=========================================================================== +MeasureGUI_ShapeStatisticsDlg::~MeasureGUI_ShapeStatisticsDlg() +{ +} + +//================================================================================= +// function : createOperation +// purpose : +//================================================================================= +GEOM::GEOM_IOperations_ptr MeasureGUI_ShapeStatisticsDlg::createOperation() +{ + return getGeomEngine()->GetIGroupOperations(getStudyId()); +} + +#define RETURN_WITH_MSG(a, b) \ + if (!(a)) { \ + theMessage += (b); \ + return false; \ + } + +//================================================================ +// Function : getFather +// Purpose : Get father object for object to be added in study +// (called with addInStudy method) +//================================================================ +GEOM::GEOM_Object_ptr MeasureGUI_ShapeStatisticsDlg::getFather(GEOM::GEOM_Object_ptr theObj) +{ + GEOM::GEOM_Object_var aFatherObj; + if (theObj->GetType() == GEOM_GROUP) { + GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation()); + aFatherObj = anOper->GetMainShape(theObj); + } + return aFatherObj._retn(); +} + +//================================================================================= +// function : getSourceObjects +// purpose : virtual method to get source objects +//================================================================================= +QList MeasureGUI_ShapeStatisticsDlg::getSourceObjects() +{ + QList res; + res << myMainObj; + return res; +} + +//================================================================================= +// function : onEditMainShape() +// purpose : called when selection button was clicked +//================================================================================= +void MeasureGUI_ShapeStatisticsDlg::onEditMainShape() +{ + // restore initial parameters for dialog box + myEditMainShape->setText(""); + myEditMainShape->setFocus(); + + //get shapes from selection + QList selShapes = getSelected( TopAbs_SHAPE, -1 ); + + myButtonPlot->setEnabled( !selShapes.isEmpty() ); + myButtonCreateGr->setEnabled( selShapes.count() == 1 ); + + if ( !selShapes.isEmpty() ) { + if ( selShapes.count() == 1 ) + myMainObj = selShapes[0]; + QString aName = selShapes.count() > 1 ? QString( "%1_objects").arg( selShapes.count() ) : GEOMBase::GetName( myMainObj.get() ); + myEditMainShape->setText( aName ); + } + + updateTypes( selShapes ); +} + +//================================================================================= +// function : currentType() +// purpose : returns currently selected type of shapes in 'Type' combobox +//================================================================================= +void MeasureGUI_ShapeStatisticsDlg::fillTypes( bool hasEdges, bool hasFaces, bool hasSolids ) +{ + if ( hasEdges ) + myCBTypes->addItem( tr("GEOM_SHAPE_STATISTICS_LENGTH"), (int)TopAbs_EDGE ); + if ( hasFaces ) + myCBTypes->addItem( tr("GEOM_SHAPE_STATISTICS_AREA"), (int)TopAbs_FACE ); + if ( hasSolids ) + myCBTypes->addItem( tr("GEOM_SHAPE_STATISTICS_VOLUME"), (int)TopAbs_SOLID ); + + myCBTypes->setEnabled( myCBTypes->count() > 0 ); +} + +//================================================================================= +// function : updateTypes() +// purpose : update 'Type' combobox with available types +//================================================================================= +void MeasureGUI_ShapeStatisticsDlg::updateTypes( QList theShapes ) +{ + myCBTypes->clear(); + myCBTypes->setEnabled( false ); + + int hasEdges = -1, hasFaces = -1, hasSolids = -1; + + myShapes.clear(); + // get types of the shapes and its sub-shapes + foreach( GEOM::GeomObjPtr aShapePtr, theShapes ) { + if ( !aShapePtr ) + return; + + TopoDS_Shape aShape; + if ( !GEOMBase::GetShape( aShapePtr.get(), aShape ) || aShape.IsNull() ) + return; + + myShapes.push_back( aShape ); + + GEOM::ListOfLong_var aSubShapes; + GEOM::GEOM_IShapesOperations_var aShOp = getGeomEngine()->GetIShapesOperations( getStudyId() ); + if ( hasEdges != 0 ) + hasEdges = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_EDGE ) > 0; + if ( hasFaces != 0 ) + hasEdges = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_FACE ) > 0; + if ( hasSolids != 0 ) + hasEdges = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_SOLID ) > 0; + } + fillTypes( hasEdges, hasFaces, hasSolids ); +} + +//================================================================================= +// function : currentType() +// purpose : returns currently selected type of shapes in 'Type' combobox +//================================================================================= +TopAbs_ShapeEnum MeasureGUI_ShapeStatisticsDlg::currentType() +{ + return (TopAbs_ShapeEnum)( myCBTypes->itemData( myCBTypes->currentIndex() ).toInt() ); +} + +//================================================================================= +// function : clickOnPlot() +// purpose : called when Plot button was clicked +//================================================================================= +bool MeasureGUI_ShapeStatisticsDlg::isValid(QString& theMessage) +{ + if ( myScalarRangeBox->isChecked() ) { + RETURN_WITH_MSG( !myMin->text().isEmpty(), tr("GEOM_SHAPE_STATISTICS_MIN_ERROR") ) + RETURN_WITH_MSG( !myMax->text().isEmpty(), tr("GEOM_SHAPE_STATISTICS_MAX_ERROR") ) + RETURN_WITH_MSG( myMin->text().toDouble() <= myMax->text().toDouble(), tr("GEOM_SHAPE_STATISTICS_MIN_MAX_ERROR") ) + } + return true; +} +//================================================================================= +// function : clickOnPlot() +// purpose : called when Plot button was clicked +//================================================================================= +void MeasureGUI_ShapeStatisticsDlg::clickOnPlot() +{ + GEOMUtils::Range aRange; + if ( myScalarRangeBox->isChecked() ) { + QString msg; + if ( !isValid( msg ) ) { + showError( msg ); + return; + } + aRange.min = myMin->text().toDouble(); + aRange.max = myMax->text().toDouble(); + } else { + aRange.min = -1.0; // flag that range is empty + aRange.max = -1.0; // flag that range is empty + } + + GEOMUtils::Distribution aShapesDistr = + GEOMUtils::ComputeDistribution( myShapes, currentType(), myNbIntervals->value(), aRange ); + + QList xVals, yVals; + double width = -1, min = -1; + double xmin = 1e+32, xmax = 0.0, ymax = 0.0; + int i=0; + GEOMUtils::Distribution::const_iterator it; + for (it = aShapesDistr.begin(); it != aShapesDistr.end(); it++) { + GEOMUtils::Range ran = *it; + if ( width < 0 ) width = ran.max - ran.min; // bar width + if ( min < 0 ) min = ran.min; // global min + xVals << width / 2. + i*width + min; // get a middle of bar + yVals << ran.count; + // get global boundary max values + if ( ran.min < xmin ) xmin = ran.min; + if ( ran.max > xmax ) xmax = ran.max; + if ( ran.count > ymax ) ymax = ran.count; + i++; + } + + // plot the computed distribution + SUIT_ViewManager* aViewManager = myApp->getViewManager( Plot2d_Viewer::Type(), true ); // create if necessary + if( !aViewManager ) + return; + Plot2d_ViewWindow* aViewWnd = dynamic_cast(aViewManager->getActiveView()); + if( !aViewWnd ) + return; + Plot2d_ViewFrame* aPlot = aViewWnd->getViewFrame(); + if ( !aPlot ) + return; + + aPlot->EraseAll(); + + // create or reuse histogram + if( !myHistogram ) + myHistogram = new Plot2d_Histogram(); + else + myHistogram->clearAllPoints(); + // set histogram parameters + myHistogram->setData( xVals, yVals ); + if ( width != 0.0 ) + myHistogram->setWidth( width ); + myHistogram->setAutoAssign(true); + myHistogram->setName( myEditMainShape->text() ); + myHistogram->setHorTitle( myCBTypes->currentText() ); + myHistogram->setVerTitle( tr("GEOM_SHAPE_STATISTICS_DISTRIBUTION_NB_ENT") ); + myHistogram->setColor( QColor(0, 85, 0) ); + // display histogram + aPlot->displayObject( myHistogram, true ); + if ( width == 0.0 ) // only one X value + aPlot->fitAll(); + else + aPlot->fitData( 0, xmin, xmax, 0.0, ymax ); +} + +//================================================================================= +// function : clickOnCompute() +// purpose : called when Compute button was clicked +//================================================================================= +void MeasureGUI_ShapeStatisticsDlg::clickOnCompute() +{ + GEOMUtils::Range aRange; + aRange.min = -1.0; // flag that range is empty + aRange.max = -1.0; // flag that range is empty + std::map measures = GEOMUtils::ComputeMeasures( myShapes, currentType(), aRange ); + if ( measures.size() != 0 ) { + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + int aPrecision = resMgr->integerValue( "Geometry", "length_precision", 6 ); + myMin->setText( DlgRef::PrintDoubleValue( aRange.min, aPrecision ) ); + myMax->setText( DlgRef::PrintDoubleValue( aRange.max, aPrecision ) ); + } +} + +//================================================================================= +// function : clickOnCreateGroups() +// purpose : called when Create Groups button was clicked +//================================================================================= +void MeasureGUI_ShapeStatisticsDlg::clickOnCreateGroups() +{ + onAccept(false, false, false); +} + +//================================================================================= +// function : execute(ObjectList& objects) +// purpose : +//================================================================================= +bool MeasureGUI_ShapeStatisticsDlg::execute(ObjectList& objects) +{ + if ( myMainObj.isNull() ) + return false; + + GEOM::GroupOpPtr anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation()); + + GEOMUtils::Range aRange; + if ( myScalarRangeBox->isChecked() ) { + QString msg; + if ( !isValid( msg ) ) { + showError( msg ); + return false; + } + aRange.min = myMin->text().toDouble(); + aRange.max = myMax->text().toDouble(); + } else { + aRange.min = -1.0; // flag that range is empty + aRange.max = -1.0; // flag that range is empty + } + + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + int aPrecision = resMgr->integerValue( "Geometry", "length_precision", 6 ); + QString aTypePrefix = myCBTypes->currentText().replace(' ', '_'); + QString objIOR, aMin, aMax, aGroupName; + SalomeApp_Study* study = getStudy(); + + GEOMUtils::Distribution aShapesDistr = + GEOMUtils::ComputeDistribution( myShapes, currentType(), myNbIntervals->value(), aRange ); + + int nbGroups = 0; + + GEOMUtils::Distribution::const_iterator it; + for (it = aShapesDistr.begin(); it != aShapesDistr.end(); it++) { + std::list idList = (*it).indices; + int nn = idList.size(); + if ( nn > 0 ) { + GEOM::ListOfLong_var aNewList = new GEOM::ListOfLong; + aNewList->length(nn); + int ii = 0; + std::list::const_iterator id_it; + for ( id_it = idList.begin(); id_it != idList.end(); id_it++ ) { + aNewList[ii++] = *id_it; + } + + // Create an empty group + GEOM::GEOM_Object_var aGroup; + aGroup = anOper->CreateGroup( myMainObj.get(), currentType() ); + + if (CORBA::is_nil(aGroup) || !anOper->IsDone()) + return false; + + // Add sub-shapes into group + anOper->UnionIDs(aGroup, aNewList); + if (!anOper->IsDone()) + return false; + + // publish group + aMin = DlgRef::PrintDoubleValue( (*it).min, aPrecision ); + aMax = DlgRef::PrintDoubleValue( (*it).max, aPrecision ); + aGroupName = aTypePrefix + "_" + aMin + "_" + aMax; + GEOMBase::PublishSubObject( aGroup, aGroupName ); + + // this is needed just to avoid error message + objects.push_back(aGroup._retn()); + + nbGroups++; + } + } + + SUIT_MessageBox::information( this, tr( "INF_INFO" ), tr( "GEOM_MSG_GROUPS_CREATED" ).arg( nbGroups ) ); + + return true; +} + +//================================================================================= +// function : clickOnHelp() +// purpose : called when Help button was clicked +//================================================================================= +void MeasureGUI_ShapeStatisticsDlg::clickOnHelp() +{ + GeometryGUI* aGeomGUI = dynamic_cast( myApp->module( "Geometry" ) ); + myApp->onHelpContextModule( aGeomGUI ? myApp->moduleName( aGeomGUI->moduleName() ) : QString(""), "shape_statistics_operation_page.html" ); +} diff --git a/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h new file mode 100644 index 000000000..80131321b --- /dev/null +++ b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h @@ -0,0 +1,92 @@ +// Copyright (C) 2015 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, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// GEOM GEOMGUI : GUI for Geometry component +// File : MeasureGUI_ShapeStatisticsDlg.h +// Author : Alexander KOVALEV, Open CASCADE (alexander.kovalev@opencascade.com) +// +#ifndef MEASUREGUI_SHAPESTATISTICSDLG_H +#define MEASUREGUI_SHAPESTATISTICSDLG_H + +// GEOM includes +#include +#include "GEOM_GenericObjPtr.h" + +// Qt includes +#include +#include +#include +#include + +// Qtx includes +#include +#include + +class Plot2d_Histogram; + +//========================================================================== +// class : MeasureGUI_ShapeStatisticsDlg +// purpose : +//========================================================================== + +class MeasureGUI_ShapeStatisticsDlg : public QDialog, public GEOMBase_Helper +{ + Q_OBJECT + +public: + MeasureGUI_ShapeStatisticsDlg( QWidget*, TopoDS_Shape aShape = TopoDS_Shape(), TopAbs_ShapeEnum aSubShapeType = TopAbs_SHAPE ); + ~MeasureGUI_ShapeStatisticsDlg(); + +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 QList getSourceObjects(); + +private slots: + void onEditMainShape(); + void clickOnCompute(); + void clickOnPlot(); + void clickOnCreateGroups(); + void clickOnHelp(); + +private: + void fillTypes( bool, bool, bool ); + void updateTypes( QList theShapes ); + TopAbs_ShapeEnum currentType(); + +private: + SalomeApp_Application* myApp; + QLineEdit* myEditMainShape; + QtxComboBox* myCBTypes; + std::list myShapes; + GEOM::GeomObjPtr myMainObj; + QtxIntSpinBox* myNbIntervals; + QGroupBox* myScalarRangeBox; + QLineEdit* myMin; + QLineEdit* myMax; + QPushButton* myButtonPlot; + QPushButton* myButtonCreateGr; + Plot2d_Histogram* myHistogram; + +}; + +#endif // MEASUREGUI_SHAPESTATISTICSDLG_H From 7760eb2714f5ede8f546ef7fc2740684018a7da0 Mon Sep 17 00:00:00 2001 From: eap Date: Mon, 27 Apr 2015 17:03:33 +0300 Subject: [PATCH 02/54] 22852: EDF 9937 GEOM: Kind of shape unrecognized when importing step files --- src/GEOMAlgo/CMakeLists.txt | 4 + src/GEOMAlgo/FILES | 13 +- src/GEOMAlgo/GEOMAlgo.cdl | 0 src/GEOMAlgo/GEOMAlgo_AlgoTools.cxx | 95 +-- src/GEOMAlgo/GEOMAlgo_FinderShapeOn.cxx | 2 - src/GEOMAlgo/GEOMAlgo_FinderShapeOn1.cxx | 21 +- src/GEOMAlgo/GEOMAlgo_FinderShapeOn2.cxx | 8 + src/GEOMAlgo/GEOMAlgo_GetInPlace_1.cxx | 48 +- src/GEOMAlgo/GEOMAlgo_GlueDetector.cxx | 8 +- src/GEOMAlgo/GEOMAlgo_Gluer.cxx | 189 +++--- src/GEOMAlgo/GEOMAlgo_Gluer2.cxx | 9 +- src/GEOMAlgo/GEOMAlgo_KindOfDef.hxx | 37 ++ src/GEOMAlgo/GEOMAlgo_KindOfName.hxx | 3 +- src/GEOMAlgo/GEOMAlgo_KindOfShape.hxx | 2 - src/GEOMAlgo/GEOMAlgo_ShapeInfo.cxx | 140 ++-- src/GEOMAlgo/GEOMAlgo_ShapeInfo.hxx | 11 +- src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller.cxx | 144 ++--- src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx | 684 ++++++++++---------- src/GEOMAlgo/GEOMAlgo_ShellSolid.cxx | 60 +- src/GEOMAlgo/GEOMAlgo_Splitter.cxx | 2 +- src/GEOMAlgo/GEOMAlgo_SurfaceTools.cxx | 42 +- 21 files changed, 789 insertions(+), 733 deletions(-) mode change 100755 => 100644 src/GEOMAlgo/GEOMAlgo.cdl mode change 100755 => 100644 src/GEOMAlgo/GEOMAlgo_AlgoTools.cxx mode change 100755 => 100644 src/GEOMAlgo/GEOMAlgo_Gluer.cxx create mode 100644 src/GEOMAlgo/GEOMAlgo_KindOfDef.hxx mode change 100755 => 100644 src/GEOMAlgo/GEOMAlgo_Splitter.cxx diff --git a/src/GEOMAlgo/CMakeLists.txt b/src/GEOMAlgo/CMakeLists.txt index f44663a10..d2b6024ab 100755 --- a/src/GEOMAlgo/CMakeLists.txt +++ b/src/GEOMAlgo/CMakeLists.txt @@ -59,7 +59,10 @@ SET(GEOMAlgo_HEADERS GEOMAlgo_DataMapOfPassKeyInteger.hxx GEOMAlgo_DataMapOfShapeMapOfShape.hxx GEOMAlgo_DataMapOfShapePnt.hxx + GEOMAlgo_FinderShapeOn.hxx + GEOMAlgo_FinderShapeOn1.hxx GEOMAlgo_FinderShapeOn2.hxx + GEOMAlgo_FinderShapeOnQuad.hxx GEOMAlgo_GetInPlace.hxx GEOMAlgo_GetInPlaceAPI.hxx GEOMAlgo_GlueAnalyser.hxx @@ -77,6 +80,7 @@ SET(GEOMAlgo_HEADERS GEOMAlgo_IndexedDataMapOfShapeState.hxx GEOMAlgo_KindOfBounds.hxx GEOMAlgo_KindOfClosed.hxx + GEOMAlgo_KindOfDef.hxx GEOMAlgo_KindOfName.hxx GEOMAlgo_KindOfShape.hxx GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx diff --git a/src/GEOMAlgo/FILES b/src/GEOMAlgo/FILES index 85d55bcfc..91e59813f 100644 --- a/src/GEOMAlgo/FILES +++ b/src/GEOMAlgo/FILES @@ -11,25 +11,28 @@ GEOMAlgo_ShellSolid.cxx GEOMAlgo_AlgoTools.hxx GEOMAlgo_AlgoTools.cxx GEOMAlgo_AlgoTools_1.cxx -GEOMAlgo_AlgoTools_2.cxx GEOMAlgo_SolidSolid.hxx GEOMAlgo_SolidSolid.cxx GEOMAlgo_ShapeAlgo.hxx GEOMAlgo_ShapeAlgo.cxx +GEOMAlgo_FinderShapeOn.hxx +GEOMAlgo_FinderShapeOn.cxx +GEOMAlgo_FinderShapeOn1.hxx +GEOMAlgo_FinderShapeOn1.cxx GEOMAlgo_HAlgo.hxx GEOMAlgo_HAlgo.cxx GEOMAlgo_Clsf.hxx GEOMAlgo_Clsf.cxx GEOMAlgo_ClsfBox.hxx GEOMAlgo_ClsfBox.cxx -GEOMAlgo_ClsfQuad.hxx -GEOMAlgo_ClsfQuad.cxx GEOMAlgo_ClsfSolid.hxx GEOMAlgo_ClsfSolid.cxx GEOMAlgo_ClsfSurf.hxx GEOMAlgo_ClsfSurf.cxx GEOMAlgo_FinderShapeOn2.hxx GEOMAlgo_FinderShapeOn2.cxx +GEOMAlgo_FinderShapeOnQuad.hxx +GEOMAlgo_FinderShapeOnQuad.cxx GEOMAlgo_Gluer.hxx GEOMAlgo_Gluer.cxx GEOMAlgo_GlueAnalyser.hxx @@ -50,8 +53,6 @@ GEOMAlgo_GetInPlace.cxx GEOMAlgo_GetInPlace_1.cxx GEOMAlgo_GetInPlace_2.cxx GEOMAlgo_GetInPlace_3.cxx -GEOMAlgo_GetInPlaceAPI.hxx -GEOMAlgo_GetInPlaceAPI.cxx GEOMAlgo_Splitter.hxx GEOMAlgo_Splitter.cxx GEOMAlgo_ShapeInfoFiller.hxx @@ -106,3 +107,5 @@ GEOMAlgo_ShapeInfo.cxx GEOMAlgo_IndexedDataMapOfShapeShapeInfo.hxx Basics_OCCTVersion.hxx + +GEOMAlgo_KindOfDef.hxx diff --git a/src/GEOMAlgo/GEOMAlgo.cdl b/src/GEOMAlgo/GEOMAlgo.cdl old mode 100755 new mode 100644 diff --git a/src/GEOMAlgo/GEOMAlgo_AlgoTools.cxx b/src/GEOMAlgo/GEOMAlgo_AlgoTools.cxx old mode 100755 new mode 100644 index 8c2a1cd1b..ed44029e3 --- a/src/GEOMAlgo/GEOMAlgo_AlgoTools.cxx +++ b/src/GEOMAlgo/GEOMAlgo_AlgoTools.cxx @@ -93,15 +93,15 @@ static Standard_Integer& iCnt); static void CopySource(const TopoDS_Shape& aS, - TopTools_IndexedDataMapOfShapeShape& aMapSS, - TopoDS_Shape& aSC); + TopTools_IndexedDataMapOfShapeShape& aMapSS, + TopoDS_Shape& aSC); //======================================================================= //function : CopyShape //purpose : //======================================================================= void GEOMAlgo_AlgoTools::CopyShape(const TopoDS_Shape& aS, - TopoDS_Shape& aSC) + TopoDS_Shape& aSC) { TopTools_IndexedDataMapOfShapeShape aMapSS; // @@ -112,8 +112,8 @@ void GEOMAlgo_AlgoTools::CopyShape(const TopoDS_Shape& aS, //purpose : //======================================================================= void GEOMAlgo_AlgoTools::CopyShape(const TopoDS_Shape& aS, - TopoDS_Shape& aSC, - TopTools_IndexedDataMapOfShapeShape& aMapSS) + TopoDS_Shape& aSC, + TopTools_IndexedDataMapOfShapeShape& aMapSS) { CopySource(aS, aMapSS, aSC); } @@ -172,9 +172,9 @@ void CopySource(const TopoDS_Shape& aS, //purpose : //======================================================================= void GEOMAlgo_AlgoTools::FaceNormal (const TopoDS_Face& aF, - const Standard_Real U, - const Standard_Real V, - gp_Vec& aN) + const Standard_Real U, + const Standard_Real V, + gp_Vec& aN) { gp_Pnt aPnt ; gp_Vec aD1U, aD1V; @@ -330,7 +330,7 @@ Standard_Integer GEOMAlgo_AlgoTools::BuildPCurveForEdgeOnFace // purpose: //======================================================================= void GEOMAlgo_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType, - TopoDS_Shape& theC) + TopoDS_Shape& theC) { BRep_Builder aBB; // @@ -399,9 +399,9 @@ Standard_Boolean GEOMAlgo_AlgoTools::IsUPeriodic(const Handle(Geom_Surface) &aS //purpose : //======================================================================= void GEOMAlgo_AlgoTools::RefinePCurveForEdgeOnFace(const TopoDS_Edge& aE, - const TopoDS_Face& aF, - const Standard_Real aUMin, - const Standard_Real aUMax) + const TopoDS_Face& aF, + const Standard_Real aUMin, + const Standard_Real aUMax) { Standard_Real aT1, aT2, aTx, aUx, aTol; gp_Pnt2d aP2D; @@ -546,7 +546,7 @@ Standard_Boolean GEOMAlgo_AlgoTools::ProjectPointOnShape //purpose : //======================================================================= void GEOMAlgo_AlgoTools::PointOnEdge(const TopoDS_Edge& aE, - gp_Pnt& aP3D) + gp_Pnt& aP3D) { Standard_Real aTx, aT1, aT2; // @@ -559,8 +559,8 @@ void GEOMAlgo_AlgoTools::PointOnEdge(const TopoDS_Edge& aE, //purpose : //======================================================================= void GEOMAlgo_AlgoTools::PointOnEdge(const TopoDS_Edge& aE, - const Standard_Real aT, - gp_Pnt& aP3D) + const Standard_Real aT, + gp_Pnt& aP3D) { Standard_Real aT1, aT2; Handle(Geom_Curve) aC3D; @@ -573,9 +573,9 @@ void GEOMAlgo_AlgoTools::PointOnEdge(const TopoDS_Edge& aE, //purpose : //======================================================================= void GEOMAlgo_AlgoTools::PointOnFace(const TopoDS_Face& aF, - const Standard_Real aU, - const Standard_Real aV, - gp_Pnt& aP3D) + const Standard_Real aU, + const Standard_Real aV, + gp_Pnt& aP3D) { Handle(Geom_Surface) aS; // @@ -587,7 +587,7 @@ void GEOMAlgo_AlgoTools::PointOnFace(const TopoDS_Face& aF, //purpose : //======================================================================= void GEOMAlgo_AlgoTools::PointOnFace(const TopoDS_Face& aF, - gp_Pnt& aP3D) + gp_Pnt& aP3D) { Standard_Real aU, aV, aUMin, aUMax, aVMin, aVMax; // @@ -603,7 +603,7 @@ void GEOMAlgo_AlgoTools::PointOnFace(const TopoDS_Face& aF, //purpose : //======================================================================= void GEOMAlgo_AlgoTools::PointOnShape(const TopoDS_Shape& aS, - gp_Pnt& aP3D) + gp_Pnt& aP3D) { TopAbs_ShapeEnum aType; // @@ -700,7 +700,7 @@ Standard_Integer GEOMAlgo_AlgoTools::FindSDShapes return 0; // Nothing to do } // - while(1) { + for(;;) { aNbEProcessed=aMProcessed.Extent(); if (aNbEProcessed==aNbE) { break; @@ -909,8 +909,8 @@ void GetCount(const TopoDS_Shape& aS, //purpose : //======================================================================= Standard_Integer GEOMAlgo_AlgoTools::PntInFace(const TopoDS_Face& aF, - gp_Pnt& theP, - gp_Pnt2d& theP2D) + gp_Pnt& theP, + gp_Pnt2d& theP2D) { Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint; Standard_Integer iErr, aIx, aNbDomains, i; @@ -935,8 +935,8 @@ Standard_Integer GEOMAlgo_AlgoTools::PntInFace(const TopoDS_Face& aF, // Geom2dHatch_Intersector aIntr(aTotArcIntr, aTolTangfIntr); Geom2dHatch_Hatcher aHatcher(aIntr, - aTolHatch2D, aTolHatch3D, - Standard_True, Standard_False); + aTolHatch2D, aTolHatch3D, + Standard_True, Standard_False); // iErr=0; aEpsT=1.e-12; @@ -991,30 +991,33 @@ Standard_Integer GEOMAlgo_AlgoTools::PntInFace(const TopoDS_Face& aF, } // // 4. + aVx=aVMin; aNbDomains=aHatcher.NbDomains(aIx); - for (i=1; i<=aNbDomains; ++i) { - const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ; - bHasFirstPoint=aDomain.HasFirstPoint(); - if (!bHasFirstPoint) { - iErr=5; - return iErr; - } - // - aV1=aDomain.FirstPoint().Parameter(); - // - bHasSecondPoint=aDomain.HasSecondPoint(); - if (!bHasSecondPoint) { - iErr=6; - return iErr; - } - // - aV2=aDomain.SecondPoint().Parameter(); - // - aVx=IntTools_Tools::IntermediatePoint(aV1, aV2); - // - break; + if (!aNbDomains) { + iErr=5; + return iErr; } // + i=1; + const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ; + bHasFirstPoint=aDomain.HasFirstPoint(); + if (!bHasFirstPoint) { + iErr=5; + return iErr; + } + // + aV1=aDomain.FirstPoint().Parameter(); + // + bHasSecondPoint=aDomain.HasSecondPoint(); + if (!bHasSecondPoint) { + iErr=6; + return iErr; + } + // + aV2=aDomain.SecondPoint().Parameter(); + // + aVx=IntTools_Tools::IntermediatePoint(aV1, aV2); + // aS->D0(aUx, aVx, aPx); // theP2D.SetCoord(aUx, aVx); diff --git a/src/GEOMAlgo/GEOMAlgo_FinderShapeOn.cxx b/src/GEOMAlgo/GEOMAlgo_FinderShapeOn.cxx index e721aca85..4db6801de 100644 --- a/src/GEOMAlgo/GEOMAlgo_FinderShapeOn.cxx +++ b/src/GEOMAlgo/GEOMAlgo_FinderShapeOn.cxx @@ -62,7 +62,6 @@ #include #include -//#include #include #include @@ -300,7 +299,6 @@ void GEOMAlgo_FinderShapeOn::Find(const TopoDS_Shape& aS) { myErrorStatus=0; // - Standard_Boolean bIsDone; Standard_Integer i, iErr; TopAbs_State aSts[]={TopAbs_IN, TopAbs_OUT, TopAbs_ON}; TopTools_ListIteratorOfListOfShape aIt; diff --git a/src/GEOMAlgo/GEOMAlgo_FinderShapeOn1.cxx b/src/GEOMAlgo/GEOMAlgo_FinderShapeOn1.cxx index 6487a04ac..f2f7fe0d5 100644 --- a/src/GEOMAlgo/GEOMAlgo_FinderShapeOn1.cxx +++ b/src/GEOMAlgo/GEOMAlgo_FinderShapeOn1.cxx @@ -309,6 +309,9 @@ void GEOMAlgo_FinderShapeOn1::ProcessEdges() aType1=myGAS.GetType(); // TopExp::MapShapes(myShape, TopAbs_EDGE, aM); + // + bIsConformState=Standard_False; + // aNb=aM.Extent(); for (i=1; i<=aNb; ++i) { GEOMAlgo_ListOfPnt aLP; @@ -427,6 +430,8 @@ void GEOMAlgo_FinderShapeOn1::ProcessFaces() } } // + bIsConformState=Standard_False; + // aExp.Init(aF, TopAbs_EDGE); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape& aE=aExp.Current(); @@ -500,6 +505,9 @@ void GEOMAlgo_FinderShapeOn1::ProcessSolids() const TopoDS_Shape& aSd=aM(i); aMF.Clear(); TopExp::MapShapes(aSd, TopAbs_FACE, aMF); + // + bIsConformState=Standard_False; + // aNbF=aMF.Extent(); for (j=1; j<=aNbF; ++j) { const TopoDS_Shape& aF=aMF(j); @@ -660,7 +668,6 @@ void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Face& aF, }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) }// if (!aNb && myNbPntsMin) { } -//modified by NIZNHY-PKV Thu Jan 26 09:56:20 2012f //======================================================================= //function : InnerPoints //purpose : @@ -676,7 +683,6 @@ void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE, aLP.Clear(); InnerPoints(aE, aNbPntsMin, aLP); } -//modified by NIZNHY-PKV Thu Jan 26 09:56:32 2012t //======================================================================= //function : InnerPoints //purpose : @@ -702,16 +708,6 @@ void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE, return; } // - //modified by NIZNHY-PKV Thu Jan 26 09:51:20 2012f - /* - aNbT=myNbPntsMin+1; - dT=(aT2-aT1)/aNbT; - for (j=1; j<=aNbPntsMin; ++j) { - aT=aT1+j*dT; - aC3D->D0(aT, aP); - aLP.Append(aP); - } - */ aNbT=aNbPntsMin+1; dT=(aT2-aT1)/aNbT; for (j=1; jD0(aT, aP); aLP.Append(aP); } - //modified by NIZNHY-PKV Thu Jan 26 09:51:24 2012t } //======================================================================= diff --git a/src/GEOMAlgo/GEOMAlgo_FinderShapeOn2.cxx b/src/GEOMAlgo/GEOMAlgo_FinderShapeOn2.cxx index 439caec37..e2e34de0f 100644 --- a/src/GEOMAlgo/GEOMAlgo_FinderShapeOn2.cxx +++ b/src/GEOMAlgo/GEOMAlgo_FinderShapeOn2.cxx @@ -362,6 +362,8 @@ void GEOMAlgo_FinderShapeOn2::ProcessEdges() // const TopoDS_Edge& aE=TopoDS::Edge(aM(i)); // + bIsConformState=Standard_False; + // aExp.Init(aE, TopAbs_VERTEX); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape& aV=aExp.Current(); @@ -475,6 +477,9 @@ void GEOMAlgo_FinderShapeOn2::ProcessFaces() } } // + // + bIsConformState=Standard_False; + // aExp.Init(aF, TopAbs_EDGE); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape& aE=aExp.Current(); @@ -558,6 +563,9 @@ void GEOMAlgo_FinderShapeOn2::ProcessSolids() const TopoDS_Shape& aSd=aM(i); aMF.Clear(); TopExp::MapShapes(aSd, TopAbs_FACE, aMF); + // + bIsConformState=Standard_False; + // aNbF=aMF.Extent(); for (j=1; j<=aNbF; ++j) { const TopoDS_Shape& aF=aMF(j); diff --git a/src/GEOMAlgo/GEOMAlgo_GetInPlace_1.cxx b/src/GEOMAlgo/GEOMAlgo_GetInPlace_1.cxx index c717997e3..03416d293 100644 --- a/src/GEOMAlgo/GEOMAlgo_GetInPlace_1.cxx +++ b/src/GEOMAlgo/GEOMAlgo_GetInPlace_1.cxx @@ -239,7 +239,6 @@ Standard_Integer PntInSolid(const TopoDS_Solid& aZ, gp_Pnt aPx; gp_Pnt2d aP2Dx; gp_Vec aDNx; - TopoDS_Face aF; TopExp_Explorer aExp; // @@ -247,9 +246,8 @@ Standard_Integer PntInSolid(const TopoDS_Solid& aZ, aCoef=10.; // aExp.Init (aZ, TopAbs_FACE); - for (; aExp.More() ; aExp.Next()) { + if (aExp.More()) { aF=*((TopoDS_Face*)&aExp.Current()); - break; } // iErr=PntInFace(aF, aPx, aP2Dx); @@ -368,29 +366,31 @@ Standard_Integer PntInFace(const TopoDS_Face& aF, // // 4. aNbDomains=aHatcher.NbDomains(aIx); - for (i=1; i<=aNbDomains; ++i) { - const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ; - bHasFirstPoint=aDomain.HasFirstPoint(); - if (!bHasFirstPoint) { - iErr=5; - return iErr; - } - // - aV1=aDomain.FirstPoint().Parameter(); - // - bHasSecondPoint=aDomain.HasSecondPoint(); - if (!bHasSecondPoint) { - iErr=6; - return iErr; - } - // - aV2=aDomain.SecondPoint().Parameter(); - // - aVx=IntTools_Tools::IntermediatePoint(aV1, aV2); - // - break; + if (!aNbDomains) { + iErr=5; + return iErr; } // + i=1; + const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ; + bHasFirstPoint=aDomain.HasFirstPoint(); + if (!bHasFirstPoint) { + iErr=5; + return iErr; + } + // + aV1=aDomain.FirstPoint().Parameter(); + // + bHasSecondPoint=aDomain.HasSecondPoint(); + if (!bHasSecondPoint) { + iErr=6; + return iErr; + } + // + aV2=aDomain.SecondPoint().Parameter(); + // + aVx=IntTools_Tools::IntermediatePoint(aV1, aV2); + // aS->D0(aUx, aVx, aPx); // theP2D.SetCoord(aUx, aVx); diff --git a/src/GEOMAlgo/GEOMAlgo_GlueDetector.cxx b/src/GEOMAlgo/GEOMAlgo_GlueDetector.cxx index e5ca7dfbd..bad1fe01f 100644 --- a/src/GEOMAlgo/GEOMAlgo_GlueDetector.cxx +++ b/src/GEOMAlgo/GEOMAlgo_GlueDetector.cxx @@ -90,7 +90,6 @@ GEOMAlgo_GlueDetector::GEOMAlgo_GlueDetector() //======================================================================= GEOMAlgo_GlueDetector::~GEOMAlgo_GlueDetector() {} -//modified by NIZNHY-PKV Tue Mar 13 12:26:50 2012f //======================================================================= //function : StickedShapes //purpose : @@ -100,7 +99,6 @@ const TopTools_IndexedDataMapOfShapeListOfShape& { return myStickedShapes; } -//modified by NIZNHY-PKV Tue Mar 13 12:26:54 2012t //======================================================================= //function : Perform //purpose : @@ -124,12 +122,10 @@ void GEOMAlgo_GlueDetector::Perform() return; } // - //modified by NIZNHY-PKV Wed Mar 14 08:00:09 2012f CheckDetected(); if (myErrorStatus) { return; } - //modified by NIZNHY-PKV Wed Mar 14 08:00:12 2012t // DetectEdges(); if (myErrorStatus) { @@ -206,7 +202,7 @@ void GEOMAlgo_GlueDetector::DetectVertices() TColStd_MapIteratorOfMapOfInteger aIt1; // aMIP.Add(i); - while(1) { + for(;;) { aNbIP=aMIP.Extent(); aIt1.Initialize(aMIP); for(; aIt1.More(); aIt1.Next()) { @@ -460,7 +456,6 @@ void GEOMAlgo_GlueDetector::EdgePassKey(const TopoDS_Edge& aE, // aPK.SetShapes(aLV); } -//modified by NIZNHY-PKV Tue Mar 13 09:54:18 2012f //======================================================================= //function : CheckDetected //purpose : @@ -607,4 +602,3 @@ Standard_Integer CheckAncesstors // return iRet; } -//modified by NIZNHY-PKV Tue Mar 13 09:54:59 2012t diff --git a/src/GEOMAlgo/GEOMAlgo_Gluer.cxx b/src/GEOMAlgo/GEOMAlgo_Gluer.cxx old mode 100755 new mode 100644 index 3c1d629ca..d9f807906 --- a/src/GEOMAlgo/GEOMAlgo_Gluer.cxx +++ b/src/GEOMAlgo/GEOMAlgo_Gluer.cxx @@ -20,10 +20,10 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File: GEOMAlgo_Gluer.cxx -// Created: Sat Dec 04 12:45:53 2004 -// Author: Peter KURNEV -// +// File: GEOMAlgo_Gluer.cxx +// Created: Sat Dec 04 12:45:53 2004 +// Author: Peter KURNEV +// // #include @@ -100,7 +100,7 @@ // static void GetSubShapes(const TopoDS_Shape& aS, - TopTools_IndexedMapOfShape& aMSS); + TopTools_IndexedMapOfShape& aMSS); //======================================================================= //function : GEOMAlgo_Gluer @@ -228,10 +228,7 @@ void GEOMAlgo_Gluer::MakeVertices() TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm; TopTools_DataMapOfShapeListOfShape aMVV; GEOMAlgo_IndexedDataMapOfIntegerShape aMIS; - //modified by NIZNHY-PKV Thu Jan 21 10:03:07 2010f - //GEOMAlgo_IndexedDataMapOfShapeBox aMSB; GEOMAlgo_IndexedDataMapOfShapeBndSphere aMSB; - //modified by NIZNHY-PKV Thu Jan 21 10:03:10 2010t // GEOMAlgo_BndSphereTreeSelector aSelector; GEOMAlgo_BndSphereTree aBBTree; @@ -278,57 +275,54 @@ void GEOMAlgo_Gluer::MakeVertices() TColStd_MapIteratorOfMapOfInteger aIt1; // aMIP.Add(i); - while(1) { + for(;;) { aNbIP=aMIP.Extent(); aIt1.Initialize(aMIP); for(; aIt1.More(); aIt1.Next()) { - aIP=aIt1.Key(); - if (aMIPC.Contains(aIP)) { - continue; - } - // - const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP); - //modified by NIZNHY-PKV Thu Jan 21 10:04:09 2010f - const GEOMAlgo_BndSphere& aBoxVP=aMSB.FindFromKey(aVP); - //const Bnd_Box& aBoxVP=aMSB.FindFromKey(aVP); - //modified by NIZNHY-PKV Thu Jan 21 10:04:11 2010t - // - aSelector.Clear(); - aSelector.SetBox(aBoxVP); - // - aNbVSD=aBBTree.Select(aSelector); - if (!aNbVSD) { - continue; // it must not be - } - // - const TColStd_ListOfInteger& aLI=aSelector.Indices(); - // - aIt.Initialize(aLI); - for (; aIt.More(); aIt.Next()) { - aIP1=aIt.Value(); - if (aMIP.Contains(aIP1)) { - continue; - } - aMIP1.Add(aIP1); - } //for (; aIt.More(); aIt.Next()) { + aIP=aIt1.Key(); + if (aMIPC.Contains(aIP)) { + continue; + } + // + const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP); + const GEOMAlgo_BndSphere& aBoxVP=aMSB.FindFromKey(aVP); + // + aSelector.Clear(); + aSelector.SetBox(aBoxVP); + // + aNbVSD=aBBTree.Select(aSelector); + if (!aNbVSD) { + continue; // it must not be + } + // + const TColStd_ListOfInteger& aLI=aSelector.Indices(); + // + aIt.Initialize(aLI); + for (; aIt.More(); aIt.Next()) { + aIP1=aIt.Value(); + if (aMIP.Contains(aIP1)) { + continue; + } + aMIP1.Add(aIP1); + } //for (; aIt.More(); aIt.Next()) { }//for(; aIt1.More(); aIt1.Next()) { // aNbIP1=aMIP1.Extent(); if (!aNbIP1) { - break; + break; } // aIt1.Initialize(aMIP); for(; aIt1.More(); aIt1.Next()) { - aIP=aIt1.Key(); - aMIPC.Add(aIP); + aIP=aIt1.Key(); + aMIPC.Add(aIP); } // aMIP.Clear(); aIt1.Initialize(aMIP1); for(; aIt1.More(); aIt1.Next()) { - aIP=aIt1.Key(); - aMIP.Add(aIP); + aIP=aIt1.Key(); + aMIP.Add(aIP); } aMIP1.Clear(); }// while(1) @@ -344,13 +338,13 @@ void GEOMAlgo_Gluer::MakeVertices() else { // SD vertices founded [ aMIPC ] aIt1.Initialize(aMIPC); for(j=0; aIt1.More(); aIt1.Next(), ++j) { - aIP=aIt1.Key(); - const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP); - if (!j) { - aVF=aVP; - } - aLVSD.Append(aVP); - aMVProcessed.Add(aVP); + aIP=aIt1.Key(); + const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP); + if (!j) { + aVF=aVP; + } + aLVSD.Append(aVP); + aMVProcessed.Add(aVP); } } myImages.Bind(aVF, aLVSD); @@ -395,7 +389,7 @@ void GEOMAlgo_Gluer::MakeVertices() for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aVSD=aItS.Value(); if (!myOrigins.IsBound(aVSD)) { - myOrigins.Bind(aVSD, aV); + myOrigins.Bind(aVSD, aV); } } } @@ -468,7 +462,8 @@ void GEOMAlgo_Gluer::MakeSubShapes (const TopoDS_Shape& theShape, aER.Orientation(TopAbs_FORWARD); if (!BRep_Tool::Degenerated(aER)) { // orient image - Standard_Boolean bIsToReverse=GEOMAlgo_AlgoTools::IsSplitToReverse(aER, aE, myContext); + Standard_Boolean bIsToReverse= + GEOMAlgo_AlgoTools::IsSplitToReverse(aER, aE, myContext); if (bIsToReverse) { aER.Reverse(); } @@ -490,8 +485,7 @@ void GEOMAlgo_Gluer::MakeSubShapes (const TopoDS_Shape& theShape, aBB.Add(theResult, aShapeR); } } - else - { + else { if (myKeepNonSolids) { // just add image const TopoDS_Shape& aShapeR = myOrigins.Find(theShape); @@ -554,12 +548,12 @@ void GEOMAlgo_Gluer::MakeShells() const TopoDS_Face& aF=TopoDS::Face(aExp.Current()); aFR=TopoDS::Face(myOrigins.Find(aF)); if (aFR.IsSame(aF)) { - aBB.Add(aNewShell, aF); - continue; + aBB.Add(aNewShell, aF); + continue; } bIsToReverse=IsToReverse(aFR, aF); if (bIsToReverse) { - aFR.Reverse(); + aFR.Reverse(); } aBB.Add(aNewShell, aFR); } @@ -660,25 +654,25 @@ void GEOMAlgo_Gluer::MakeShapes(const TopAbs_ShapeEnum aType) if (aNbSDF==1) { bHasNewSubShape=HasNewSubShape(aS1); if (!bHasNewSubShape) { - aNewShape=aS1; - aNewShape.Orientation(TopAbs_FORWARD); + aNewShape=aS1; + aNewShape.Orientation(TopAbs_FORWARD); } } // if (bHasNewSubShape) { if (aType==TopAbs_FACE) { - TopoDS_Face aNewFace; - // - const TopoDS_Face& aF1=TopoDS::Face(aS1); - MakeFace(aF1, aNewFace); - aNewShape=aNewFace; + TopoDS_Face aNewFace; + // + const TopoDS_Face& aF1=TopoDS::Face(aS1); + MakeFace(aF1, aNewFace); + aNewShape=aNewFace; } else if (aType==TopAbs_EDGE) { - TopoDS_Edge aNewEdge; - // - const TopoDS_Edge& aE1=TopoDS::Edge(aS1); - MakeEdge(aE1, aNewEdge); - aNewShape=aNewEdge; + TopoDS_Edge aNewEdge; + // + const TopoDS_Edge& aE1=TopoDS::Edge(aS1); + MakeEdge(aE1, aNewEdge); + aNewShape=aNewEdge; } } // @@ -688,7 +682,7 @@ void GEOMAlgo_Gluer::MakeShapes(const TopAbs_ShapeEnum aType) for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aFSD=aItS.Value(); if (!myOrigins.IsBound(aFSD)) { - myOrigins.Bind(aFSD, aNewShape); + myOrigins.Bind(aFSD, aNewShape); } } } @@ -728,12 +722,12 @@ void GEOMAlgo_Gluer::CheckResult() for (j=1; j<=aNbFS; ++j) { const TopoDS_Shape& aFS=aMFS(j); if (aMFR.Contains(aFS)) { - const TopTools_ListOfShape& aLSx=aMFR.FindFromKey(aFS); - aNbSx=aLSx.Extent(); - if (aNbSx==2) { - bFound=!bFound; - break; - } + const TopTools_ListOfShape& aLSx=aMFR.FindFromKey(aFS); + aNbSx=aLSx.Extent(); + if (aNbSx==2) { + bFound=!bFound; + break; + } } } // @@ -795,7 +789,7 @@ void GEOMAlgo_Gluer::InnerTolerance() //purpose : //======================================================================= void GEOMAlgo_Gluer::FacePassKey(const TopoDS_Face& aF, - GEOMAlgo_PassKeyShape& aPK) + GEOMAlgo_PassKeyShape& aPK) { Standard_Integer i, aNbE; TopTools_ListOfShape aLE; @@ -820,7 +814,7 @@ void GEOMAlgo_Gluer::FacePassKey(const TopoDS_Face& aF, //purpose : //======================================================================= void GEOMAlgo_Gluer::EdgePassKey(const TopoDS_Edge& aE, - GEOMAlgo_PassKeyShape& aPK) + GEOMAlgo_PassKeyShape& aPK) { TopoDS_Vertex aV1, aV2; // @@ -839,7 +833,7 @@ void GEOMAlgo_Gluer::EdgePassKey(const TopoDS_Edge& aE, //purpose : //======================================================================= void GEOMAlgo_Gluer::MakeVertex(const TopTools_ListOfShape& aLV, - TopoDS_Vertex& aNewVertex) + TopoDS_Vertex& aNewVertex) { Standard_Integer aNbV; Standard_Real aTolV, aD, aDmax; @@ -885,7 +879,7 @@ void GEOMAlgo_Gluer::MakeVertex(const TopTools_ListOfShape& aLV, //purpose : //======================================================================= void GEOMAlgo_Gluer::MakeEdge(const TopoDS_Edge& aE, - TopoDS_Edge& aNewEdge) + TopoDS_Edge& aNewEdge) { myErrorStatus=0; // @@ -939,7 +933,7 @@ void GEOMAlgo_Gluer::MakeEdge(const TopoDS_Edge& aE, //purpose : //======================================================================= void GEOMAlgo_Gluer::MakeFace(const TopoDS_Face& aF, - TopoDS_Face& aNewFace) + TopoDS_Face& aNewFace) { myErrorStatus=0; // @@ -975,20 +969,20 @@ void GEOMAlgo_Gluer::MakeFace(const TopoDS_Face& aF, // aER.Orientation(TopAbs_FORWARD); if (!BRep_Tool::Degenerated(aER)) { - // build p-curve - if (bIsUPeriodic) { - GEOMAlgo_AlgoTools::RefinePCurveForEdgeOnFace(aER, aFFWD, aUMin, aUMax); - } - BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aER, aFFWD); - - // orient image - bIsToReverse=GEOMAlgo_AlgoTools::IsSplitToReverse(aER, aE, myContext); - if (bIsToReverse) { - aER.Reverse(); - } + // build p-curve + if (bIsUPeriodic) { + GEOMAlgo_AlgoTools::RefinePCurveForEdgeOnFace(aER, aFFWD, aUMin, aUMax); + } + BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aER, aFFWD); + + // orient image + bIsToReverse=GEOMAlgo_AlgoTools::IsSplitToReverse(aER, aE, myContext); + if (bIsToReverse) { + aER.Reverse(); + } } else { - aER.Orientation(aE.Orientation()); + aER.Orientation(aE.Orientation()); } // aBB.Add(newWire, aER); @@ -1009,7 +1003,7 @@ void GEOMAlgo_Gluer::MakeFace(const TopoDS_Face& aF, //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Gluer::IsToReverse(const TopoDS_Face& aFR, - const TopoDS_Face& aF) + const TopoDS_Face& aF) { Standard_Boolean bRet; Standard_Real aT, aT1, aT2, aTR, aScPr; @@ -1088,7 +1082,7 @@ Standard_Boolean GEOMAlgo_Gluer::HasNewSubShape(const TopoDS_Shape& aS)const //purpose : //======================================================================= void GetSubShapes(const TopoDS_Shape& aS, - TopTools_IndexedMapOfShape& aMSS) + TopTools_IndexedMapOfShape& aMSS) { Standard_Integer aR; TopAbs_ShapeEnum aType; @@ -1111,7 +1105,8 @@ void GetSubShapes(const TopoDS_Shape& aS, //function : Modified //purpose : //======================================================================= -const TopTools_ListOfShape& GEOMAlgo_Gluer::Modified (const TopoDS_Shape& aS) +const TopTools_ListOfShape& GEOMAlgo_Gluer::Modified + (const TopoDS_Shape& aS) { TopAbs_ShapeEnum aType; // @@ -1127,7 +1122,7 @@ const TopTools_ListOfShape& GEOMAlgo_Gluer::Modified (const TopoDS_Shape& aS) if(myOrigins.IsBound(aS)) { const TopoDS_Shape& aSnew=myOrigins.Find(aS); if (!aSnew.IsSame(aS)) { - myGenerated.Append(aSnew); + myGenerated.Append(aSnew); } } } diff --git a/src/GEOMAlgo/GEOMAlgo_Gluer2.cxx b/src/GEOMAlgo/GEOMAlgo_Gluer2.cxx index 80e71f4fa..7ecbd807b 100644 --- a/src/GEOMAlgo/GEOMAlgo_Gluer2.cxx +++ b/src/GEOMAlgo/GEOMAlgo_Gluer2.cxx @@ -84,11 +84,8 @@ void GEOMAlgo_Gluer2::Clear() myImagesToWork.Clear(); myOriginsToWork.Clear(); myKeepNonSolids=Standard_False; - //modified by NIZNHY-PKV Tue Mar 13 13:38:28 2012f myDetector.Clear(); - //modified by NIZNHY-PKV Tue Mar 13 13:38:30 2012t } -//modified by NIZNHY-PKV Tue Mar 13 12:26:50 2012f //======================================================================= //function : StickedShapes //purpose : @@ -98,12 +95,12 @@ const TopTools_IndexedDataMapOfShapeListOfShape& { return myDetector.StickedShapes(); } -//modified by NIZNHY-PKV Tue Mar 13 12:26:54 2012t //======================================================================= //function : SetShapesToGlue //purpose : //======================================================================= -void GEOMAlgo_Gluer2::SetShapesToGlue(const TopTools_DataMapOfShapeListOfShape& aM) +void GEOMAlgo_Gluer2::SetShapesToGlue + (const TopTools_DataMapOfShapeListOfShape& aM) { myShapesToGlue=aM; } @@ -241,6 +238,7 @@ void GEOMAlgo_Gluer2::CheckData() myWarningStatus=0; // aNbSG=myShapesToGlue.Extent(); + aType=TopAbs_SHAPE; if (aNbSG) { // Check myShapesToGlue aItDMSLS.Initialize(myShapesToGlue); @@ -587,6 +585,7 @@ void GEOMAlgo_Gluer2::BuildResult() myErrorStatus=0; myWarningStatus=0; // + bHasImage=Standard_False; aItC.Initialize(myArgument); for (; aItC.More(); aItC.Next()) { const TopoDS_Shape& aCx=aItC.Value(); diff --git a/src/GEOMAlgo/GEOMAlgo_KindOfDef.hxx b/src/GEOMAlgo/GEOMAlgo_KindOfDef.hxx new file mode 100644 index 000000000..fab59298a --- /dev/null +++ b/src/GEOMAlgo/GEOMAlgo_KindOfDef.hxx @@ -0,0 +1,37 @@ +// Copyright (C) 2007-2015 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, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +//GEOMAlgo_KindOfDef +#ifndef _GEOMAlgo_KindOfDef_HeaderFile +#define _GEOMAlgo_KindOfDef_HeaderFile + + +enum GEOMAlgo_KindOfDef { +GEOMAlgo_KD_UNKNOWN, +GEOMAlgo_KD_SPECIFIED, +GEOMAlgo_KD_ARBITRARY +}; + +#ifndef _Standard_PrimitiveTypes_HeaderFile +#include +#endif + +#endif diff --git a/src/GEOMAlgo/GEOMAlgo_KindOfName.hxx b/src/GEOMAlgo/GEOMAlgo_KindOfName.hxx index eda5fba08..cf012663e 100644 --- a/src/GEOMAlgo/GEOMAlgo_KindOfName.hxx +++ b/src/GEOMAlgo/GEOMAlgo_KindOfName.hxx @@ -44,7 +44,8 @@ GEOMAlgo_KN_DISKELLIPSE, GEOMAlgo_KN_RECTANGLE, GEOMAlgo_KN_TRIANGLE, GEOMAlgo_KN_QUADRANGLE, -GEOMAlgo_KN_ARCELLIPSE +GEOMAlgo_KN_ARCELLIPSE, +GEOMAlgo_KN_SOLID }; #ifndef _Standard_PrimitiveTypes_HeaderFile diff --git a/src/GEOMAlgo/GEOMAlgo_KindOfShape.hxx b/src/GEOMAlgo/GEOMAlgo_KindOfShape.hxx index 32efa59c9..382fdef6a 100644 --- a/src/GEOMAlgo/GEOMAlgo_KindOfShape.hxx +++ b/src/GEOMAlgo/GEOMAlgo_KindOfShape.hxx @@ -35,9 +35,7 @@ GEOMAlgo_KS_PLANE, GEOMAlgo_KS_CIRCLE, GEOMAlgo_KS_LINE, GEOMAlgo_KS_DEGENERATED, -//modified by NIZNHY-PKV Tue Jul 03 10:28:09 2012f GEOMAlgo_KS_BSPLINE -//modified by NIZNHY-PKV Tue Jul 03 10:28:11 2012t }; #ifndef _Standard_PrimitiveTypes_HeaderFile diff --git a/src/GEOMAlgo/GEOMAlgo_ShapeInfo.cxx b/src/GEOMAlgo/GEOMAlgo_ShapeInfo.cxx index b91eb9728..fe4b7f69b 100644 --- a/src/GEOMAlgo/GEOMAlgo_ShapeInfo.cxx +++ b/src/GEOMAlgo/GEOMAlgo_ShapeInfo.cxx @@ -29,6 +29,8 @@ static void DumpKindOfBounds(const GEOMAlgo_KindOfBounds aKB); static void DumpKindOfName(const GEOMAlgo_KindOfName aKS); +static + void DumpKindOfDef(const GEOMAlgo_KindOfDef aKD); static void DumpPosition(const gp_Ax3& aAx3); static @@ -39,7 +41,7 @@ static //function : //purpose : //======================================================================= - GEOMAlgo_ShapeInfo::GEOMAlgo_ShapeInfo() +GEOMAlgo_ShapeInfo::GEOMAlgo_ShapeInfo() { Reset(); } @@ -47,14 +49,14 @@ static //function : ~ //purpose : //======================================================================= - GEOMAlgo_ShapeInfo::~GEOMAlgo_ShapeInfo() +GEOMAlgo_ShapeInfo::~GEOMAlgo_ShapeInfo() { } //======================================================================= //function : Reset //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::Reset() +void GEOMAlgo_ShapeInfo::Reset() { Standard_Integer i; // @@ -69,6 +71,7 @@ static myKindOfBounds=GEOMAlgo_KB_UNKNOWN; myKindOfClosed=GEOMAlgo_KC_UNKNOWN; myKindOfName=GEOMAlgo_KN_UNKNOWN; + myKindOfDef=GEOMAlgo_KD_UNKNOWN; // myLocation.SetCoord(99., 99., 99.); myDirection.SetCoord(1.,0.,0.); @@ -83,7 +86,7 @@ static //function : SetType //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetType(const TopAbs_ShapeEnum aType) +void GEOMAlgo_ShapeInfo::SetType(const TopAbs_ShapeEnum aType) { myType=aType; } @@ -91,7 +94,7 @@ static //function : Type //purpose : //======================================================================= - TopAbs_ShapeEnum GEOMAlgo_ShapeInfo::Type() const +TopAbs_ShapeEnum GEOMAlgo_ShapeInfo::Type() const { return myType; } @@ -99,8 +102,8 @@ static //function : SetNbSubShapes //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetNbSubShapes(const TopAbs_ShapeEnum aType, - const Standard_Integer aNb) +void GEOMAlgo_ShapeInfo::SetNbSubShapes(const TopAbs_ShapeEnum aType, + const Standard_Integer aNb) { Standard_Integer iN; @@ -113,7 +116,8 @@ static //function : NbSubShapes //purpose : //======================================================================= - Standard_Integer GEOMAlgo_ShapeInfo::NbSubShapes(const TopAbs_ShapeEnum aType) const +Standard_Integer GEOMAlgo_ShapeInfo::NbSubShapes + (const TopAbs_ShapeEnum aType) const { Standard_Integer iN; @@ -127,7 +131,7 @@ static //function : SetKindOfShape //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetKindOfShape(const GEOMAlgo_KindOfShape aT) +void GEOMAlgo_ShapeInfo::SetKindOfShape(const GEOMAlgo_KindOfShape aT) { myKindOfShape=aT; } @@ -135,7 +139,7 @@ static //function : KindOfShape //purpose : //======================================================================= - GEOMAlgo_KindOfShape GEOMAlgo_ShapeInfo::KindOfShape() const +GEOMAlgo_KindOfShape GEOMAlgo_ShapeInfo::KindOfShape() const { return myKindOfShape; } @@ -143,7 +147,7 @@ static //function : SetKindOfName //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetKindOfName(const GEOMAlgo_KindOfName aT) +void GEOMAlgo_ShapeInfo::SetKindOfName(const GEOMAlgo_KindOfName aT) { myKindOfName=aT; } @@ -151,7 +155,7 @@ static //function : KindOfName //purpose : //======================================================================= - GEOMAlgo_KindOfName GEOMAlgo_ShapeInfo::KindOfName() const +GEOMAlgo_KindOfName GEOMAlgo_ShapeInfo::KindOfName() const { return myKindOfName; } @@ -159,7 +163,7 @@ static //function : SetKindOfBounds //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetKindOfBounds(const GEOMAlgo_KindOfBounds aT) +void GEOMAlgo_ShapeInfo::SetKindOfBounds(const GEOMAlgo_KindOfBounds aT) { myKindOfBounds=aT; } @@ -167,7 +171,7 @@ static //function : KindOfBounds //purpose : //======================================================================= - GEOMAlgo_KindOfBounds GEOMAlgo_ShapeInfo::KindOfBounds() const +GEOMAlgo_KindOfBounds GEOMAlgo_ShapeInfo::KindOfBounds() const { return myKindOfBounds; } @@ -175,7 +179,7 @@ static //function : SetKindOfClosed //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetKindOfClosed(const GEOMAlgo_KindOfClosed aT) +void GEOMAlgo_ShapeInfo::SetKindOfClosed(const GEOMAlgo_KindOfClosed aT) { myKindOfClosed=aT; } @@ -183,15 +187,31 @@ static //function : KindOfClosed //purpose : //======================================================================= - GEOMAlgo_KindOfClosed GEOMAlgo_ShapeInfo::KindOfClosed() const +GEOMAlgo_KindOfClosed GEOMAlgo_ShapeInfo::KindOfClosed() const { return myKindOfClosed; } //======================================================================= +//function : SetKindOfDef +//purpose : +//======================================================================= +void GEOMAlgo_ShapeInfo::SetKindOfDef(const GEOMAlgo_KindOfDef aT) +{ + myKindOfDef=aT; +} +//======================================================================= +//function : KindOfDef +//purpose : +//======================================================================= +GEOMAlgo_KindOfDef GEOMAlgo_ShapeInfo::KindOfDef() const +{ + return myKindOfDef; +} +//======================================================================= //function : SetLocation //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetLocation(const gp_Pnt& aP) +void GEOMAlgo_ShapeInfo::SetLocation(const gp_Pnt& aP) { myLocation=aP; } @@ -199,7 +219,7 @@ static //function : Location //purpose : //======================================================================= - const gp_Pnt& GEOMAlgo_ShapeInfo::Location() const +const gp_Pnt& GEOMAlgo_ShapeInfo::Location() const { return myLocation; } @@ -207,7 +227,7 @@ static //function : SetDirection //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetDirection(const gp_Dir& aD) +void GEOMAlgo_ShapeInfo::SetDirection(const gp_Dir& aD) { myDirection=aD; } @@ -215,7 +235,7 @@ static //function : Direction //purpose : //======================================================================= - const gp_Dir& GEOMAlgo_ShapeInfo::Direction() const +const gp_Dir& GEOMAlgo_ShapeInfo::Direction() const { return myDirection; } @@ -223,7 +243,7 @@ static //function : SetPosition //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetPosition(const gp_Ax2& aAx2) +void GEOMAlgo_ShapeInfo::SetPosition(const gp_Ax2& aAx2) { gp_Ax3 aAx3(aAx2); SetPosition(aAx3); @@ -232,7 +252,7 @@ static //function : SetPosition //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetPosition(const gp_Ax3& aAx3) +void GEOMAlgo_ShapeInfo::SetPosition(const gp_Ax3& aAx3) { myPosition=aAx3; } @@ -240,7 +260,7 @@ static //function : Position //purpose : //======================================================================= - const gp_Ax3& GEOMAlgo_ShapeInfo::Position() const +const gp_Ax3& GEOMAlgo_ShapeInfo::Position() const { return myPosition; } @@ -249,7 +269,7 @@ static //function : SetPnt1 //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetPnt1(const gp_Pnt& aP) +void GEOMAlgo_ShapeInfo::SetPnt1(const gp_Pnt& aP) { myPnt1=aP; } @@ -257,7 +277,7 @@ static //function : Pnt1 //purpose : //======================================================================= - const gp_Pnt& GEOMAlgo_ShapeInfo::Pnt1() const +const gp_Pnt& GEOMAlgo_ShapeInfo::Pnt1() const { return myPnt1; } @@ -265,7 +285,7 @@ static //function : SetPnt2 //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetPnt2(const gp_Pnt& aP) +void GEOMAlgo_ShapeInfo::SetPnt2(const gp_Pnt& aP) { myPnt2=aP; } @@ -273,7 +293,7 @@ static //function : Pnt2 //purpose : //======================================================================= - const gp_Pnt& GEOMAlgo_ShapeInfo::Pnt2() const +const gp_Pnt& GEOMAlgo_ShapeInfo::Pnt2() const { return myPnt2; } @@ -281,7 +301,7 @@ static //function : SetRadius1 //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetRadius1(const Standard_Real aR) +void GEOMAlgo_ShapeInfo::SetRadius1(const Standard_Real aR) { myRadius1=aR; } @@ -289,7 +309,7 @@ static //function : Radius1 //purpose : //======================================================================= - Standard_Real GEOMAlgo_ShapeInfo::Radius1() const +Standard_Real GEOMAlgo_ShapeInfo::Radius1() const { return myRadius1; } @@ -297,7 +317,7 @@ static //function : SetRadius2 //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetRadius2(const Standard_Real aR) +void GEOMAlgo_ShapeInfo::SetRadius2(const Standard_Real aR) { myRadius2=aR; } @@ -305,7 +325,7 @@ static //function : Radius2 //purpose : //======================================================================= - Standard_Real GEOMAlgo_ShapeInfo::Radius2() const +Standard_Real GEOMAlgo_ShapeInfo::Radius2() const { return myRadius2; } @@ -313,7 +333,7 @@ static //function : SetLength //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetLength(const Standard_Real aL) +void GEOMAlgo_ShapeInfo::SetLength(const Standard_Real aL) { myLength=aL; } @@ -321,7 +341,7 @@ static //function : Length //purpose : //======================================================================= - Standard_Real GEOMAlgo_ShapeInfo::Length() const +Standard_Real GEOMAlgo_ShapeInfo::Length() const { return myLength; } @@ -329,7 +349,7 @@ static //function : SetWidth //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetWidth(const Standard_Real aW) +void GEOMAlgo_ShapeInfo::SetWidth(const Standard_Real aW) { myWidth=aW; } @@ -337,7 +357,7 @@ static //function : Width //purpose : //======================================================================= - Standard_Real GEOMAlgo_ShapeInfo::Width() const +Standard_Real GEOMAlgo_ShapeInfo::Width() const { return myWidth; } @@ -345,7 +365,7 @@ static //function : SetHeight //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::SetHeight(const Standard_Real aH) +void GEOMAlgo_ShapeInfo::SetHeight(const Standard_Real aH) { myHeight=aH; } @@ -353,7 +373,7 @@ static //function : Height //purpose : //======================================================================= - Standard_Real GEOMAlgo_ShapeInfo::Height() const +Standard_Real GEOMAlgo_ShapeInfo::Height() const { return myHeight; } @@ -372,7 +392,7 @@ Standard_Integer TypeToInteger(const TopAbs_ShapeEnum aType) //function : Dump //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::Dump()const +void GEOMAlgo_ShapeInfo::Dump()const { switch (myType) { // @@ -417,7 +437,7 @@ Standard_Integer TypeToInteger(const TopAbs_ShapeEnum aType) //function : DumpCompound //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::DumpCompound()const +void GEOMAlgo_ShapeInfo::DumpCompound()const { Standard_Integer aNbV, aNbE, aNbF, aNbS, aNbC, aNbP; GEOMAlgo_KindOfShape aKS; @@ -452,7 +472,7 @@ Standard_Integer TypeToInteger(const TopAbs_ShapeEnum aType) //function : DumpCompSolid //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::DumpCompSolid()const +void GEOMAlgo_ShapeInfo::DumpCompSolid()const { Standard_Integer aNbV, aNbE, aNbF, aNbS; GEOMAlgo_KindOfShape aKS; @@ -479,12 +499,11 @@ Standard_Integer TypeToInteger(const TopAbs_ShapeEnum aType) DumpKindOfBounds(aKB); DumpKindOfClosed(aKC); } - //======================================================================= //function : DumpSolid //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::DumpSolid()const +void GEOMAlgo_ShapeInfo::DumpSolid()const { Standard_Integer aNbV, aNbE, aNbF; GEOMAlgo_KindOfShape aKS; @@ -545,18 +564,18 @@ Standard_Integer TypeToInteger(const TopAbs_ShapeEnum aType) printf(" Height : %.3lf\n", myHeight); } } - //======================================================================= //function : DumpFace //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::DumpFace()const +void GEOMAlgo_ShapeInfo::DumpFace()const { Standard_Integer aNbV, aNbE; GEOMAlgo_KindOfShape aKS; GEOMAlgo_KindOfName aKN; GEOMAlgo_KindOfBounds aKB; GEOMAlgo_KindOfClosed aKC; + GEOMAlgo_KindOfDef aKD; // aNbV=NbSubShapes(TopAbs_VERTEX); aNbE=NbSubShapes(TopAbs_EDGE); @@ -564,6 +583,7 @@ Standard_Integer TypeToInteger(const TopAbs_ShapeEnum aType) aKN=KindOfName(); aKB=KindOfBounds(); aKC=KindOfClosed(); + aKD=KindOfDef(); // printf(" *FACE\n"); printf(" number of vertices: %d\n", aNbV); @@ -572,6 +592,7 @@ Standard_Integer TypeToInteger(const TopAbs_ShapeEnum aType) DumpKindOfName (aKN); DumpKindOfBounds(aKB); DumpKindOfClosed(aKC); + DumpKindOfDef(aKD); // // PLANE if (aKN==GEOMAlgo_KN_PLANE) { @@ -641,7 +662,7 @@ Standard_Integer TypeToInteger(const TopAbs_ShapeEnum aType) //function : DumpShell //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::DumpShell()const +void GEOMAlgo_ShapeInfo::DumpShell()const { Standard_Integer aNbV, aNbE, aNbF; GEOMAlgo_KindOfClosed aKC; @@ -662,7 +683,7 @@ Standard_Integer TypeToInteger(const TopAbs_ShapeEnum aType) //function : DumpWire //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::DumpWire()const +void GEOMAlgo_ShapeInfo::DumpWire()const { Standard_Integer aNbV, aNbE; GEOMAlgo_KindOfClosed aKC; @@ -682,7 +703,7 @@ Standard_Integer TypeToInteger(const TopAbs_ShapeEnum aType) //function : DumpEdge //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::DumpEdge()const +void GEOMAlgo_ShapeInfo::DumpEdge()const { Standard_Integer aNbV; Standard_Real aX, aY, aZ; @@ -755,7 +776,7 @@ Standard_Integer TypeToInteger(const TopAbs_ShapeEnum aType) //function : DumpVertex //purpose : //======================================================================= - void GEOMAlgo_ShapeInfo::DumpVertex()const +void GEOMAlgo_ShapeInfo::DumpVertex()const { printf(" *VERTEX\n"); DumpLocation(myLocation); @@ -764,7 +785,7 @@ Standard_Integer TypeToInteger(const TopAbs_ShapeEnum aType) //function : DumpLocation //purpose : //======================================================================= - void DumpLocation(const gp_Pnt& aP) +void DumpLocation(const gp_Pnt& aP) { Standard_Real aX, aY, aZ; // @@ -775,7 +796,7 @@ Standard_Integer TypeToInteger(const TopAbs_ShapeEnum aType) //function : DumpDirection //purpose : //======================================================================= - void DumpDirection(const gp_Dir& aD) +void DumpDirection(const gp_Dir& aD) { Standard_Real aX, aY, aZ; // @@ -881,10 +902,27 @@ void DumpKindOfName(const GEOMAlgo_KindOfName aKS) "KN_RECTANGLE", "KN_TRIANGLE", "KN_QUADRANGLE", - "KN_ARCELLIPSE" + "KN_ARCELLIPSE", + "KN_SOLID" }; int i; // i=(Standard_Integer)aKS; printf(" KindOfName : %s\n", pStr[i]); } +//======================================================================= +//function : DumpKindOfDef +//purpose : +//======================================================================= +void DumpKindOfDef(const GEOMAlgo_KindOfDef aKD) +{ + const char *pStr[]={ + "KD_UNKNOWN", + "KD_SPECIFIED", + "KB_ARBITRARY" + }; + int i; + // + i=(Standard_Integer)aKD; + printf(" KindOfDef: %s\n", pStr[i]); +} diff --git a/src/GEOMAlgo/GEOMAlgo_ShapeInfo.hxx b/src/GEOMAlgo/GEOMAlgo_ShapeInfo.hxx index 827370343..0556e68d4 100644 --- a/src/GEOMAlgo/GEOMAlgo_ShapeInfo.hxx +++ b/src/GEOMAlgo/GEOMAlgo_ShapeInfo.hxx @@ -37,6 +37,7 @@ #include #include #include +#include //======================================================================= @@ -62,7 +63,8 @@ class GEOMAlgo_ShapeInfo TopAbs_ShapeEnum Type() const; Standard_EXPORT - void SetNbSubShapes(const TopAbs_ShapeEnum aType,const Standard_Integer aNb) ; + void SetNbSubShapes(const TopAbs_ShapeEnum aType, + const Standard_Integer aNb) ; Standard_EXPORT Standard_Integer NbSubShapes(const TopAbs_ShapeEnum aType) const; @@ -91,6 +93,12 @@ class GEOMAlgo_ShapeInfo Standard_EXPORT GEOMAlgo_KindOfClosed KindOfClosed() const; + Standard_EXPORT + void SetKindOfDef(const GEOMAlgo_KindOfDef aT) ; + + Standard_EXPORT + GEOMAlgo_KindOfDef KindOfDef() const; + Standard_EXPORT void SetLocation(const gp_Pnt& aP) ; @@ -189,6 +197,7 @@ class GEOMAlgo_ShapeInfo GEOMAlgo_KindOfName myKindOfName; GEOMAlgo_KindOfBounds myKindOfBounds; GEOMAlgo_KindOfClosed myKindOfClosed; + GEOMAlgo_KindOfDef myKindOfDef; gp_Pnt myLocation; gp_Dir myDirection; gp_Ax3 myPosition; diff --git a/src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller.cxx b/src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller.cxx index 84a4f4322..e440912b6 100644 --- a/src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller.cxx +++ b/src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller.cxx @@ -59,7 +59,7 @@ //function : //purpose : //======================================================================= - GEOMAlgo_ShapeInfoFiller::GEOMAlgo_ShapeInfoFiller() +GEOMAlgo_ShapeInfoFiller::GEOMAlgo_ShapeInfoFiller() : GEOMAlgo_Algo() { @@ -69,14 +69,14 @@ //function : ~ //purpose : //======================================================================= - GEOMAlgo_ShapeInfoFiller::~GEOMAlgo_ShapeInfoFiller() +GEOMAlgo_ShapeInfoFiller::~GEOMAlgo_ShapeInfoFiller() { } //======================================================================= //function : SetTolerance //purpose : //======================================================================= - void GEOMAlgo_ShapeInfoFiller::SetTolerance(const Standard_Real aT) +void GEOMAlgo_ShapeInfoFiller::SetTolerance(const Standard_Real aT) { myTolerance=aT; } @@ -84,7 +84,7 @@ //function : Tolerance //purpose : //======================================================================= - Standard_Real GEOMAlgo_ShapeInfoFiller::Tolerance()const +Standard_Real GEOMAlgo_ShapeInfoFiller::Tolerance()const { return myTolerance; } @@ -92,7 +92,7 @@ //function : SetShape //purpose : //======================================================================= - void GEOMAlgo_ShapeInfoFiller::SetShape(const TopoDS_Shape& aS) +void GEOMAlgo_ShapeInfoFiller::SetShape(const TopoDS_Shape& aS) { myShape=aS; } @@ -100,7 +100,7 @@ //function : Shape //purpose : //======================================================================= - const TopoDS_Shape& GEOMAlgo_ShapeInfoFiller::Shape() const +const TopoDS_Shape& GEOMAlgo_ShapeInfoFiller::Shape() const { return myShape; } @@ -108,7 +108,7 @@ //function : Info //purpose : //======================================================================= - const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info() const +const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info() const { return Info(myShape); } @@ -116,7 +116,8 @@ //function : Info //purpose : //======================================================================= - const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info(const TopoDS_Shape& aS) const +const GEOMAlgo_ShapeInfo& GEOMAlgo_ShapeInfoFiller::Info + (const TopoDS_Shape& aS) const { if (!aS.IsNull()) { if (myMapInfo.Contains(aS)) { @@ -131,7 +132,7 @@ //function : CheckData //purpose : //======================================================================= - void GEOMAlgo_ShapeInfoFiller::CheckData() +void GEOMAlgo_ShapeInfoFiller::CheckData() { myErrorStatus=0; // @@ -144,7 +145,7 @@ //function : Perform //purpose : //======================================================================= - void GEOMAlgo_ShapeInfoFiller::Perform() +void GEOMAlgo_ShapeInfoFiller::Perform() { myErrorStatus=0; // @@ -161,7 +162,7 @@ //function :FillShape //purpose : //======================================================================= - void GEOMAlgo_ShapeInfoFiller::FillShape(const TopoDS_Shape& aS) +void GEOMAlgo_ShapeInfoFiller::FillShape(const TopoDS_Shape& aS) { TopAbs_ShapeEnum aType; // @@ -199,7 +200,7 @@ //function :FillSubShapes //purpose : //======================================================================= - void GEOMAlgo_ShapeInfoFiller::FillSubShapes(const TopoDS_Shape& aS) +void GEOMAlgo_ShapeInfoFiller::FillSubShapes(const TopoDS_Shape& aS) { TopoDS_Iterator aIt; // @@ -213,7 +214,7 @@ //function : FillContainer //purpose : //======================================================================= - void GEOMAlgo_ShapeInfoFiller::FillContainer(const TopoDS_Shape& aS) +void GEOMAlgo_ShapeInfoFiller::FillContainer(const TopoDS_Shape& aS) { myErrorStatus=0; // @@ -258,9 +259,8 @@ //function : FillSolid //purpose : //======================================================================= - void GEOMAlgo_ShapeInfoFiller::FillSolid(const TopoDS_Shape& aS) +void GEOMAlgo_ShapeInfoFiller::FillSolid(const TopoDS_Shape& aS) { - Standard_Integer aNbShells; TopoDS_Solid aSd; // myErrorStatus=0; @@ -280,40 +280,32 @@ // aSd=TopoDS::Solid(aS); // - aNbShells=GEOMAlgo_ShapeInfoFiller::NbShells(aSd); - if (aNbShells>1) { - return; - } - // FillDetails(aSd); } //======================================================================= //function :FillFace //purpose : //======================================================================= - void GEOMAlgo_ShapeInfoFiller::FillFace(const TopoDS_Shape& aS) +void GEOMAlgo_ShapeInfoFiller::FillFace(const TopoDS_Shape& aS) { myErrorStatus=0; + if (myMapInfo.Contains(aS)) { + return; + } // Standard_Boolean bIsAllowedType; - Standard_Integer aNbWires;//, iRet Standard_Boolean bInf, bInfU1, bInfU2, bInfV1, bInfV2; - Standard_Real aUMin, aUMax, aVMin, aVMax, aR1, aR2; + Standard_Real aUMin, aUMax, aVMin, aVMax, aR1, aR2, dV; gp_Pnt aP0; gp_Dir aDN; gp_Ax3 aAx3; GeomAbs_SurfaceType aST; Handle(Geom_Surface) aSurf; TopoDS_Face aF; - //GEOMAlgo_KindOfName aKindOfName; //---------------------------------------------------- - if (myMapInfo.Contains(aS)) { - return; - } - else { - GEOMAlgo_ShapeInfo aInfoX; - myMapInfo.Add(aS, aInfoX); - } + GEOMAlgo_ShapeInfo aInfoX; + myMapInfo.Add(aS, aInfoX); + // GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aS); //---------------------------------------------------- aInfo.SetType(TopAbs_FACE); @@ -324,8 +316,6 @@ // aF=TopoDS::Face(aS); // - aNbWires=GEOMAlgo_ShapeInfoFiller::NbWires(aF); - // aSurf=BRep_Tool::Surface(aF); GeomAdaptor_Surface aGAS(aSurf); aST=aGAS.GetType(); @@ -334,6 +324,7 @@ return; } // + //|||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // 1. Plane if (aST==GeomAbs_Plane) { gp_Pln aPln; @@ -342,16 +333,12 @@ aP0=aPln.Location(); aAx3=aPln.Position(); // - aInfo.SetKindOfShape(GEOMAlgo_KS_PLANE); + aInfo.SetKindOfShape(GEOMAlgo_KS_PLANE); + aInfo.SetKindOfName(GEOMAlgo_KN_PLANE); aInfo.SetKindOfClosed(GEOMAlgo_KC_NOTCLOSED); aInfo.SetLocation(aP0); aInfo.SetPosition(aAx3); // - if (aNbWires>1) { - return; - } - // - //aSurf->Bounds(aUMin, aUMax, aVMin, aVMax); BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax); bInfU1=Precision::IsNegativeInfinite(aUMin); bInfU2=Precision::IsPositiveInfinite(aUMax); @@ -361,14 +348,15 @@ bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2); if (bInf) { aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE); + return; } - else { - aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED); - } + // + aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED); // FillDetails(aF, aPln); }// if (aCT==GeomAbs_Line) { // + //|||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // 2. Sphere else if (aST==GeomAbs_Sphere) { gp_Sphere aSphere; @@ -379,20 +367,18 @@ aR1=aSphere.Radius(); // aInfo.SetKindOfShape(GEOMAlgo_KS_SPHERE); + aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE); aInfo.SetLocation(aP0); aInfo.SetPosition(aAx3); aInfo.SetRadius1(aR1); // - if (aNbWires>1) { - return; - } - // aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED); aInfo.SetKindOfClosed(GEOMAlgo_KC_CLOSED); // FillDetails(aF, aSphere); }// else if (aST==GeomAbs_Sphere) { // + //|||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // 3. Cylinder else if (aST==GeomAbs_Cylinder) { gp_Cylinder aCyl; @@ -403,14 +389,11 @@ aR1=aCyl.Radius(); // aInfo.SetKindOfShape(GEOMAlgo_KS_CYLINDER); + aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER); aInfo.SetLocation(aP0); aInfo.SetPosition(aAx3); aInfo.SetRadius1(aR1); // - if (aNbWires>1) { - return; - } - // BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax); bInfU1=Precision::IsNegativeInfinite(aUMin); bInfU2=Precision::IsPositiveInfinite(aUMax); @@ -420,30 +403,31 @@ bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2); if (bInf) { aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE); + return; } - else { - aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED); - } + // + aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED); + // + dV=aVMax-aVMin; + aInfo.SetHeight(dV); + // FillDetails(aF, aCyl); } // + //|||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // 4. Cone else if (aST==GeomAbs_Cone) { + Standard_Real aSemiAngle; gp_Cone aCone; // aCone=aGAS.Cone(); aP0=aCone.Location(); aAx3=aCone.Position(); - //aR1=aCyl.Radius(); // aInfo.SetKindOfShape(GEOMAlgo_KS_CONE); + aInfo.SetKindOfName(GEOMAlgo_KN_CONE); aInfo.SetLocation(aP0); aInfo.SetPosition(aAx3); - //aInfo.SetRadius1(aR1); - // - if (aNbWires>1) { - return; - } // BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax); bInfU1=Precision::IsNegativeInfinite(aUMin); @@ -454,13 +438,20 @@ bInf=(bInfU1 || bInfU2 || bInfV1 || bInfV2); if (bInf) { aInfo.SetKindOfBounds(GEOMAlgo_KB_INFINITE); + return; } - else { - aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED); - } + // + aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED); + // + aSemiAngle=fabs(aCone.SemiAngle()); + dV=(aVMax-aVMin)*cos(aSemiAngle); + + aInfo.SetHeight(dV); + // FillDetails(aF, aCone); } // + //|||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // 5. Torus else if (aST==GeomAbs_Torus) { gp_Torus aTorus; @@ -472,15 +463,12 @@ aR2=aTorus.MinorRadius(); // aInfo.SetKindOfShape(GEOMAlgo_KS_TORUS); + aInfo.SetKindOfName(GEOMAlgo_KN_TORUS); aInfo.SetLocation(aP0); aInfo.SetPosition(aAx3); aInfo.SetRadius1(aR1); aInfo.SetRadius2(aR2); // - if (aNbWires>1) { - return; - } - // aInfo.SetKindOfBounds(GEOMAlgo_KB_TRIMMED); // FillDetails(aF, aTorus); @@ -535,7 +523,6 @@ void GEOMAlgo_ShapeInfoFiller::FillEdge(const TopoDS_Shape& aS) FillSubShapes(aS); return; } - //modified by NIZNHY-PKV Tue Jul 03 10:19:03 2012f // BSplineCurve if (aCT==GeomAbs_BSplineCurve) { Standard_Integer aNbKnots, aNbPoles, aDegree; @@ -577,7 +564,6 @@ void GEOMAlgo_ShapeInfoFiller::FillEdge(const TopoDS_Shape& aS) aInfo.SetDirection(aDir); } } - //modified by NIZNHY-PKV Tue Jul 03 10:19:06 2012t // Line else if (aCT==GeomAbs_Line) { Standard_Boolean bInf1, bInf2; @@ -712,7 +698,7 @@ void GEOMAlgo_ShapeInfoFiller::FillEdge(const TopoDS_Shape& aS) //function :FillVertex //purpose : //======================================================================= - void GEOMAlgo_ShapeInfoFiller::FillVertex(const TopoDS_Shape& aS) +void GEOMAlgo_ShapeInfoFiller::FillVertex(const TopoDS_Shape& aS) { myErrorStatus=0; // @@ -739,8 +725,8 @@ void GEOMAlgo_ShapeInfoFiller::FillEdge(const TopoDS_Shape& aS) //function : FillNbSubshapes //purpose : //======================================================================= - void GEOMAlgo_ShapeInfoFiller::FillNbSubShapes(const TopoDS_Shape& aS, - GEOMAlgo_ShapeInfo& aInfo) +void GEOMAlgo_ShapeInfoFiller::FillNbSubShapes(const TopoDS_Shape& aS, + GEOMAlgo_ShapeInfo& aInfo) { myErrorStatus=0; // @@ -776,7 +762,8 @@ void GEOMAlgo_ShapeInfoFiller::FillEdge(const TopoDS_Shape& aS) //function :NbShells //purpose : //======================================================================= -Standard_Integer GEOMAlgo_ShapeInfoFiller::NbShells(const TopoDS_Solid& aSd) +Standard_Integer GEOMAlgo_ShapeInfoFiller::NbShells + (const TopoDS_Solid& aSd) { Standard_Integer iCnt; TopoDS_Iterator aIt; @@ -785,7 +772,6 @@ Standard_Integer GEOMAlgo_ShapeInfoFiller::NbShells(const TopoDS_Solid& aSd) // aIt.Initialize(aSd); for (; aIt.More(); aIt.Next()) { - //const TopoDS_Shape& aSh=aIt.Value(); ++iCnt; } return iCnt; @@ -794,7 +780,8 @@ Standard_Integer GEOMAlgo_ShapeInfoFiller::NbShells(const TopoDS_Solid& aSd) //function : NbWires //purpose : //======================================================================= -Standard_Integer GEOMAlgo_ShapeInfoFiller::NbWires(const TopoDS_Face& aF) +Standard_Integer GEOMAlgo_ShapeInfoFiller::NbWires + (const TopoDS_Face& aF) { Standard_Integer iCnt; TopoDS_Iterator aIt; @@ -803,7 +790,6 @@ Standard_Integer GEOMAlgo_ShapeInfoFiller::NbWires(const TopoDS_Face& aF) // aIt.Initialize(aF); for (; aIt.More(); aIt.Next()) { - //const TopoDS_Shape& aW=aIt.Value(); ++iCnt; } return iCnt; @@ -812,7 +798,8 @@ Standard_Integer GEOMAlgo_ShapeInfoFiller::NbWires(const TopoDS_Face& aF) //function : IsAllowedType //purpose : //======================================================================= -Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType(const GeomAbs_CurveType aCT) +Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType + (const GeomAbs_CurveType aCT) { Standard_Boolean bRet; Standard_Integer i, aNb; @@ -820,7 +807,7 @@ Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType(const GeomAbs_CurveType GeomAbs_Line, GeomAbs_Circle, GeomAbs_Ellipse, - GeomAbs_BSplineCurve //modified by NIZNHY-PKV Tue Jul 03 10:18:01 2012ft + GeomAbs_BSplineCurve }; // bRet=Standard_False; @@ -834,7 +821,8 @@ Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType(const GeomAbs_CurveType //function : IsAllowedType //purpose : //======================================================================= -Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType(const GeomAbs_SurfaceType aST) +Standard_Boolean GEOMAlgo_ShapeInfoFiller::IsAllowedType + (const GeomAbs_SurfaceType aST) { Standard_Boolean bRet; Standard_Integer i, aNb; diff --git a/src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx b/src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx index ef1cc41d7..785ceb416 100644 --- a/src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx +++ b/src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx @@ -68,10 +68,12 @@ static void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd) { Standard_Boolean bIsStepSphere; - Standard_Integer i, aNbF, aNbCyl, aNbCon, aNbPgn, aNbRct, aNbCrc, aNbX; + Standard_Integer i, aNbF, aNbCyl, aNbCon, aNbPgn, aNbRct; + Standard_Integer aNbShells, aNbCrc, aNbX; TopoDS_Shape aFCyl, aFCon; TopTools_IndexedMapOfShape aMF; GEOMAlgo_KindOfName aKNF; + GEOMAlgo_KindOfDef aKD; // GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aSd); aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN); @@ -83,7 +85,26 @@ void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd) return; } // + aKD=GEOMAlgo_KD_SPECIFIED; + for (i=1; i<=aNbF && aKD==GEOMAlgo_KD_SPECIFIED; ++i) { + const TopoDS_Shape& aF=aMF(i); + GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF); + aKD=aInfoF.KindOfDef(); + } + if (aKD!=GEOMAlgo_KD_SPECIFIED) { + aInfo.SetKindOfName(GEOMAlgo_KN_SOLID); + return; + } + // + aNbShells=GEOMAlgo_ShapeInfoFiller::NbShells(aSd); + if (aNbShells>1) { + aInfo.SetKindOfName(GEOMAlgo_KN_SOLID); + return; + } + // + // if (aNbF==1) { + // mb: sphere, torus const TopoDS_Shape& aF=aMF(1); GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF); aKNF=aInfoF.KindOfName(); // mb: sphere, torus @@ -99,7 +120,6 @@ void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd) return; } } - //modified by NIZNHY-PKV Tue Jul 03 13:23:55 2012f else if (aNbF==2) { // specific solid that should be treated as a sphere bIsStepSphere=TreatStepSphere(aSd); @@ -107,7 +127,6 @@ void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd) return; } } - //modified by NIZNHY-PKV Tue Jul 03 13:23:57 2012t // aNbCyl=0; aNbCon=0; @@ -229,11 +248,9 @@ void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd) const gp_Dir& aDNj=aIFj.Position().Direction(); // aDot=aDNi*aDNj; - //modified by NIZNHY-PKV Tue Jul 03 10:01:56 2012f if (aDot<0.) { aDot=-aDot; } - //modified by NIZNHY-PKV Tue Jul 03 10:01:52 2012t if (fabs(1.-aDot)<0.0001) { aMp.Add(i); aMp.Add(j); @@ -248,6 +265,8 @@ void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd) return; } // + iMin=-1; + iMax=-1; aDistMin=1.e15; aDistMax=-aDistMin; for (i=0; i myTolerance) { - aInfo.SetKindOfName(GEOMAlgo_KN_QUADRANGLE); - return; + if (aNbV==4 && aNbE==4) { + aIt.Initialize(aF); + if (aIt.More()) { + aW=*((TopoDS_Wire*)&aIt.Value()); } - } - // - // rectangle - aInfo.SetKindOfName(GEOMAlgo_KN_RECTANGLE); - // - // shift location to the center and calc. sizes - aXYZc.SetCoord(0.,0.,0.); - TopExp::MapShapes(aF, TopAbs_VERTEX, aMV); - for (i=1; i<=aNbV; ++i) { - const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i)); - aP=BRep_Tool::Pnt(aV); - const gp_XYZ& aXYZ=aP.XYZ(); - aXYZc=aXYZc+aXYZ; - } - // - // Location : aPc in center of rectangle - // Position : 0z is plane normal - // 0x is along length - // - aXYZc.Divide(4.); - aPc.SetXYZ(aXYZc); - // - gp_Lin aL0(aPx[0], aDx[0]); - gp_Lin aL1(aPx[1], aDx[1]); - // - aD0=aL0.Distance(aPc); - aD1=aL1.Distance(aPc); - // - aLength=aD0; - aWidth =aD1; - aDX=aL1.Direction(); - if (aD0 myTolerance) { + aInfo.SetKindOfName(GEOMAlgo_KN_QUADRANGLE); + return; + } + } + // + // rectangle + aInfo.SetKindOfName(GEOMAlgo_KN_RECTANGLE); + // + // shift location to the center and calc. sizes + aXYZc.SetCoord(0.,0.,0.); + TopExp::MapShapes(aF, TopAbs_VERTEX, aMV); + for (i=1; i<=aNbV; ++i) { + const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i)); + aP=BRep_Tool::Pnt(aV); + const gp_XYZ& aXYZ=aP.XYZ(); + aXYZc=aXYZc+aXYZ; + } + // + // Location : aPc in center of rectangle + // Position : 0z is plane normal + // 0x is along length + // + aXYZc.Divide(4.); + aPc.SetXYZ(aXYZc); + // + gp_Lin aL0(aPx[0], aDx[0]); + gp_Lin aL1(aPx[1], aDx[1]); + // + aD0=aL0.Distance(aPc); + aD1=aL1.Distance(aPc); + // + aLength=aD0; + aWidth =aD1; + aDX=aL1.Direction(); + if (aD0aR[1]) { - aRmin=aR[1]; - aRmax=aR[0]; - aPc=aPC[0]; - gp_Vec aVz(aPC[0], aPC[1]); - gp_Vec aVx(aPC[0], aPX[0]); - gp_Dir aDz(aVz); - gp_Dir aDx(aVx); - gp_Ax2 aAx2(aPc, aDz, aDx); - aAx2new=aAx2; - } - else { - aRmin=aR[0]; - aRmax=aR[1]; - aPc=aPC[1]; - gp_Vec aVz(aPC[1], aPC[0]); - gp_Vec aVx(aPC[1], aPX[1]); - gp_Dir aDz(aVz); - gp_Dir aDx(aVx); - gp_Ax2 aAx2(aPc, aDz, aDx); - aAx2new=aAx2; - } - // - gp_Ax3 aAx3(aAx2new); - aInfo.SetLocation(aPc); - aInfo.SetPosition(aAx3); - aInfo.SetRadius1(aRmax); - aInfo.SetRadius2(aRmin); - aInfo.SetHeight(aHeight); - // - aInfo.SetKindOfName(GEOMAlgo_KN_CONE); } //======================================================================= //function : FillDetails @@ -660,6 +535,7 @@ void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF, //======================================================================= void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF, const gp_Cylinder& aCyl) + { Standard_Integer i, aNbV, aNbE, aNbCE, aNbSE; Standard_Real aT0, aT1, aHeight; @@ -667,78 +543,185 @@ void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF, TopoDS_Edge aE; TopExp_Explorer aExp; TopTools_MapOfShape aM; - GEOMAlgo_KindOfShape aKS; - GEOMAlgo_KindOfName aKN, aKNE; + GEOMAlgo_KindOfName aKNE; GEOMAlgo_KindOfClosed aKCE; // GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF); - aKN=GEOMAlgo_KN_UNKNOWN; - aInfo.SetKindOfName(aKN); - // - aKS=aInfo.KindOfShape(); - if (aKS!=GEOMAlgo_KS_CYLINDER) { - return; - } - // - if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) { - return; - } // + aInfo.SetKindOfDef(GEOMAlgo_KD_ARBITRARY); aNbV=aInfo.NbSubShapes(TopAbs_VERTEX); aNbE=aInfo.NbSubShapes(TopAbs_EDGE); - if (!(aNbV==2 && aNbE==3)) { - return; - } - // - i=0; - aNbCE=0; - aNbSE=0; - aExp.Init(aF, TopAbs_EDGE); - for (; aExp.More(); aExp.Next()) { - aE=TopoDS::Edge(aExp.Current()); - if(aM.Add(aE)) { - const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE); - aKNE=aInfoE.KindOfName(); - aKCE=aInfoE.KindOfClosed(); - if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) { - aPC[aNbCE]=aInfoE.Location(); - ++aNbCE; - } - else if (aKNE==GEOMAlgo_KN_SEGMENT) { - if (BRep_Tool::IsClosed(aE, aF)) { - ++aNbSE; + if (aNbV==2 && aNbE==3) { + const gp_Ax1& aAx1=aCyl.Axis(); + const gp_Dir& aDir=aAx1.Direction(); + const gp_Pnt& aPLoc=aAx1.Location(); + // + i=0; + aNbCE=0; + aNbSE=0; + aExp.Init(aF, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + aE=TopoDS::Edge(aExp.Current()); + if(aM.Add(aE)) { + const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE); + aKNE=aInfoE.KindOfName(); + aKCE=aInfoE.KindOfClosed(); + if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) { + aPC[aNbCE]=aInfoE.Location(); + ++aNbCE; + } + else if (aKNE==GEOMAlgo_KN_SEGMENT) { + if (BRep_Tool::IsClosed(aE, aF)) { + ++aNbSE; + } } } } - } - // - if (!(aNbCE==2 && aNbSE==1)) { - return; - } - // - const gp_Ax1& aAx1=aCyl.Axis(); - const gp_Dir& aDir=aAx1.Direction(); - const gp_Pnt& aPLoc=aAx1.Location(); - gp_Lin aLin(aPLoc, aDir); - // - aT0=ElCLib::Parameter(aLin, aPC[0]); - aT1=ElCLib::Parameter(aLin, aPC[1]); - // - aPc=aPC[0];; - if (aT0>aT1) { - aPc=aPC[1]; - } - aHeight=aPC[0].Distance(aPC[1]); - // - gp_Ax3 aAx3=aCyl.Position(); - aAx3.SetLocation(aPc); - // - aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER); - aInfo.SetPosition(aAx3); - aInfo.SetLocation(aPc); - aInfo.SetHeight(aHeight); + // + if (aNbCE==2 && aNbSE==1) { + gp_Lin aLin(aPLoc, aDir); + // + aT0=ElCLib::Parameter(aLin, aPC[0]); + aT1=ElCLib::Parameter(aLin, aPC[1]); + // + aPc=aPC[0]; + if (aT0>aT1) { + aPc=aPC[1]; + } + aHeight=aPC[0].Distance(aPC[1]); + // + gp_Ax3 aAx3=aCyl.Position(); + aAx3.SetLocation(aPc); + // + aInfo.SetPosition(aAx3); + aInfo.SetLocation(aPc); + aInfo.SetHeight(aHeight); + // + aInfo.SetKindOfDef(GEOMAlgo_KD_SPECIFIED); + return; // conventional cylinder + }//if (aNbCE==2 && aNbSE==1) { + }//if (aNbV==2 && aNbE==3) { +} +//======================================================================= +//function : FillDetails +//purpose : +//======================================================================= +void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF, + const gp_Cone& aCone) +{ + Standard_Integer aNbV, aNbE, aNbCE, aNbSE, aNbDE, i; + Standard_Real aR[3], aHeight, aRmin, aRmax; + gp_Pnt aPC[3], aPD, aPc, aPX[3]; + TopoDS_Vertex aVD; + TopoDS_Edge aE; + TopoDS_Iterator aIt; + TopExp_Explorer aExp; + TopTools_MapOfShape aM; + GEOMAlgo_KindOfShape aKSE; + GEOMAlgo_KindOfName aKNE; + GEOMAlgo_KindOfClosed aKCE; + // + GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF); + // + aInfo.SetKindOfDef(GEOMAlgo_KD_ARBITRARY); + // + aNbV=aInfo.NbSubShapes(TopAbs_VERTEX); + aNbE=aInfo.NbSubShapes(TopAbs_EDGE); + if (aNbV==2 && aNbE==3) { + i=0; + aNbCE=0; + aNbSE=0; + aNbDE=0; + aExp.Init(aF, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + aE=TopoDS::Edge(aExp.Current()); + if(aM.Add(aE)) { + const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE); + aKNE=aInfoE.KindOfName(); + aKCE=aInfoE.KindOfClosed(); + aKSE=aInfoE.KindOfShape(); + if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) { + aPC[i]=aInfoE.Location(); + aR[i]=aInfoE.Radius1(); + // + aIt.Initialize(aE); + if (aIt.More()) { + aVD=*((TopoDS_Vertex*)&aIt.Value()); + } + aPX[i]=BRep_Tool::Pnt(aVD); + // + ++i; + ++aNbCE; + } + else if (aKNE==GEOMAlgo_KN_SEGMENT) { + if (BRep_Tool::IsClosed(aE, aF)) { + ++aNbSE; + } + } + else if (aKSE==GEOMAlgo_KS_DEGENERATED) { + aIt.Initialize(aE); + if (aIt.More()) { + aVD=*((TopoDS_Vertex*)&aIt.Value()); + } + // + aPD=BRep_Tool::Pnt(aVD); + // + ++aNbDE; + } + } + } + // + if ((aNbCE==2 || (aNbCE==1 && aNbDE==1)) && aNbSE==1) { + if (aNbDE==1) { + aPC[1]=aPD; + aR[1]=0.; + } + // + aHeight=aPC[0].Distance(aPC[1]); + // + + gp_Ax2 aAx2new; + // + if (aR[0]>aR[1]) { + aRmin=aR[1]; + aRmax=aR[0]; + aPc=aPC[0]; + gp_Vec aVz(aPC[0], aPC[1]); + gp_Vec aVx(aPC[0], aPX[0]); + gp_Dir aDz(aVz); + gp_Dir aDx(aVx); + gp_Ax2 aAx2(aPc, aDz, aDx); + aAx2new=aAx2; + } + else { + aRmin=aR[0]; + aRmax=aR[1]; + aPc=aPC[1]; + gp_Vec aVz(aPC[1], aPC[0]); + gp_Vec aVx(aPC[1], aPX[1]); + gp_Dir aDz(aVz); + gp_Dir aDx(aVx); + gp_Ax2 aAx2(aPc, aDz, aDx); + aAx2new=aAx2; + } + // + gp_Ax3 aAx3(aAx2new); + aInfo.SetLocation(aPc); + aInfo.SetPosition(aAx3); + aInfo.SetRadius1(aRmax); + aInfo.SetRadius2(aRmin); + aInfo.SetHeight(aHeight); + // + aInfo.SetKindOfDef(GEOMAlgo_KD_SPECIFIED); + return; + }//if ((aNbCE==2 || (aNbCE==1 && aNbDE==1)) && aNbSE==1) { + }//if (aNbV==2 && aNbE==3) { + // + aInfo.SetRadius1 (aCone.RefRadius()); + // + aRmin=0.; // ZZ + aInfo.SetRadius2(aRmin); } - //======================================================================= //function : FillDetails //purpose : @@ -746,6 +729,7 @@ void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF, void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF, const gp_Torus& ) { + Standard_Integer aNbV, aNbE, aNbSE; TopoDS_Edge aE; TopExp_Explorer aExp; @@ -753,42 +737,39 @@ void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF, GEOMAlgo_KindOfShape aKS; // GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF); - aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN); + aInfo.SetKindOfDef(GEOMAlgo_KD_ARBITRARY); // aKS=aInfo.KindOfShape(); if (aKS!=GEOMAlgo_KS_TORUS) { return; } - // + aNbV=aInfo.NbSubShapes(TopAbs_VERTEX); - aNbE=aInfo.NbSubShapes(TopAbs_EDGE); - if (!(aNbV==1 && aNbE==2)) { - return; - } - // - aNbSE=0; - aExp.Init(aF, TopAbs_EDGE); - for (; aExp.More(); aExp.Next()) { - aE=TopoDS::Edge(aExp.Current()); - if (aM.Add(aE)) { - if (BRep_Tool::IsClosed(aE, aF)) { - ++aNbSE; + aNbE=aInfo.NbSubShapes(TopAbs_EDGE); + + if (aNbV==1 && aNbE==2) { + aNbSE=0; + aExp.Init(aF, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + aE=TopoDS::Edge(aExp.Current()); + if (aM.Add(aE)) { + if (BRep_Tool::IsClosed(aE, aF)) { + ++aNbSE; + } } } + // + if (aNbSE==2) { + aInfo.SetKindOfDef(GEOMAlgo_KD_SPECIFIED); + } } - // - if (aNbSE!=2) { - return; - } - aInfo.SetKindOfName(GEOMAlgo_KN_TORUS); } -//modified by NIZNHY-PKV Tue Jul 03 13:29:41 2012f //======================================================================= //function : TreatStepSphere //purpose : //======================================================================= -Standard_Boolean - GEOMAlgo_ShapeInfoFiller::TreatStepSphere(const TopoDS_Solid& aSd) +Standard_Boolean GEOMAlgo_ShapeInfoFiller::TreatStepSphere + (const TopoDS_Solid& aSd) { Standard_Boolean bRet, bIsAllowedType, bOnlyClosed, bIsEqual; Standard_Integer j; @@ -899,4 +880,3 @@ Standard_Boolean IsEqual(const gp_Sphere& aSp1, // return bRet; } -//modified by NIZNHY-PKV Tue Jul 03 13:29:43 2012t diff --git a/src/GEOMAlgo/GEOMAlgo_ShellSolid.cxx b/src/GEOMAlgo/GEOMAlgo_ShellSolid.cxx index 3749b7cd7..964ea96cd 100644 --- a/src/GEOMAlgo/GEOMAlgo_ShellSolid.cxx +++ b/src/GEOMAlgo/GEOMAlgo_ShellSolid.cxx @@ -245,7 +245,7 @@ void GEOMAlgo_ShellSolid::Perform() const BOPDS_IndexRange& aRange=pDS->Range(iRank); aRange.Indices(iBeg, iEnd); const TopoDS_Solid& aSolid=(!iRank) ? *((TopoDS_Solid*)&aTool) : *((TopoDS_Solid*)&aObj); - BRepClass3d_SolidClassifier& aSC=aCtx->SolidClassifier(aSolid); + //BRepClass3d_SolidClassifier& aSC=aCtx->SolidClassifier(aSolid); // //------------------------------ShellSolidBuilder GEOMAlgo_ShellSolidBuilder aSSB; @@ -264,50 +264,50 @@ void GEOMAlgo_ShellSolid::Perform() const TopoDS_Shape& aS=pDS->Shape(i); aType=aS.ShapeType(); if (aType!=TopAbs_FACE) { - continue; + continue; } // aState=TopAbs_UNKNOWN; aF=*((TopoDS_Face*)&aS); // if (!aImages.IsBound(aS)) { - iErr=GEOMAlgo_AlgoTools::PntInFace(aF, aP, aP2D); - if (iErr) { - myErrorStatus=16; - return; - } - // - aState=BOPTools_AlgoTools::ComputeState(aP, aSolid, aTol, aCtx); + iErr=GEOMAlgo_AlgoTools::PntInFace(aF, aP, aP2D); + if (iErr) { + myErrorStatus=16; + return; + } + // + aState=BOPTools_AlgoTools::ComputeState(aP, aSolid, aTol, aCtx); } else { - const BOPCol_ListOfShape& aLSp=aImages.Find(aS); - aNbSp=aLSp.Extent(); - if (aNbSp>0) { - continue; - } - // - if (aNbSp==1) { - aF=*((TopoDS_Face*)&aLSp.First()); - } - // - iErr=GEOMAlgo_AlgoTools::PntInFace(aF, aP, aP2D); - if (iErr) { - myErrorStatus=16; - return; - } - // - aState=BOPTools_AlgoTools::ComputeState(aP, aSolid, aTol, aCtx); + const BOPCol_ListOfShape& aLSp=aImages.Find(aS); + aNbSp=aLSp.Extent(); + if (aNbSp>0) { + continue; + } + // + if (aNbSp==1) { + aF=*((TopoDS_Face*)&aLSp.First()); + } + // + iErr=GEOMAlgo_AlgoTools::PntInFace(aF, aP, aP2D); + if (iErr) { + myErrorStatus=16; + return; + } + // + aState=BOPTools_AlgoTools::ComputeState(aP, aSolid, aTol, aCtx); } //---------- if (aState==TopAbs_ON) { - myLSON.Append(aF); + myLSON.Append(aF); } else if (aState==TopAbs_OUT) { - myLSOUT.Append(aF); + myLSOUT.Append(aF); } else if (aState==TopAbs_IN) { - myLSIN.Append(aF); - } + myLSIN.Append(aF); + } //---------- }//for (i=iBeg; i<=iEnd; ++i) { diff --git a/src/GEOMAlgo/GEOMAlgo_Splitter.cxx b/src/GEOMAlgo/GEOMAlgo_Splitter.cxx old mode 100755 new mode 100644 index 4bbcf5c48..f48c5e193 --- a/src/GEOMAlgo/GEOMAlgo_Splitter.cxx +++ b/src/GEOMAlgo/GEOMAlgo_Splitter.cxx @@ -301,7 +301,7 @@ void TreatCompound(const TopoDS_Shape& aC1, TopoDS_Iterator aItC; // aLC.Append (aC1); - while(1) { + for(;;) { aLC1.Clear(); aIt.Initialize(aLC); for (; aIt.More(); aIt.Next()) { diff --git a/src/GEOMAlgo/GEOMAlgo_SurfaceTools.cxx b/src/GEOMAlgo/GEOMAlgo_SurfaceTools.cxx index 59cfe94ad..4a02ac4be 100644 --- a/src/GEOMAlgo/GEOMAlgo_SurfaceTools.cxx +++ b/src/GEOMAlgo/GEOMAlgo_SurfaceTools.cxx @@ -48,10 +48,11 @@ //function : GetState //purpose : //======================================================================= - Standard_Integer GEOMAlgo_SurfaceTools::GetState(const gp_Pnt& aP, - const GeomAdaptor_Surface& aGAS, - const Standard_Real aTol, - TopAbs_State& aState) + Standard_Integer GEOMAlgo_SurfaceTools::GetState + (const gp_Pnt& aP, + const GeomAdaptor_Surface& aGAS, + const Standard_Real aTol, + TopAbs_State& aState) { Standard_Integer iErr = 0; GeomAbs_SurfaceType aType = aGAS.GetType(); @@ -95,10 +96,11 @@ //function : GetState //purpose : //======================================================================= - Standard_Integer GEOMAlgo_SurfaceTools::GetState(const gp_Pnt& aP, - const Handle(Geom_Surface)& aSurf, - const Standard_Real aTol, - TopAbs_State& aState) + Standard_Integer GEOMAlgo_SurfaceTools::GetState + (const gp_Pnt& aP, + const Handle(Geom_Surface)& aSurf, + const Standard_Real aTol, + TopAbs_State& aState) { Standard_Integer iErr; GeomAdaptor_Surface aGAS; @@ -114,7 +116,8 @@ //function : ReverseState //purpose : //======================================================================= - TopAbs_State GEOMAlgo_SurfaceTools::ReverseState(const TopAbs_State aState) + TopAbs_State GEOMAlgo_SurfaceTools::ReverseState + (const TopAbs_State aState) { TopAbs_State aRSt=aState; // @@ -135,10 +138,11 @@ //function : IsCoaxial //purpose : //======================================================================= -Standard_Boolean GEOMAlgo_SurfaceTools::IsCoaxial(const gp_Pnt& aP1, - const gp_Pnt& aP2, - const gp_Cylinder& aCyl, - const Standard_Real aTol) +Standard_Boolean GEOMAlgo_SurfaceTools::IsCoaxial + (const gp_Pnt& aP1, + const gp_Pnt& aP2, + const gp_Cylinder& aCyl, + const Standard_Real aTol) { const gp_XYZ &aLoc = aCyl.Location().XYZ(); const gp_Ax1 &aAxis = aCyl.Axis(); @@ -147,7 +151,7 @@ Standard_Boolean GEOMAlgo_SurfaceTools::IsCoaxial(const gp_Pnt& aP1, gp_XYZ aDP2 = aP2.XYZ().Subtracted(aLoc); Standard_Real aDot1 = aDP1.Dot(aDAxis); Standard_Real aDot2 = aDP1.Dot(aDAxis); - Standard_Real aTol2 = aTol*aTol; + //Standard_Real aTol2 = aTol*aTol; // Project P1 and P2 onto a plane with location aLoc and Norm aDAxis. aDP1.Subtract(aDAxis.Multiplied(aDot1)); @@ -160,7 +164,7 @@ Standard_Boolean GEOMAlgo_SurfaceTools::IsCoaxial(const gp_Pnt& aP1, if (fabs(aRadius1 - aRadius2) <= aTol) { // Check the deflection of the middle point. gp_XYZ aMidP = 0.5*(aDP1 + aDP2); - Standard_Real aMidRadius1 = aMidP.Modulus(); + //Standard_Real aMidRadius1 = aMidP.Modulus(); if (fabs(aRadius1 - aRadius2) <= aTol) { isOn = Standard_True; @@ -173,7 +177,8 @@ Standard_Boolean GEOMAlgo_SurfaceTools::IsCoaxial(const gp_Pnt& aP1, //function : IsAnalytic //purpose : //======================================================================= -Standard_Boolean GEOMAlgo_SurfaceTools::IsAnalytic(const Handle(Geom_Surface)& aSurf) +Standard_Boolean GEOMAlgo_SurfaceTools::IsAnalytic + (const Handle(Geom_Surface)& aSurf) { Standard_Boolean bRet; GeomAbs_SurfaceType aType; @@ -190,8 +195,9 @@ Standard_Boolean GEOMAlgo_SurfaceTools::IsAnalytic(const Handle(Geom_Surface)& a //function : IsConformState //purpose : //======================================================================= -Standard_Boolean GEOMAlgo_SurfaceTools::IsConformState(const TopAbs_State aST1, - const GEOMAlgo_State aST2) +Standard_Boolean GEOMAlgo_SurfaceTools::IsConformState + (const TopAbs_State aST1, + const GEOMAlgo_State aST2) { Standard_Boolean bRet=Standard_False; // From d63b189331780e61927d8ba3b558346f334e579a Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 7 May 2015 13:43:14 +0300 Subject: [PATCH 03/54] 22853: EDF 9924 GEOM: Dimension histogram - Fix bug with improper range computing when selecting list of shapes --- src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx b/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx index 81ae5aeba..37b5f6b2c 100644 --- a/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx +++ b/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx @@ -45,6 +45,7 @@ namespace GEOMUtils std::map measures; std::list::const_iterator it; + int shift = 0; for ( it = shapes.begin(); it != shapes.end(); ++it ) { double aMeasure; TopTools_IndexedMapOfShape aSubShapesMap; @@ -80,8 +81,9 @@ namespace GEOMUtils // get global index of sub-shape index = aSubShapesMap.FindIndex( aSubShape ); // keep measures to distribute it - measures[index] = aMeasure; + measures[shift+index] = aMeasure; } + shift += aNbS; } return measures; } From cf8092c35525622bdca3515afae15c6d7d245046 Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 7 May 2015 14:08:49 +0300 Subject: [PATCH 04/54] 22853: EDF 9924 GEOM: Dimension histogram - Alternative fix for list of shapes case, as previous one is incorrect. --- src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx b/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx index 37b5f6b2c..4ef3b8658 100644 --- a/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx +++ b/src/GEOMUtils/GEOMUtils_ShapeStatistics.cxx @@ -83,7 +83,7 @@ namespace GEOMUtils // keep measures to distribute it measures[shift+index] = aMeasure; } - shift += aNbS; + shift += aSubShapesMap.Extent(); } return measures; } From 63738c1a1f18d2acafa77eea3e9f1dc21c84c991 Mon Sep 17 00:00:00 2001 From: mpa Date: Wed, 20 May 2015 14:19:08 +0300 Subject: [PATCH 05/54] INT PAL 0052749: Wrong icon and pop-up of a reversed group --- src/GEOMImpl/GEOMImpl_IHealingOperations.cxx | 2 +- .../GEOMImpl_ITransformOperations.cxx | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx b/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx index 4bc9a6700..82654f21f 100644 --- a/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx @@ -1116,7 +1116,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientationCopy (Handle(G return NULL; //There is no function which creates an object to be processed // Add a new object - Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), GEOM_COPY); if (theObject->GetType() == GEOM_VECTOR) { // Mantis issue 21066 //Add the function diff --git a/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx b/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx index 5d89b0c0a..0373f9b05 100644 --- a/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx @@ -218,7 +218,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::TranslateTwoPointsCopy if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved //Add a new Copy object - Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY); //Add a translate function Handle(GEOM_Function) aFunction = @@ -271,7 +271,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::TranslateDXDYDZCopy if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved //Add a new Copy object - Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY); //Add a translate function Handle(GEOM_Function) aFunction = @@ -376,7 +376,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::TranslateVectorCopy if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved //Add a new Copy object - Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY); //Add a translate function Handle(GEOM_Function) aFunction = @@ -807,7 +807,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::MirrorPlaneCopy if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be mirrored //Add a new Copy object - Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY); //Add a mirror function Handle(GEOM_Function) aFunction = @@ -910,7 +910,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::MirrorPointCopy if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be mirrored //Add a new Copy object - Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY); //Add a mirror function Handle(GEOM_Function) aFunction = @@ -1013,7 +1013,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::MirrorAxisCopy if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be mirrored //Add a new Copy object - Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY); //Add a mirror function Handle(GEOM_Function) aFunction = @@ -1114,7 +1114,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::OffsetShapeCopy if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be offset //Add a new Copy object - Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY); //Add a new Offset function Handle(GEOM_Function) aFunction = @@ -1364,7 +1364,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::ScaleShapeCopy if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be scaled //Add a new Copy object - Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY); //Add a scale function Handle(GEOM_Function) aFunction = @@ -1555,7 +1555,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::PositionShapeCopy if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be set in position //Add a new Copy object - Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY); //Add a position function Standard_Integer aType = POSITION_SHAPE_COPY; @@ -1734,7 +1734,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::RotateCopy (Handle(GEOM_Objec 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()); + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY); //Add a rotate function aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_COPY); @@ -2088,7 +2088,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::RotateThreePointsCopy (Handle 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()); + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY); //Add a rotate function aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_THREE_POINTS_COPY); @@ -2145,7 +2145,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::TransformLikeOtherCopy if (aSampleFunc.IsNull()) return NULL; // There is no function which creates a sample object // Add a new Copy object - Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType()); + Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY); // Add a transform function (depends on theSample function) Handle(GEOM_Function) aFunction = From c94c721135361d4ac877d3a67b98bc29b7ee2c5f Mon Sep 17 00:00:00 2001 From: akl Date: Tue, 19 May 2015 12:15:20 +0400 Subject: [PATCH 06/54] 22888: EDF 10437 GEOM: Dimensions improvements --- resources/CMakeLists.txt | 1 + resources/SalomeApp.xml.in | 5 +- resources/Y14.5M-2009.ttf | Bin 0 -> 41952 bytes src/GEOMGUI/CMakeLists.txt | 3 + src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx | 421 ++++++++++++++++++ src/GEOMGUI/GEOMGUI_TextTreeWdg.h | 89 ++++ src/GEOMGUI/GEOM_Displayer.cxx | 11 +- src/GEOMGUI/GEOM_msg_en.ts | 19 +- src/GEOMGUI/GEOM_msg_fr.ts | 19 +- src/GEOMGUI/GEOM_msg_ja.ts | 23 +- src/GEOMGUI/GeometryGUI.cxx | 81 +++- src/GEOMGUI/GeometryGUI.h | 6 + .../MeasureGUI_CreateDimensionDlg.cxx | 11 +- .../MeasureGUI_ManageDimensionsDlg.cxx | 5 + 14 files changed, 664 insertions(+), 30 deletions(-) create mode 100644 resources/Y14.5M-2009.ttf create mode 100644 src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx create mode 100644 src/GEOMGUI/GEOMGUI_TextTreeWdg.h diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index cef2c42f2..44d86e7bc 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -35,6 +35,7 @@ SET( _res_files GEOM.config GEOMDS_Resources ShHealing + Y14.5M-2009.ttf 3dsketch.png isoline.png isoline_v.png diff --git a/resources/SalomeApp.xml.in b/resources/SalomeApp.xml.in index 84f53783c..8e83fdbc2 100644 --- a/resources/SalomeApp.xml.in +++ b/resources/SalomeApp.xml.in @@ -92,12 +92,13 @@ - + - + + diff --git a/resources/Y14.5M-2009.ttf b/resources/Y14.5M-2009.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1f1ca199a0c631f368a1e4cefc58af5b83c87d35 GIT binary patch literal 41952 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 AZ2$lO literal 0 HcmV?d00001 diff --git a/src/GEOMGUI/CMakeLists.txt b/src/GEOMGUI/CMakeLists.txt index 211156716..c5e9e928f 100755 --- a/src/GEOMGUI/CMakeLists.txt +++ b/src/GEOMGUI/CMakeLists.txt @@ -76,12 +76,14 @@ SET(GEOMGUI_HEADERS GEOMGUI_Selection.h GEOM_GEOMGUI.hxx GEOMGUI_CreationInfoWdg.h + GEOMGUI_TextTreeWdg.h GEOMGUI_DimensionProperty.h ) # header files / to be processed by moc SET(_moc_HEADERS GEOMGUI_CreationInfoWdg.h + GEOMGUI_TextTreeWdg.h GeometryGUI.h ) @@ -114,6 +116,7 @@ SET(GEOMGUI_SOURCES GEOMGUI_OCCSelector.cxx GEOMGUI_Selection.cxx GEOMGUI_CreationInfoWdg.cxx + GEOMGUI_TextTreeWdg.cxx GEOMGUI_DimensionProperty.cxx ${_moc_SOURCES} ${_rcc_SOURCES} diff --git a/src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx b/src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx new file mode 100644 index 000000000..2c00a3bd4 --- /dev/null +++ b/src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx @@ -0,0 +1,421 @@ +// Copyright (C) 2015 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, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : GEOMGUI_TextTreeWdg.cxx +// Author : Alexander KOVALEV (akl) + +#include "GEOMGUI_TextTreeWdg.h" + +#include "GEOMGUI_DimensionProperty.h" +#include "GeometryGUI.h" +#include "GeometryGUI_Operations.h" +#include +#include + +// GUI includes +#include +#include +#include +#include +#include +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GEOMGUI_TextTreeWdg::GEOMGUI_TextTreeWdg( SalomeApp_Application* app ) + : myDisplayer(NULL) +{ + myStudy = dynamic_cast( app->activeStudy() ); + myDisplayer = GEOM_Displayer( myStudy ); + + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + myVisibleIcon = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) ); + myInvisibleIcon = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) ); + + setWindowTitle( tr( "TEXT_TREE_VIEW_TITLE" ) ); + setObjectName( "geomTextTreeWdg" ); + + setRootIsDecorated( true ); + setSelectionMode( QAbstractItemView::ExtendedSelection ); + setAllColumnsShowFocus( true ); + setUniformRowHeights( true ); + + QStringList columnNames; + columnNames << tr("TEXT_TREE_VIEW_NAME") << ""; + QTreeWidgetItem * headerItem = new QTreeWidgetItem( columnNames ); + headerItem->setIcon( 1, myVisibleIcon ); + setHeaderItem ( headerItem ); + header()->moveSection( 1, 0 ); + header()->setResizeMode( 1, QHeaderView::ResizeToContents ); + + QStringList rootNames; + rootNames << tr("GEOM_DIMENSIONS") << ""; + myDimensionsItem = new QTreeWidgetItem( this, rootNames ); + myDimensionsItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); + addTopLevelItem( myDimensionsItem ); + + // get a free dockable window id + myWindowID = 11; + while( app->dockWindow( myWindowID )) + ++myWindowID; + ++myWindowID; + + createActions(); + setContextMenuPolicy( Qt::CustomContextMenu ); + connect( this, SIGNAL( customContextMenuRequested(const QPoint&) ), + this, SLOT( showContextMenu(const QPoint&) ) ); + + connect( myStudy, SIGNAL( objVisibilityChanged( QString, Qtx::VisibilityState ) ), + this, SLOT( updateVisibilityColumn( QString, Qtx::VisibilityState ) ) ); + connect( app->objectBrowser(), SIGNAL( updated() ), this, SLOT( updateTree() ) ); + GeometryGUI* aGeomGUI = dynamic_cast( app->module( "Geometry" ) ); + connect( aGeomGUI, SIGNAL( DimensionsUpdated( const QString& ) ), this, SLOT( updateBranch( const QString& ) ) ); + connect( this, SIGNAL( itemClicked( QTreeWidgetItem*, int) ), + this, SLOT( onItemClicked( QTreeWidgetItem*, int ) ) ); + +} + +GEOMGUI_TextTreeWdg::~GEOMGUI_TextTreeWdg() +{ + //std::cout<<"~GEOMGUI_TextTreeWdg"<setIcon( myVisibleIcon ); + myActions.insert( GEOMOp::OpShow, a ); + + QAction* b = new QAction( tr( "MEN_ERASE" ), this ); + b->setIcon( myInvisibleIcon ); + myActions.insert( GEOMOp::OpHide, b ); +} + +//================================================================================= +// function : updateTree +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::updateTree() +{ + myStudy = dynamic_cast( SUIT_Session::session()->activeApplication()->activeStudy() ); + _PTR(Study) aDSStudy = myStudy->studyDS(); + if ( aDSStudy ) { + _PTR(SComponent) SC ( aDSStudy->FindComponent( "GEOM" ) ); + if ( SC ) { + _PTR(ChildIterator) anIter ( aDSStudy->NewChildIterator( SC ) ); + anIter->InitEx( true ); + QList objEntries = myObjects.keys(); + while( anIter->More() ) { + _PTR(SObject) valSO ( anIter->Value() ); + _PTR(SObject) refSO; + if ( !valSO->ReferencedObject( refSO ) ) { + // update tree of object's dimensions + QString anEntry = valSO->GetID().c_str(); + updateBranch( anEntry ); + objEntries.removeAll( anEntry ); + } + anIter->Next(); + } + foreach (QString entry, objEntries) { + removeBranch( entry, true ); + } + } + } +} + +//================================================================================= +// function : updateBranch +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::updateBranch( const QString& theEntry ) +{ + myStudy = dynamic_cast( SUIT_Session::session()->activeApplication()->activeStudy() ); + if ( myStudy ) { + _PTR(Study) aStudyDS = myStudy->studyDS(); + if ( aStudyDS ) { + _PTR(SObject) obj( aStudyDS->FindObjectID( theEntry.toStdString() ) ); + QString aName = obj->GetName().c_str(); + + GEOMGUI_DimensionProperty aProp; + aProp.LoadFromAttribute( myStudy, theEntry.toStdString() ); + int nbProps = aProp.GetNumber(); + + QTreeWidgetItem* objectItem = itemFromEntry( theEntry ); + if ( objectItem ) { + removeBranch( theEntry, nbProps > 0 ? false : true ); + } + QStringList itemName; + if ( nbProps > 0 ) { + itemName << aName << ""; + if ( !objectItem ) { + objectItem = new QTreeWidgetItem( myDimensionsItem, itemName ); + objectItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); + objectItem->setData( 1, Qt::UserRole, theEntry ); + myDimensionsItem->addChild( objectItem ); + myObjects.insert( theEntry, objectItem ); + if ( myDimensionsItem->childCount() == 1 ) + myDimensionsItem->setExpanded( true ); + } + bool isDisplayed = myDisplayer.IsDisplayed( theEntry ); + // read dimension records from property + for ( int anIt = 0; anIt < aProp.GetNumber(); ++anIt ) + { + QString aName = aProp.GetName( anIt ); + bool isVisible = aProp.IsVisible( anIt ); + + QTreeWidgetItem* anItem = new QTreeWidgetItem; + anItem->setText( 0, aName ); + // if ( isDisplayed ) + anItem->setIcon( 1, isVisible ? myVisibleIcon : myInvisibleIcon ); + anItem->setData( 0, Qt::UserRole, anIt ); + anItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); + objectItem->addChild( anItem ); + } + } + } + } +} + +//================================================================================= +// function : removeBranch +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::removeBranch( const QString& theEntry, bool force ) +{ + QTreeWidgetItem* objectItem = itemFromEntry( theEntry ); + if ( !objectItem ) + return; + qDeleteAll( objectItem->takeChildren() ); + if ( force ) { + myDimensionsItem->removeChild( objectItem ); + myObjects.remove( theEntry ); + } +} + +//================================================================================= +// function : onItemClicked() +// purpose : called when tree item was clicked +//================================================================================= +void GEOMGUI_TextTreeWdg::onItemClicked( QTreeWidgetItem* theItem, int theColumn ) +{ + if( theColumn != 1 || theItem->icon( 1 ).isNull() || theItem->isDisabled() ) + return; + + std::string anEntry = entryFromItem( theItem->parent() ).toStdString(); + int aDimIndex = idFromItem( theItem ); + GEOMGUI_DimensionProperty aProp; + aProp.LoadFromAttribute( myStudy, anEntry ); + if ( aProp.IsVisible( aDimIndex ) ) { + aProp.SetVisible( aDimIndex, false ); + theItem->setIcon( 1, myInvisibleIcon ); + } else { + aProp.SetVisible( aDimIndex, true ); + theItem->setIcon( 1, myVisibleIcon ); + } + aProp.SaveToAttribute( myStudy, anEntry ); + redisplay( anEntry.c_str() ); +} + +//================================================================================= +// function : idFromItem +// purpose : +//================================================================================= +int GEOMGUI_TextTreeWdg::idFromItem( QTreeWidgetItem* theItem ) +{ + if ( !theItem ) + return -1; + + bool isIdOK = false; + const int anId = theItem->data( 0, Qt::UserRole ).toInt( &isIdOK ); + + return isIdOK ? anId : -1; +} + +//================================================================================= +// function : entryFromItem +// purpose : +//================================================================================= +QString GEOMGUI_TextTreeWdg::entryFromItem( QTreeWidgetItem* theShapeItem ) +{ + if ( !theShapeItem ) + return ""; + + return theShapeItem->data( 1, Qt::UserRole ).toString(); +} + +//================================================================================= +// function : itemFromEntry +// purpose : +//================================================================================= +QTreeWidgetItem* GEOMGUI_TextTreeWdg::itemFromEntry( QString theEntry ) +{ + if ( theEntry.isEmpty() ) + return 0; + + return myObjects.value( theEntry, 0 ); +} + +//================================================================================= +// function : updateVisibilityColumn +// purpose : Update icons of dimension items. +//================================================================================= +void GEOMGUI_TextTreeWdg::updateVisibilityColumn( QString theEntry, Qtx::VisibilityState theState ) +{ + QTreeWidgetItem* anItem = itemFromEntry( theEntry ); + if ( !anItem ) + return; + anItem->setDisabled( theState != Qtx::ShownState ); + QTreeWidgetItem* aChildItem; + GEOMGUI_DimensionProperty aProp; + for ( int i=0; i < anItem->childCount(); i++ ) { + aChildItem = anItem->child( i ); + if ( theState == Qtx::ShownState ) { + aProp.LoadFromAttribute( myStudy, theEntry.toStdString() ); + if ( aProp.GetNumber() == 0 ) + continue; + aChildItem->setIcon( 1, aProp.IsVisible( idFromItem( aChildItem ) ) ? myVisibleIcon : myInvisibleIcon ); + aChildItem->setDisabled( false ); + } else { + aChildItem->setIcon( 1, QIcon() ); + aChildItem->setDisabled( true ); + } + } +} + +//================================================================================= +// function : showContextMenu +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::showContextMenu( const QPoint& pos ) +{ + if ( selectedItems().isEmpty() ) + return; + QMenu aMenu; + aMenu.addAction( myActions[GEOMOp::OpShow] ); + aMenu.addAction( myActions[GEOMOp::OpHide] ); + if ( selectedItems().count() == 1 ) { + QTreeWidgetItem* anItem = selectedItems().first(); + QString anEntry = entryFromItem( anItem->parent() ); + if ( !anEntry.isEmpty() ) { + GEOMGUI_DimensionProperty aProp; + aProp.LoadFromAttribute( myStudy, anEntry.toStdString() ); + if ( aProp.GetNumber() == 0 ) + return; + aMenu.clear(); + if ( aProp.IsVisible( idFromItem( anItem ) ) ) + aMenu.addAction( myActions[GEOMOp::OpHide] ); + else + aMenu.addAction( myActions[GEOMOp::OpShow] ); + } + } + QAction* selPopupItem = aMenu.exec( viewport()->mapToGlobal(pos) ); + if ( selPopupItem == myActions[GEOMOp::OpShow] ) + setVisibility( true ); + else if ( selPopupItem == myActions[GEOMOp::OpHide] ) + setVisibility( false ); +} + +//================================================================================= +// function : setVisibility +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::setVisibility( bool theVisibility ) +{ + if ( myDimensionsItem->isSelected() ) { + // set visibility for all dimensions + QTreeWidgetItem* anItem; + foreach ( QString entry, myObjects.keys() ) { + anItem = itemFromEntry( entry ); + if ( !anItem->isDisabled() ) + setShapeDimensionsVisibility( entry, theVisibility ); + } + return; + } + foreach ( QTreeWidgetItem* item, selectedItems() ) { + if ( item->isDisabled() || item->parent()->isSelected() ) + continue; + QString anEntry = entryFromItem( item ); + if ( !anEntry.isEmpty() ) { + // it is a shape item + setShapeDimensionsVisibility( anEntry, theVisibility ); + } else { + // it is a dimension item + anEntry = entryFromItem( item->parent() ); + setDimensionVisibility( anEntry, item, theVisibility ); + } + } +} + +//================================================================================= +// function : setShapeDimensionsVisibility +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::setShapeDimensionsVisibility( QString theEntry, bool theVisibility ) +{ + QTreeWidgetItem* anItem = itemFromEntry( theEntry ); + QTreeWidgetItem* aChildItem; + for ( int i=0; i < anItem->childCount(); i++ ) { + aChildItem = anItem->child( i ); + setDimensionVisibility( theEntry, aChildItem, theVisibility ); + } + redisplay( theEntry ); +} + +//================================================================================= +// function : setDimensionVisibility +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::setDimensionVisibility( QString theEntry, QTreeWidgetItem* theDimItem, bool theVisibility ) +{ + GEOMGUI_DimensionProperty aProp; + aProp.LoadFromAttribute( myStudy, theEntry.toStdString() ); + int aDimIndex = idFromItem( theDimItem ); + if ( aProp.GetNumber() == 0 || aProp.IsVisible( aDimIndex ) == theVisibility ) + return;; + aProp.SetVisible( aDimIndex, theVisibility ); + aProp.SaveToAttribute( myStudy, theEntry.toStdString() ); + + theDimItem->setIcon( 1, theVisibility ? myVisibleIcon : myInvisibleIcon ); + redisplay( theEntry ); +} + +//================================================================================= +// function : redisplay +// purpose : +//================================================================================= +void GEOMGUI_TextTreeWdg::redisplay( QString theEntry ) +{ + Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( theEntry.toLatin1().constData(), "GEOM", "TEMP_IO" ); + myDisplayer.Redisplay( io ); +} diff --git a/src/GEOMGUI/GEOMGUI_TextTreeWdg.h b/src/GEOMGUI/GEOMGUI_TextTreeWdg.h new file mode 100644 index 000000000..689a21a67 --- /dev/null +++ b/src/GEOMGUI/GEOMGUI_TextTreeWdg.h @@ -0,0 +1,89 @@ +// Copyright (C) 2015 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, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef GEOMGUI_TEXTTREEWDG_H +#define GEOMGUI_TEXTTREEWDG_H + +#include "GEOM_GEOMGUI.hxx" +#include "GEOM_Displayer.h" + +#include +#include + +#include + +class QLabel; +class QLineEdit; +class QString; +class QTreeWidgetItem; +class SalomeApp_Application; +class SalomeApp_Study; + +/*! + * \brief Tree view contains Dimension and Annotation text items: + * - text visibility in OCC viewer + * - text object name + */ +class GEOMGUI_EXPORT GEOMGUI_TextTreeWdg : public QTreeWidget +{ + Q_OBJECT + + public: + GEOMGUI_TextTreeWdg( SalomeApp_Application* app ); + ~GEOMGUI_TextTreeWdg(); + + int getWinID() { return myWindowID; } + + void removeBranch( const QString& theEntry, + bool force = true ); + int idFromItem( QTreeWidgetItem* theItem ); + QString entryFromItem( QTreeWidgetItem* theShapeItem ); + QTreeWidgetItem* itemFromEntry( QString theEntry ); + void setShapeDimensionsVisibility( QString theEntry, bool theVisibility ); + void setDimensionVisibility( QString theEntry, QTreeWidgetItem* theDimItem, bool theVisibility ); + +protected: + void createActions(); + void redisplay( QString theEntry ); + + public slots: + void updateTree(); + void updateBranch( const QString& theEntry ); + +private slots: + void onItemClicked(QTreeWidgetItem*, int ); + void updateVisibilityColumn( QString theEntry, Qtx::VisibilityState theState ); + void setVisibility( bool visibility ); + void showContextMenu( const QPoint& pos ); + + private: + + int myWindowID; + + QIcon myVisibleIcon; + QIcon myInvisibleIcon; + QHash myObjects; + SalomeApp_Study* myStudy; + QTreeWidgetItem* myDimensionsItem; + GEOM_Displayer myDisplayer; + + QMap myActions; //!< menu actions list + +}; +#endif diff --git a/src/GEOMGUI/GEOM_Displayer.cxx b/src/GEOMGUI/GEOM_Displayer.cxx index 205e9db75..3166ac20a 100644 --- a/src/GEOMGUI/GEOM_Displayer.cxx +++ b/src/GEOMGUI/GEOM_Displayer.cxx @@ -1234,11 +1234,12 @@ void GEOM_Displayer::updateDimensions( const Handle(SALOME_InteractiveObject)& t QColor aQColor = aResMgr->colorValue ( "Geometry", "dimensions_color", QColor( 0, 255, 0 ) ); int aLineWidth = aResMgr->integerValue( "Geometry", "dimensions_line_width", 1 ); - double aFontHeight = aResMgr->doubleValue ( "Geometry", "dimensions_font_height", 10 ); + QFont aFont = aResMgr->fontValue ( "Geometry", "dimensions_font", QFont("Y14.5M-2009", 14) ); double anArrowLength = aResMgr->doubleValue ( "Geometry", "dimensions_arrow_length", 5 ); bool isUnitsShown = aResMgr->booleanValue( "Geometry", "dimensions_show_units", false ); QString aUnitsLength = aResMgr->stringValue ( "Geometry", "dimensions_length_units", "m" ); QString aUnitsAngle = aResMgr->stringValue ( "Geometry", "dimensions_angle_units", "deg" ); + bool aUseText3d = aResMgr->booleanValue( "Geometry", "dimensions_use_text3d", false ); // restore dimension presentation from saved attribute or property data AIS_ListOfInteractive aRestoredDimensions; @@ -1304,10 +1305,12 @@ void GEOM_Displayer::updateDimensions( const Handle(SALOME_InteractiveObject)& t aStyle->SetCommonColor( aColor ); aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown ); - aStyle->MakeText3d( Standard_True ); + aStyle->MakeText3d( aUseText3d ); aStyle->MakeTextShaded( Standard_True ); - aStyle->SetExtensionSize( aFontHeight * 0.5 ); - aStyle->TextAspect()->SetHeight( aFontHeight ); + int fsize = aFont.pixelSize() != -1 ? aFont.pixelSize() : aFont.pointSize(); + aStyle->SetExtensionSize( fsize * 0.5 ); + aStyle->TextAspect()->SetFont( aFont.family().toLatin1().data() ); + aStyle->TextAspect()->SetHeight( fsize ); aStyle->ArrowAspect()->SetLength( anArrowLength ); aStyle->LineAspect()->SetWidth( aLineWidth ); aStyle->SetTextHorizontalPosition( aPrs->DimensionAspect()->TextHorizontalPosition() ); diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index c67b290fe..9e13e729b 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -3453,8 +3453,8 @@ Please, select face, shell or solid and try again Line width - PREF_DIMENSIONS_FONT_HEIGHT - Font height + PREF_DIMENSIONS_FONT + Font PREF_DIMENSIONS_ARROW_LENGTH @@ -3476,6 +3476,10 @@ Please, select face, shell or solid and try again PREF_DIMENSIONS_SHOW_UNITS Show units of measurement + + PREF_DIMENSIONS_USE_TEXT3D + Use 3D text + PREF_HIDE_INPUT_OBJECT Hide input objects from the viewer @@ -7238,6 +7242,17 @@ Do you want to create new material? (No info available) + + GEOMGUI_TextTreeWdg + + TEXT_TREE_VIEW_TITLE + Text + + + TEXT_TREE_VIEW_NAME + Name + + EntityGUI_IsolineDlg diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 0ab7e34fc..54b86aee7 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -3401,8 +3401,8 @@ Choisissez une face, une coque ou un solide et essayez de nouveau Epaisseur de la ligne - PREF_DIMENSIONS_FONT_HEIGHT - Taille de police + PREF_DIMENSIONS_FONT + Font PREF_DIMENSIONS_ARROW_LENGTH @@ -3424,6 +3424,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau PREF_DIMENSIONS_SHOW_UNITS Afficher les unités + + PREF_DIMENSIONS_USE_TEXT3D + Use 3D text + PREF_HIDE_INPUT_OBJECT Hide input objects from the viewer @@ -7171,6 +7175,17 @@ Voulez-vous en créer un nouveau ? (aucune information disponible) + + GEOMGUI_TextTreeWdg + + TEXT_TREE_VIEW_TITLE + Text + + + TEXT_TREE_VIEW_NAME + Name + + EntityGUI_IsolineDlg diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts index 75807fcc7..5f181fa6e 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -3344,8 +3344,8 @@ 線幅 - PREF_DIMENSIONS_FONT_HEIGHT - フォント高さ + PREF_DIMENSIONS_FONT + Font PREF_DIMENSIONS_ARROW_LENGTH @@ -3368,8 +3368,12 @@ 測定単位の表示 - PREF_HIDE_INPUT_OBJECT - Hide input objects from the viewer + PREF_DIMENSIONS_USE_TEXT3D + Use 3D text + + + PREF_HIDE_INPUT_OBJECT + Hide input objects from the viewer PREF_ISOS @@ -7056,6 +7060,17 @@ (有効情報なし) + + GEOMGUI_TextTreeWdg + + TEXT_TREE_VIEW_TITLE + Text + + + TEXT_TREE_VIEW_NAME + Name + + EntityGUI_IsolineDlg diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 25832ed53..ffe4ee97f 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -33,6 +33,7 @@ #include "GEOMGUI_OCCSelector.h" #include "GEOMGUI_Selection.h" #include "GEOMGUI_CreationInfoWdg.h" +#include "GEOMGUI_TextTreeWdg.h" #include "GEOMGUI_DimensionProperty.h" #include "GEOM_Constants.h" #include "GEOM_Displayer.h" @@ -86,6 +87,7 @@ #include #include +#include // External includes #include @@ -97,6 +99,7 @@ #include #include #include +#include #include #include @@ -107,6 +110,7 @@ #include #include +#include #include @@ -116,6 +120,10 @@ #include #include +#include +#include +#include + #include "GEOM_version.h" #include "GEOMImpl_Types.hxx" // dangerous hxx (defines short-name macros) - include after all @@ -218,6 +226,7 @@ GeometryGUI::GeometryGUI() : myLocalSelectionMode = GEOM_ALLOBJECTS; myCreationInfoWdg = 0; + myTextTreeWdg = 0; connect( Material_ResourceMgr::resourceMgr(), SIGNAL( changed() ), this, SLOT( updateMaterials() ) ); @@ -1783,6 +1792,11 @@ bool GeometryGUI::activateModule( SUIT_Study* study ) getApp()->insertDockWindow( myCreationInfoWdg->getWinID(), myCreationInfoWdg ); getApp()->placeDockWindow( myCreationInfoWdg->getWinID(), Qt::LeftDockWidgetArea ); + if ( !myTextTreeWdg ) + myTextTreeWdg = new GEOMGUI_TextTreeWdg( getApp() ); + getApp()->insertDockWindow( myTextTreeWdg->getWinID(), myTextTreeWdg ); + getApp()->placeDockWindow( myTextTreeWdg->getWinID(), Qt::LeftDockWidgetArea ); + //NPAL 19674 SALOME_ListIO selected; sm->selectedObjects( selected ); @@ -1844,8 +1858,15 @@ bool GeometryGUI::deactivateModule( SUIT_Study* study ) disconnect( selMrg, SIGNAL( currentSelectionChanged() ), this, SLOT( updateCreationInfo() )); disconnect( selMrg, SIGNAL( currentSelectionChanged() ), this, SLOT( updateFieldColorScale() )); - getApp()->removeDockWindow( myCreationInfoWdg->getWinID() ); - myCreationInfoWdg = 0; + if ( myCreationInfoWdg ) { + getApp()->removeDockWindow( myCreationInfoWdg->getWinID() ); + myCreationInfoWdg = 0; + } + if ( myTextTreeWdg ) { + getApp()->removeDockWindow( myTextTreeWdg->getWinID() ); + disconnect( application(), 0, myTextTreeWdg, 0 ); + myTextTreeWdg = 0; + } EmitSignalCloseAllDialogs(); @@ -1903,6 +1924,8 @@ void GeometryGUI::windows( QMap& mappa ) const mappa.insert( SalomeApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea ); if ( myCreationInfoWdg ) mappa.insert( myCreationInfoWdg->getWinID(), Qt::LeftDockWidgetArea ); + if ( myTextTreeWdg ) + mappa.insert( myTextTreeWdg->getWinID(), Qt::LeftDockWidgetArea ); } void GeometryGUI::viewManagers( QStringList& lst ) const @@ -2237,6 +2260,8 @@ void GeometryGUI::OnSetMaterial(const QString& theName) void GeometryGUI::createPreferences() { + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + int tabId = addPreference( tr( "PREF_TAB_SETTINGS" ) ); int genGroup = addPreference( tr( "PREF_GROUP_GENERAL" ), tabId ); @@ -2333,12 +2358,36 @@ void GeometryGUI::createPreferences() setPreferenceProperty( aDimLineWidthId, "min", 1 ); setPreferenceProperty( aDimLineWidthId, "max", 5 ); - int aDimFontHeightId = addPreference( tr( "PREF_DIMENSIONS_FONT_HEIGHT" ), aDimGroupId, - LightApp_Preferences::DblSpin, "Geometry", "dimensions_font_height" ); + int aDimFontId = addPreference( tr( "PREF_DIMENSIONS_FONT" ), aDimGroupId, LightApp_Preferences::Font, "Geometry", "dimensions_font" ); - setPreferenceProperty( aDimFontHeightId, "min", 1e-9 ); - setPreferenceProperty( aDimFontHeightId, "max", 1e+9 ); - setPreferenceProperty( aDimFontHeightId, "precision", 9 ); + int f = QtxFontEdit::Family | QtxFontEdit::Size; + setPreferenceProperty( aDimFontId, "features", f ); + setPreferenceProperty( aDimFontId, "mode", QtxFontEdit::Custom ); + + Handle(Font_FontMgr) fmgr = Font_FontMgr::GetInstance(); + QString aFontFile = ""; + resMgr->value("resources", "GEOM", aFontFile); + aFontFile = aFontFile + QDir::separator() + "Y14.5M-2009.ttf"; + // add enginier font into combobox + int fontID = QFontDatabase::addApplicationFont( aFontFile ); + Handle(Font_SystemFont) sf = new Font_SystemFont( + new TCollection_HAsciiString("Y14.5M-2009"), + Font_FA_Regular, + new TCollection_HAsciiString(aFontFile.toLatin1().data()) ); + // register font in OCC font manager + fmgr->RegisterFont( sf, Standard_False ); + + // get list of supported fonts by OCC + QStringList anOCCFonts; + TColStd_SequenceOfHAsciiString theFontsNames; + fmgr->GetAvailableFontsNames( theFontsNames ); + for(Standard_Integer i=1; i<=theFontsNames.Length(); i++) { + Handle(TCollection_HAsciiString) str = theFontsNames(i); + anOCCFonts << str->ToCString(); + } + anOCCFonts.removeDuplicates(); + // set the supported fonts into combobox to use its only + setPreferenceProperty( aDimFontId, "fonts", anOCCFonts ); int aDimArrLengthId = addPreference( tr( "PREF_DIMENSIONS_ARROW_LENGTH" ), aDimGroupId, LightApp_Preferences::DblSpin, "Geometry", "dimensions_arrow_length" ); @@ -2353,9 +2402,6 @@ void GeometryGUI::createPreferences() int anAngUnitsId = addPreference( tr( "PREF_DIMENSIONS_ANGLE_UNITS" ), aDimGroupId, LightApp_Preferences::Selector, "Geometry", "dimensions_angle_units" ); - addPreference( tr( "PREF_DIMENSIONS_SHOW_UNITS" ), aDimGroupId, - LightApp_Preferences::Bool, "Geometry", "dimensions_show_units" ); - QStringList aListOfLengthUnits; aListOfLengthUnits << "m"; aListOfLengthUnits << "cm"; @@ -2370,6 +2416,9 @@ void GeometryGUI::createPreferences() setPreferenceProperty( aLengthUnitsId, "strings", aListOfLengthUnits ); setPreferenceProperty( anAngUnitsId, "strings", aListOfAngUnits ); + addPreference( tr( "PREF_DIMENSIONS_SHOW_UNITS" ), aDimGroupId, + LightApp_Preferences::Bool, "Geometry", "dimensions_show_units" ); + int aDimDefFlyout = addPreference( tr( "PREF_DIMENSIONS_DEFAULT_FLYOUT" ), aDimGroupId, LightApp_Preferences::DblSpin, "Geometry", "dimensions_default_flyout" ); @@ -2377,6 +2426,9 @@ void GeometryGUI::createPreferences() setPreferenceProperty( aDimDefFlyout, "max", 1e+9 ); setPreferenceProperty( aDimDefFlyout, "precision", 9 ); + addPreference( tr( "PREF_DIMENSIONS_USE_TEXT3D" ), aDimGroupId, + LightApp_Preferences::Bool, "Geometry", "dimensions_use_text3d" ); + int isoGroup = addPreference( tr( "PREF_ISOS" ), tabId ); setPreferenceProperty( isoGroup, "columns", 2 ); int isoU = addPreference( tr( "PREF_ISOS_U" ), isoGroup, @@ -2483,7 +2535,6 @@ void GeometryGUI::createPreferences() QList aMarkerTypeIndicesList; QList aMarkerTypeIconsList; - SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); for ( int i = GEOM::MT_POINT; i < GEOM::MT_USER; i++ ) { QString icoFile = QString( "ICON_VERTEX_MARKER_%1" ).arg( i ); QPixmap pixmap = resMgr->loadPixmap( "GEOM", tr( qPrintable( icoFile ) ) ); @@ -2645,11 +2696,12 @@ void GeometryGUI::preferencesChanged( const QString& section, const QString& par } else if ( param == QString("dimensions_color") || param == QString("dimensions_line_width") || - param == QString("dimensions_font_height") || + param == QString("dimensions_font") || param == QString("dimensions_arrow_length") || param == QString("dimensions_show_units") || param == QString("dimensions_length_units") || param == QString("dimensions_angle_units") || + param == QString("dimensions_use_text3d") || param == QString("label_color") ) { SalomeApp_Application* anApp = getApp(); @@ -3468,3 +3520,8 @@ void GeometryGUI::dropObjects( const DataObjectList& what, SUIT_DataObject* wher // update Object browser getApp()->updateObjectBrowser( false ); } + +void GeometryGUI::emitDimensionsUpdated( QString entry ) +{ + emit DimensionsUpdated( entry ); +} diff --git a/src/GEOMGUI/GeometryGUI.h b/src/GEOMGUI/GeometryGUI.h index 53d314ed1..f0abf2da2 100644 --- a/src/GEOMGUI/GeometryGUI.h +++ b/src/GEOMGUI/GeometryGUI.h @@ -64,6 +64,7 @@ class LightApp_Selection; class SUIT_ViewManager; class SalomeApp_Study; class GEOMGUI_CreationInfoWdg; +class GEOMGUI_TextTreeWdg; //================================================================================= // class : GeometryGUI @@ -148,6 +149,8 @@ public: SUIT_DataObject* where, const int row, Qt::DropAction action ); + void emitDimensionsUpdated( QString entry ); + public slots: virtual bool deactivateModule( SUIT_Study* ); virtual bool activateModule( SUIT_Study* ); @@ -176,6 +179,7 @@ signals : void SignalDefaultStepValueChanged( double newVal ); void SignalDependencyTreeParamChanged( const QString&, const QString& ); void SignalDependencyTreeRenameObject( const QString& ); + void DimensionsUpdated( const QString& ); protected: virtual LightApp_Selection* createSelection() const; @@ -224,6 +228,8 @@ private: GEOMGUI_CreationInfoWdg* myCreationInfoWdg; + GEOMGUI_TextTreeWdg* myTextTreeWdg; + SALOME_ListIO myTopLevelIOList; friend class DisplayGUI; diff --git a/src/MeasureGUI/MeasureGUI_CreateDimensionDlg.cxx b/src/MeasureGUI/MeasureGUI_CreateDimensionDlg.cxx index 2576676b2..45ef0135f 100644 --- a/src/MeasureGUI/MeasureGUI_CreateDimensionDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_CreateDimensionDlg.cxx @@ -495,12 +495,13 @@ Handle(AIS_Dimension) MeasureGUI_CreateDimensionDlg::CreateDimension() QColor aQColor = aResMgr->colorValue ( "Geometry", "dimensions_color", QColor( 0, 255, 0 ) ); int aLineWidth = aResMgr->integerValue( "Geometry", "dimensions_line_width", 1 ); - double aFontHeight = aResMgr->doubleValue ( "Geometry", "dimensions_font_height", 10 ); + QFont aFont = aResMgr->fontValue ( "Geometry", "dimensions_font", QFont("Y14.5M-2009", 14) ); double anArrowLength = aResMgr->doubleValue ( "Geometry", "dimensions_arrow_length", 5 ); double aDefFlyout = aResMgr->doubleValue ( "Geometry", "dimensions_default_flyout", 20 ); bool isUnitsShown = aResMgr->booleanValue( "Geometry", "dimensions_show_units", false ); QString aUnitsLength = aResMgr->stringValue ( "Geometry", "dimensions_length_units", "m" ); QString aUnitsAngle = aResMgr->stringValue ( "Geometry", "dimensions_angle_units", "deg" ); + bool aUseText3d = aResMgr->booleanValue( "Geometry", "dimensions_use_text3d", false ); OCCViewer_ViewWindow* anActiveView = NULL; @@ -610,10 +611,12 @@ Handle(AIS_Dimension) MeasureGUI_CreateDimensionDlg::CreateDimension() aStyle->SetCommonColor( aColor ); aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown ); - aStyle->MakeText3d( Standard_True ); + aStyle->MakeText3d( aUseText3d ); aStyle->MakeTextShaded( Standard_True ); - aStyle->SetExtensionSize( aFontHeight * 0.5 ); - aStyle->TextAspect()->SetHeight( aFontHeight ); + int fsize = aFont.pixelSize() != -1 ? aFont.pixelSize() : aFont.pointSize(); + aStyle->SetExtensionSize( fsize * 0.5 ); + aStyle->TextAspect()->SetFont( aFont.family().toLatin1().data() ); + aStyle->TextAspect()->SetHeight( fsize ); aStyle->ArrowAspect()->SetLength( anArrowLength ); aStyle->LineAspect()->SetWidth( aLineWidth ); diff --git a/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.cxx b/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.cxx index 7dfda2db9..370204f94 100644 --- a/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_ManageDimensionsDlg.cxx @@ -29,6 +29,7 @@ #include "MeasureGUI_DimensionFilter.h" #include +#include #include #include #include @@ -771,6 +772,8 @@ bool MeasureGUI_ManageDimensionsDlg::ClickOnApply() mySavedPropertyState.SaveToAttribute( aStudy, myEditObject->GetStudyEntry() ); + myGeomGUI->emitDimensionsUpdated( QString( myEditObject->GetStudyEntry() ) ); + return true; } @@ -807,6 +810,8 @@ void MeasureGUI_ManageDimensionsDlg::OnFinish() QVariant() ); redisplay( myEditObject.get() ); + + myGeomGUI->emitDimensionsUpdated( QString( myEditObject->GetStudyEntry() ) ); } //================================================================================= From da1ba107c6893399d40650790023102eae6b6cb6 Mon Sep 17 00:00:00 2001 From: skv Date: Fri, 22 May 2015 17:00:10 +0300 Subject: [PATCH 07/54] 0052604: [TC7.5.1] GetInPlace failure --- src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx | 98 ++++++++++--------------- 1 file changed, 40 insertions(+), 58 deletions(-) diff --git a/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx b/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx index 6c1afa4e9..c7abe5e96 100644 --- a/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx +++ b/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx @@ -126,93 +126,75 @@ Standard_Integer GEOMAlgo_GetInPlaceAPI::GetInPlaceOld return 1; } - TopoDS_Shape aPntShape; - TopoDS_Vertex aVertex; - bool isFound = false; - TopAbs_ShapeEnum iType = TopAbs_SOLID; - //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.; - Standard_Real tab_aWhat[4], tab_aWhere[4]; - Standard_Real dl_l = 1e-3; - Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass; - Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; - Bnd_Box BoundingBox; - gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2]; - GProp_GProps aProps; + // Check shape type. + TopAbs_ShapeEnum iType = GEOMUtils::GetTypeOfSimplePart(theWhat); - iType = GEOMUtils::GetTypeOfSimplePart(theWhat); if (iType == TopAbs_SHAPE) { // Error: An attempt to extract a shape of not supported type. return 2; } - TopExp_Explorer Exp_aWhat ( theWhat, iType ); - TopExp_Explorer Exp_aWhere ( theWhere, iType ); - TopExp_Explorer Exp_Edge ( theWhere, TopAbs_EDGE ); + // Compute confusion tolerance. + Standard_Real aTolConf = Precision::Confusion(); + Standard_Integer i; - // Find the shortest edge in theShapeWhere shape - BRepBndLib::Add(theWhere, BoundingBox); - BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); - min_l = fabs(aXmax - aXmin); - if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin); - if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin); - min_l /= dl_l; - // Mantis issue 0020908 BEGIN - if (!Exp_Edge.More()) { - min_l = Precision::Confusion(); - } - // Mantis issue 0020908 END - for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) { - TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX); - for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) { - aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) ); - tab_Pnt[nbVertex] = aPnt; - } - if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) { - BRepGProp::LinearProperties(Exp_Edge.Current(), aProps); - if ( aProps.Mass() < min_l ) min_l = aProps.Mass(); + for (i = 0; i < 2; ++i) { + TopExp_Explorer anExp(i == 0 ? theWhere : theWhat, TopAbs_VERTEX); + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current()); + const Standard_Real aTolVtx = BRep_Tool::Tolerance(aVtx); + + if (aTolVtx > aTolConf) { + aTolConf = aTolVtx; + } } } - // Compute tolerances - Tol_0D = dl_l; - Tol_1D = dl_l * min_l; - Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l); - Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) ); + // Compute mass tolerance. + Bnd_Box aBoundingBox; + Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; + Standard_Real aMassTol; - if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion(); - if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion(); - if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion(); - if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion(); + BRepBndLib::Add(theWhere, aBoundingBox); + BRepBndLib::Add(theWhat, aBoundingBox); + aBoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + aMassTol = Max(aXmax - aXmin, aYmax - aYmin); + aMassTol = Max(aMassTol, aZmax - aZmin); + aMassTol *= aTolConf; - Tol_Mass = Tol_3D; - if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D; - else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D; - else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D; - - // Searching for the sub-shapes inside the ShapeWhere shape + // Compute the result. + TopExp_Explorer Exp_aWhat (theWhat, iType); + TopExp_Explorer Exp_aWhere (theWhere, iType); + Standard_Real tab_aWhat[4], tab_aWhere[4]; + gp_Pnt aPnt, aPnt_aWhat; + TopoDS_Shape aPntShape; + TopoDS_Vertex aVertex; + bool isFound = false; TopTools_MapOfShape map_aWhere; - for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) { + + for (; Exp_aWhere.More(); Exp_aWhere.Next()) { if (!map_aWhere.Add(Exp_aWhere.Current())) continue; // skip repeated shape to avoid mass addition GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt ); for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) { GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat ); - if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D ) + if (fabs(tab_aWhat[3] - tab_aWhere[3]) <= aMassTol && aPnt_aWhat.Distance(aPnt) <= aTolConf) isFound = true; else { - if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) { + if ((tab_aWhat[3] - tab_aWhere[3]) > aMassTol) { aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape(); aVertex = TopoDS::Vertex( aPntShape ); BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() ); BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() ); - if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() && - fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D ) + if (aWhereDistance.IsDone() && aWhatDistance.IsDone() && + fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= aTolConf) { // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces" // aVertex must be projected to the same point on Where and on What gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1); gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1); - isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D ); + isFound = (pOnWhat.Distance(pOnWhere) <= aTolConf); if ( isFound && iType == TopAbs_FACE ) { // check normals at pOnWhat and pOnWhere From b7331b45228fd331aaa80545873251266da39b2b Mon Sep 17 00:00:00 2001 From: ysn Date: Mon, 25 May 2015 12:45:48 +0300 Subject: [PATCH 08/54] Help Update for version 7.6.0 --- .../input/add_point_on_edge_operation.doc | 31 ++++++----- .../GEOM/input/check_compound_of_blocks.doc | 10 ++-- .../GEOM/input/check_self_intersections.doc | 17 +++--- .../gui/GEOM/input/creating_complex_obj.doc | 6 +-- .../gui/GEOM/input/creating_explode.doc | 54 +++++++++---------- .../GEOM/input/creating_surface_from_face.doc | 8 +-- .../GEOM/input/creating_thickness_page.doc | 26 ++++----- doc/salome/gui/GEOM/input/dependency_tree.doc | 8 +-- doc/salome/gui/GEOM/input/display_mode.doc | 7 ++- .../gui/GEOM/input/extension_operation.doc | 31 +++++------ .../gui/GEOM/input/fast_intersection.doc | 15 +++--- .../gui/GEOM/input/glue_edges_operation.doc | 10 ++-- .../gui/GEOM/input/glue_faces_operation.doc | 4 +- .../GEOM/input/inspect_object_operation.doc | 10 ++-- .../projection_on_cylinder_operation.doc | 13 +++-- .../gui/GEOM/input/sewing_operation.doc | 8 +-- .../GEOM/input/shape_processing_operation.doc | 12 ++--- doc/salome/gui/GEOM/input/shared_shapes.doc | 16 +++--- .../gui/GEOM/input/size_models_range.doc | 50 ++++++++--------- doc/salome/gui/GEOM/input/transfer_data.doc | 19 ++++--- doc/salome/gui/GEOM/input/whatis.doc | 6 +-- .../gui/GEOM/input/working_with_groups.doc | 16 +++--- 22 files changed, 180 insertions(+), 197 deletions(-) diff --git a/doc/salome/gui/GEOM/input/add_point_on_edge_operation.doc b/doc/salome/gui/GEOM/input/add_point_on_edge_operation.doc index 187cefbcd..92d6c31a1 100644 --- a/doc/salome/gui/GEOM/input/add_point_on_edge_operation.doc +++ b/doc/salome/gui/GEOM/input/add_point_on_edge_operation.doc @@ -10,25 +10,24 @@ This operation is available in OCC Viewer only. The \b Result will be a \b GEOM_Object. -\n Location of a new vertex on a selected edge can be defined two ways: +\n The location of a new vertex on the selected edge can be defined in two ways:
      -
    1. We can specify a position (ranging from 0.0 to 1.0) of the - vertex on the selected edge either by length or by parameter. +
    2. By specifying the position (ranging from 0.0 to 1.0) by length or by parameter.

      TUI Command: geompy.DivideEdge(Shape, EdgeID, Value, IsByParameter)

        -
      • \em Shape is a shape which contains an edge to be divided
      • +
      • \em Shape is a shape, which contains an edge to be divided;
      • \em EdgeID is the ID of the edge to be divided, if it is = -1, - then \em Shape should be an edge itself.
      • + then \em Shape should be an edge itself;
      • \em Value is a value of parameter on edge or length parameter, - depending on \em IsByParameter.
      • -
      • \em IsByParameter is a boolean flag, specifying operation mode: - - \c True: \em Value is treated as a curve parameter [0..1] - - \c False: \em Value is treated as a length parameter [0..1]
      • + depending on \em IsByParameter; +
      • \em IsByParameter is a boolean flag, specifying the operation mode: + - \c True: \em Value is treated as a curve parameter; [0..1] + - \c False: \em Value is treated as a length parameter. [0..1]
      \b Arguments: Name + 1 Edge + 1 Value setting the position of - the point according to one of the selected modes. + the point according to the selected mode. The difference between "by parameter" and "by length" modes becomes apparent on the edges with irregular parametrization (for example, @@ -41,15 +40,15 @@ The \b Result will be a \b GEOM_Object. \image html repair8.png \n\n
    3. -
    4. We can select several points that will be projected to the selected +
    5. By selecting several points that will be projected to the selected edge to find the location of new vertices.

      - TUI Command: geompy.DivideEdgeByPoint(Shape, Edge, Points) + TUI Command: geompy.DivideEdgeByPoint(Shape, Edge, Points):

        -
      • \em Shape is a shape which contains an edge to be divided
      • -
      • \em Edge is an edge to be divided (or it's ID, if it is = -1, - then \em Shape should be an edge itself).
      • -
      • \em Points is a list of points to project to \a Edge.
      • +
      • \em Shape is a shape, which contains an edge to be divided;
      • +
      • \em Edge is an edge to be divided (or its ID, if it is = -1, + then \em Shape should be an edge itself);
      • +
      • \em Points is a list of points to be projected to the \a Edge.
      \b Arguments: Name + 1 Edge + 1 or more Points. diff --git a/doc/salome/gui/GEOM/input/check_compound_of_blocks.doc b/doc/salome/gui/GEOM/input/check_compound_of_blocks.doc index 7151dcff7..d903fc1ba 100644 --- a/doc/salome/gui/GEOM/input/check_compound_of_blocks.doc +++ b/doc/salome/gui/GEOM/input/check_compound_of_blocks.doc @@ -8,10 +8,10 @@ This operation checks whether a shape is a compound of glued blocks. To be considered as a compound of blocks, the given shape must satisfy the following conditions: -- Each element of the compound should be a Block (6 quadrangle faces); -- Each quadrangle face is a face that has 1 wire with 4 edges. If there are -more than 4 edges in a single wire and C1 continuity mode is switched on, -a face is quadrangular if it has 4 bounds of C1 continuity. +- Each element of the compound should be a Block, i.e. have 6 quadrangle faces; +- Each quadrangle face should have one wire with four edges. If there are +more than four edges in a single wire and C1 continuity mode is switched on, +a face is quadrangular if it has four bounds with C1 continuity. - Blocks can be connected only via an entire quadrangle face or an entire edge; - The compound should be connected; - Each couple of connecting quadrangle faces should be glued. @@ -20,7 +20,7 @@ a face is quadrangular if it has 4 bounds of C1 continuity. In this dialog: - \b Object - the checked object. \b Selection button allows picking it in the viewer or in the object browser. -- Use C1 criterion - option that shitches on/off the C1 continuity mode. +- Use C1 criterion - option switches on/off the C1 continuity mode. - Angular Tolerance - angular tolerance to check C1 continuity between neighbor edges in a wire. - \b Errors list informs of possible errors, for example: - Not a block; diff --git a/doc/salome/gui/GEOM/input/check_self_intersections.doc b/doc/salome/gui/GEOM/input/check_self_intersections.doc index 8cf4d57bf..41658151a 100644 --- a/doc/salome/gui/GEOM/input/check_self_intersections.doc +++ b/doc/salome/gui/GEOM/input/check_self_intersections.doc @@ -9,17 +9,14 @@ This operation checks the topology of the selected shape to detect self-intersec In this dialog: - \b Object - the checked object. \b Selection button allows picking it in the viewer or in the object browser. -- Level of check - The combo box that allows to set the level of checking shape on self-interference. - It defines which interferferences will be checked. Default value is "All interferences". -- Compute self-intersections button computes self-interferences. -- \b Summary section contains the general report if the object has self-intersections and/or if errors are occured during computation. -- \b Self-intersections list contains the list of self-intersections detected. -Select the intersection(s) to show Sub-shapes in the field to the right. -- \b Apply and Apply and Close buttons are used to store interferences selected in the "Self-intersections" list box in the study for further analysis. -If no any interference is selected, all interferences are published in the study. Each interference is published as a child -compound of the source shape and contains a couple of intersecting sub-shapes. +- Level of check - combo box allows setting the level of self-interference checking. It defines, which interferences will be checked. The default value is "All interferences". +- Compute self-intersections button performs the computation. +- \b Summary section contains the general report about self-intersections of the object and/or errors that occurred during the computation. +- \b Self-intersections list contains the list of detected self-intersections. Select the intersection to show Sub-shapes in the field to the right. +- \b Apply and Apply and Close buttons store the interferences selected in the Self-intersections list box in the study for further analysis. +If no interferences are selected, all of them are published in the study. Each interference is published as a child compound of the source shape and contains a couple of intersecting sub-shapes. -\note This tool is useful for detection of shapes, not suitable for +\note This tool is useful for detection of shapes that are not suitable as arguments of Boolean operations and Partition algorithm. For more information about Partition and Boolean Operations Algorithms and their limitations refer to
      this document. diff --git a/doc/salome/gui/GEOM/input/creating_complex_obj.doc b/doc/salome/gui/GEOM/input/creating_complex_obj.doc index 1fbb1d6a2..01b6eb85f 100644 --- a/doc/salome/gui/GEOM/input/creating_complex_obj.doc +++ b/doc/salome/gui/GEOM/input/creating_complex_obj.doc @@ -15,10 +15,8 @@ axis, creating a body of revolution.
    6. \subpage create_extrusion_alongpath_page "Extrude an object along a path", creating a more complex trajectory object.
    7. \subpage create_pipe_path_page "Restore Path" of a pipe-like shape.
    8. -
    9. \subpage create_thickness_page "Thickness" operation that allows to add a thickness to objects.
    10. - -
    11. \subpage create_groups_page "Generate Groups". -This cross-operation functionality allows creation of groups for certain generation operations.
    12. +
    13. \subpage create_thickness_page "Add thickness" to objects.
    14. +
    15. \subpage create_groups_page "Generate Groups" for certain generation operations.
    16. New entity -> Advanced sub-menu allows creating new geometric diff --git a/doc/salome/gui/GEOM/input/creating_explode.doc b/doc/salome/gui/GEOM/input/creating_explode.doc index c25b719ae..693773973 100644 --- a/doc/salome/gui/GEOM/input/creating_explode.doc +++ b/doc/salome/gui/GEOM/input/creating_explode.doc @@ -16,7 +16,7 @@ obtain from it. The \b Result of the operation will be a List of \b GEOM_Objects (vertexes, edges, wires, faces, shells or solids). -Available choices in the Sub Shapes Type combo box depend on the type +The choices available in the Sub Shapes Type combo box depend on the type of selected Main Object: - \b Compound: to extract compounds; - \b Compsolid: to extract compsolids; @@ -29,72 +29,70 @@ of selected Main Object: - \b Shape: to extract top-level contents of the compound shape; - \b Flat: to extract "flat" contents of the compound shape. -Note: "flat" contents means top-level simple-type sub-shapes extracted from -the compound object recursively (i.e. there is no compounds in the result). -For example, if a compound C1 contains a solid S1 and another compound C2 that -contains solids S2 and S3 (see picture below): +Note: "flat" contents means that top-level simple-type sub-shapes are extracted from +the compound object recursively (i.e. there are no compounds in the result). + +Let us take, for example, compound C1 that contains solid S1 and another compound C2 that +contains solids S2 and S3 (see the picture below): - Explode operation with \b Shape type given as parameter will return S1 and C2; - Explode operation with \b Flat type given as parameter will return S1, S2 and S3. \image html flat_contents.png Switching on Select Sub-shapes check box allows manual selection of sub-shapes -to be extracted from the main object. In this mode the user can select sub-shapes +to be extracted from the main object. In this mode it is possible to select sub-shapes directly in 3D viewer. When Select Sub-shapes check box is switched on, additional \b Filter controls -allow to automatically pick up entites which satisfy specified threshold value(s). -The numerical functor for each sub-shape that is compared with threshold value(s) -is computed according to the shape's topological properties: -- length for edges and wires -- area for faces and shells -- volume for solids, compounds, compsolids +allow to automatically pick up entities, which satisfy the specified threshold value(s). +The numerical functor for each sub-shape that is compared with the threshold value(s) +is computed according to the topological properties of the shape: +- length for edges and wires; +- area for faces and shells; +- volume for solids, compounds and compsolids. Filtering capabilities are not available for vertices. -In order to filter out some entities: -- Activate one or two filtering controls by switching on corresponding check boxes; -- Select required threshold comparator type; the following choices are available: +To filter out some entities it is necessary to do the following: +- Activate one or two filtering controls by switching on the corresponding check boxes; +- Select the required threshold comparator type; the following choices are available: - Less Than or Equal or Less Than for the first comparator; - Greater Than or Equal or Greater Than for the second comparator; -- Enter required threshold value (values); +- Enter the required threshold value (values); - Press \b Apply button in the \b Filter group. -The entities which satisfy entered filtering parameters will be automatically highlighted +The entities, which correspond to the entered filtering parameters, will be automatically highlighted in the 3D viewer. Using TUI Commands you can perform this operation in a variety of ways: - geompy.ExtractShapes(Shape, Type, isSorted) explodes a Shape into sub-shapes of a given Type and returns a List of sub-shapes. - This method does not return the Shape itself if it matches the - Type. -- geompy.SubShapeAll(Shape, Type) explodes a Shape on + This method does not return the Shape itself if it matches the Type. +- geompy.SubShapeAll(Shape, Type) explodes a Shape into sub-shapes of a given Type and returns a List of sub-shapes. -- geompy.SubShapeAllIDs(Shape, Type) explodes a Shape on - sub-shapes of a given Type and returns a List of IDs of - sub-shapes. +- geompy.SubShapeAllIDs(Shape, Type) explodes a Shape into sub-shapes of a given Type and returns a List of IDs of sub-shapes. - geompy.SubShapeAllSortedCentres(Shape, Type) explodes a - shape on sub-shapes of a given type and sorts them taking into account + shape into sub-shapes of a given type and sorts them taking into account their gravity centers, to provide a stable order of sub-shapes. It returns a list of sub-shapes. - geompy.SubShapeAllSortedCentresIDs(Shape, Type) explodes - a shape on sub-shapes of a given type and sorts them taking into + a shape into sub-shapes of a given type and sorts them taking into account their gravity centers, to provide a stable order of sub-shapes. It returns a List of IDs of sub-shapes. - geompy.SubShape(Shape, Type, ListOfInd) allows to obtain - a compound of sub-shapes of the Shape, selected by they indices in a + a compound of sub-shapes of the Shape, selected by their indexes in a list of all sub-shapes of the given Type. Each index is in the range [1, Nb_Sub-Shapes_Of_Given_Type]. - geompy.SubShapeSortedCentres(Shape, Type, ListOfInd) allows to obtain a compound of sub-shapes of the Shape, selected by - they indices in sorted list of all sub-shapes of the given Type. Each + their indexes in a sorted list of all sub-shapes of the given Type. Each index is in the range [1, Nb_Sub-Shapes_Of_Given_Type] Arguments: 1 SHAPE + 1 type of SubShape. Example: -\image html explode.png "A box, exploded into faces" +\image html explode.png "A box exploded into faces" */ diff --git a/doc/salome/gui/GEOM/input/creating_surface_from_face.doc b/doc/salome/gui/GEOM/input/creating_surface_from_face.doc index 6034ed5e3..a707dc64e 100644 --- a/doc/salome/gui/GEOM/input/creating_surface_from_face.doc +++ b/doc/salome/gui/GEOM/input/creating_surface_from_face.doc @@ -4,10 +4,10 @@ To create a Surface From Face in the Main Menu select New Entity - > Basic - > Surface From Face -\n This function takes some face as input parameter and creates new -GEOM_Object, i.e. topological shape by extracting underlying surface -of the source face and limiting it by the Umin, Umax, Vmin, Vmax -parameters of the source face (in the parametrical space). +\n This function takes a face at input and creates a new +GEOM_Object, i.e. topological shape by extracting the underlying surface +of the source face and limiting it by the Umin, Umax, Vmin and Vmax +parameters of the source face (in the parametric space). \n \ref restore_presentation_parameters_page "Advanced options". diff --git a/doc/salome/gui/GEOM/input/creating_thickness_page.doc b/doc/salome/gui/GEOM/input/creating_thickness_page.doc index 140c02fc1..88dfc221e 100644 --- a/doc/salome/gui/GEOM/input/creating_thickness_page.doc +++ b/doc/salome/gui/GEOM/input/creating_thickness_page.doc @@ -2,26 +2,28 @@ \page create_thickness_page Thickness Construction -To add a \b Thickness to a shape in the Main Menu select New Entity - > Generation - > Thickness -\n -It is possible to create a Solid from a Face or a Shell by applying a -\b Thickness. To do it you should define an \b Object that is a Face or a -Shell, \b Thickness and to define the thickness direction by means of -Thicken towards the inside check box. +To add \b Thickness to a shape in the Main Menu select New Entity - > Generation - > Thickness. + +Switch between adding thickness to a Face (Shell) or a Solid using radio buttons. + +Firstly, \b Thickness can be applied to a Face or a Shell to create a Solid. \image html thickness.png +It is necessary to define an \b Object (Face or Shell) and the value of \b Thickness. +Thicken towards the inside check box allows changing the thickness direction. + Example: \image html thickness_result.png "Thickness of Shell" -It is possible to apply \b Thickness to a Solid. The result of this operation -is the hollowed Solid. To do it you should define an \b Object that is a Solid, -\b Faces to be removed from result, \b Thickness and the thickness direction by -means of Thicken towards the inside check box. +Secondly, the \b Thickness can be applied to a Solid to create a hollowed Solid. \image html thicksolid.png +It is necessary to define a Solid \b Object \b Faces to be removed from the result and \b Thickness. +Thicken towards the inside check box allows changing the thickness direction. + Example: \image html thicksolid_result.png "Thickness of Solid" @@ -36,8 +38,8 @@ Modifies a shape to make it a thick solid. Arguments: Name + 1 shape (face, shell or solid) + thickness + the list of face IDs. -\n If the shape is face or shell the list of face IDs is not used. -The thickness can be positive or negative for thicken towards the inside. +\n If the shape is a face or a shell the list of face IDs is not used. +The thickness can be positive or negative for thickening towards the inside. \n\n Advanced options \ref preview_anchor "Preview" Our TUI Scripts provide you with useful examples of creation of diff --git a/doc/salome/gui/GEOM/input/dependency_tree.doc b/doc/salome/gui/GEOM/input/dependency_tree.doc index 2f07c9bd3..b8346eec7 100644 --- a/doc/salome/gui/GEOM/input/dependency_tree.doc +++ b/doc/salome/gui/GEOM/input/dependency_tree.doc @@ -34,7 +34,7 @@ All necessary parameters of Dependency Tree Viewer can be edited in the \ref pre Tree nodes in the Dependency Viewer are named according to the study names of the corresponding objects. -All nodes have fixed size, so long names are cut; the full object name can be seen in the tooltip +All nodes have fixed size, so long names are cut; the full object name can be seen in the tool-tip when the cursor is hovered over the node. "Dependency Tree" view supports the following states of nodes: @@ -61,11 +61,11 @@ Browser, OCC Viewer or Dependency Tree Viewer; Dependency Tree Viewer shows oriented links between nodes to represent the dependency direction. The viewer supports the following states of links: -
      • Unidirectional link - shows that object B depends on object A;
      +
      • Unidirectional link - shows that object \b B depends on object \b A;
      \image html tree_unidir_link.png -
      • Bidirectional link - shows that object B depends on -object A and, at the same time, object A depends on object B;
      +
      • Bidirectional link - shows that object \b B depends on +object \b A and, at the same time, object \b A depends on object \b B;
      \image html tree_bidir_link.png
      • Self-dependency link - shows that an object depends on itself;
      diff --git a/doc/salome/gui/GEOM/input/display_mode.doc b/doc/salome/gui/GEOM/input/display_mode.doc index 7ba535184..af842ccf1 100644 --- a/doc/salome/gui/GEOM/input/display_mode.doc +++ b/doc/salome/gui/GEOM/input/display_mode.doc @@ -29,7 +29,7 @@ functionality for all objects in the current view via the main menu \n TUI Command: gg.setVectorsMode(ID, Bool) -\n Also it is possible to show the vertices of the selected +\n It is possible to show the vertices of the selected shape. For this, choose in the context menu of the shape Display mode -> Show Vertices, or apply this functionality for all objects in the current view via the main menu @@ -40,10 +40,9 @@ functionality for all objects in the current view via the main menu \n TUI Command: gg.setVerticesMode(ID, Bool) -\n Moreover user can show the name of the selected -shape. For this, choose in the context menu of the shape +\n To show the name of the selected shape, choose in its context menu Display mode -> Show Name, or apply this -functionality for all objects in the current view via the main menu +functionality for all objects in the current view via the main menu option View -> Display Mode -> Show/Hide Name. \image html name_mode.png diff --git a/doc/salome/gui/GEOM/input/extension_operation.doc b/doc/salome/gui/GEOM/input/extension_operation.doc index 605ff176f..dd2ad27fa 100644 --- a/doc/salome/gui/GEOM/input/extension_operation.doc +++ b/doc/salome/gui/GEOM/input/extension_operation.doc @@ -1,25 +1,20 @@ /*! -\page extension_operation_page Extension of an Edge or a Face +\page extension_operation_page Extension -\n To produce an \b Extension in the Main Menu select -Operations - > Transformation - > Extension +\n To produce an \b Extension of an Edge or a Face select in the Main Menu +Operations - > Transformation - > Extension. The type of extension is defined using the radio buttons. -\n This operation resizes an \b Edge by means of first - and last parameters modification or a \b Face by means of modification - of minimal and maximal U- and V-Parameters. \n -\ref restore_presentation_parameters_page "Advanced options". +Firstly it is possible to resize an \b Edge by modifying its first +and last parameters -The type of extension is defined using the radio buttons. +\image html extension1.png "Edge Extension" -Firstly it is possible to resize an \b Edge. \n TUI Command: geompy.ExtendEdge(theEdge, theMin, theMax), where \em theEdge the input edge to be resized, \em theMin the minimal parameter value, \em theMax the maximal parameter value. \n Arguments: Name + Object (Edge) + 2 values (Min and Max Parameters). -\image html extension1.png "Extension of an Edge" - \n Example: \image html extend_edge_example.png "Original edge (white) and extended edge" @@ -28,8 +23,12 @@ parameter value, \em theMax the maximal parameter value. negative, the input Edge is extended, otherwise it is shrinked by \b theMin parameter. If \b theMax is greater than 1, the Edge is extended, otherwise it is shrinked by \b theMax parameter. + +Secondly it is possible to resize a \b Face by modifying its +minimal and maximal U- and V-Parameters. -Secondly it is possible to resize a \b Face. + \image html extension2.png "Face Extension" + \n TUI Command: geompy.ExtendFace(theFace, theUMin, theUMax, theVMin, theVMax), where \em theFace the input face to be resized, \em theUMin the minimal U-Parameter value, \em theUMax the maximal U-Parameter @@ -38,18 +37,16 @@ V-Parameter value. \n Arguments: Name + Object (Face) + 4 values (Min and Max U- and V-Parameters). -\image html extension2.png "Extension of a Face" \n Example: -\image html extend_face_example.png "The original face (gray) and a result - face shrinked along U-Direction and extended along V-Direction" +\image html extend_face_example.png "The original face (gray) and a result face shrinked along U-Direction and extended along V-Direction" \note The input Face U- and V-Parameters range is [0, 1]. If \b theUMin parameter is negative, the input Face is extended, otherwise it is - shrinked along U-Direction by \b theUMin parameter. If theUMax is + shrinked along U-Direction by \b theUMin parameter. If \b theUMax is greater than 1, the Face is extended, otherwise it is shrinked along - U-Direction by \b theUMax parameter. So as for \b theVMin, \b theVMax + U-Direction by \b theUMax parameter. The same applies to \b theVMin, \b theVMax and V-Direction of the input Face. Our TUI Scripts provide you with useful examples of the use of diff --git a/doc/salome/gui/GEOM/input/fast_intersection.doc b/doc/salome/gui/GEOM/input/fast_intersection.doc index 4de27fc29..f27a6d944 100644 --- a/doc/salome/gui/GEOM/input/fast_intersection.doc +++ b/doc/salome/gui/GEOM/input/fast_intersection.doc @@ -1,11 +1,11 @@ /*! \page fast_intersection_page Fast intersection -This operation checks whether or not two selected shapes are overlapped. +This operation checks if two selected shapes are overlapped. This tool is useful for fast detection of intersections and gaps. In contrast to Boolean Operations, Partition and Detect Self-intersection -algorithms that compute topological intersections, this algoritm computes +algorithms that compute topological intersections, this algorithm computes intersections by generating tessellation (triangulation) of the source shapes and detecting overlapping of resulting meshes. High performance is achieved through the use of existing triangulation of faces. @@ -28,22 +28,21 @@ of the GUI module's documentation. In this dialog: -- \b Object 1 - first checked object. \b Selection button allows picking it in the viewer or in the object browser. -- \b Object 2 - second checked object. \b Selection button allows picking it in the viewer or in the object browser. +- Object 1 and Object 2 the checked objects. \b Selection button allows picking them in the viewer or in the object browser. - Deflection coefficient specifies the quality of shapes tessellation. - Detect gaps - when switched on, allows detecting gaps between shapes. -- Tolerance - specifies a distance between shapes used for detecting gaps. +- Tolerance - specifies the distance between shapes used for detecting gaps. - Compute intersections - press this button to compute interferences. - Sub-shapes of Object 1 - list of sub-shapes from the first source shape that localize the intersection. - Sub-shapes of Object 2 - list of sub-shapes from the second source shape that localize the intersection. - \b Apply and Apply and Close buttons are used to store selected intersected shapes in the study for further analysis (see below). -\note Quality of the result depends on the quality of triangulation. Changing a value of the deflection coefficient -parameter can strongly affect the result. On the other hand, small values of deflection coefficient might lead to +\note The result quality depends on the quality of triangulation. Changing the value of the deflection coefficient +parameter can strongly affect the result. However, small values of the deflection coefficient might lead to some performance loss of the algorithm, as number of triangles of the tesselation mesh depends on this parameter. -It is possible to store sub-shapes selected by the user in the study, for the further analysis. +Press Apply and Close or \b Apply button to store the selected sub-shapes in the study for further analysis. The selection will be published as a compound containing intersected sub-shapes from both source objects. TUI Command: geompy.FastIntersect(theShape1, theShape2, theTolerance = 0.0, theDeflection = 0.001), \n diff --git a/doc/salome/gui/GEOM/input/glue_edges_operation.doc b/doc/salome/gui/GEOM/input/glue_edges_operation.doc index eb7d2377c..2b5c8a981 100644 --- a/doc/salome/gui/GEOM/input/glue_edges_operation.doc +++ b/doc/salome/gui/GEOM/input/glue_edges_operation.doc @@ -17,7 +17,7 @@ given tolerance value. \n TUI Command:

      geompy.MakeGlueEdges( theShapes, theTolerance ), -\n where \em theShapes is either a list or compound of shapes to be +\n where \em theShapes is a list or compound of shapes to be glued, and \em theTolerance is a maximum distance between two edges, which can be considered as coincident. @@ -41,12 +41,12 @@ The selected edges will be marked in white. theTolerance is a maximum distance between two edges, which can be considered as coincident. The \b Result will be a list of \b GEOM_Objects (edges), containing one sub-shape per each detected set of - coincident sub-shapes. For example if there are two coincident edges -in selected shapes, the result list contains one of the two coincident edges. + coincident sub-shapes. For example, if there are two coincident edges +in the selected shapes, the result list contains one of the two coincident edges. geompy.MakeGlueEdgesByList( theShapes, theTolerance, theEdges ), -\n where \em theShape is either a list or compound of shapes to be glued, \em - theTolerance is a maximum distance between two edges, which can +\n where \em theShape is a list or compound of shapes to be glued, +\em theTolerance is a maximum distance between two edges, which can be considered as coincident, \em theEdges is a list of edges to be glued. diff --git a/doc/salome/gui/GEOM/input/glue_faces_operation.doc b/doc/salome/gui/GEOM/input/glue_faces_operation.doc index 8f020115b..c6a6fa021 100644 --- a/doc/salome/gui/GEOM/input/glue_faces_operation.doc +++ b/doc/salome/gui/GEOM/input/glue_faces_operation.doc @@ -41,12 +41,12 @@ The selected faces will be marked in white. When the faces are glued their edges are glued as well. By default, other edges are not glued. To force gluing of all edges, check Glue all coincident edges -checkbox. +check-box. \n TUI Commands: geompy.GetGlueFaces( theShapes, theTolerance ), -\n where \em theShapes is either a list or compound of shapes to be glued, \em +\n where \em theShapes is a list or compound of shapes to be glued, \em theTolerance is a maximum distance between two faces, which can be considered as coincident. The \b Result will be a list of \b GEOM_Objects (faces), containing one sub-shape per each detected set of diff --git a/doc/salome/gui/GEOM/input/inspect_object_operation.doc b/doc/salome/gui/GEOM/input/inspect_object_operation.doc index 40cc4c027..0650bd47b 100755 --- a/doc/salome/gui/GEOM/input/inspect_object_operation.doc +++ b/doc/salome/gui/GEOM/input/inspect_object_operation.doc @@ -12,11 +12,11 @@ In this dialog: - Click on the "selection" button and select an object to inspect in the Object Browser or in the viewer. - Show/hide sub-shape(s) in the 3D viewer, by pressing “eye” icon in the first column of the tree view. - Show/hide all sub-shapes in the 3D viewer, by pressing “eye” icon in the first column of the tree view header. -- Rename selected sub-shape by double-clicking on the item or pressing key. -- Show selected sub-shape(s) in the 3D viewer by pressing Show Selected button. -- Show selected sub-shape(s) in the 3D viewer and erase all currently shown objects by pressing Show Only Selected button. -- Hide selected sub-shape(s) from the 3D viewer by pressing Hide Selected button. -- Publish selected sub-shapes in the study, by pressing Publish Selected button. +- Rename the selected sub-shape by double-clicking on the item or pressing key. +- Show the selected sub-shape(s) in the 3D viewer by pressing Show Selected button. +- Show the selected sub-shape(s) in the 3D viewer and erase all currently shown objects by pressing Show Only Selected button. +- Hide the selected sub-shape(s) from the 3D viewer by pressing Hide Selected button. +- Publish the selected sub-shapes in the study, by pressing Publish Selected button. - Close dialog box, by pressing Close button. */ diff --git a/doc/salome/gui/GEOM/input/projection_on_cylinder_operation.doc b/doc/salome/gui/GEOM/input/projection_on_cylinder_operation.doc index be0c5aa27..88e4d9fbd 100644 --- a/doc/salome/gui/GEOM/input/projection_on_cylinder_operation.doc +++ b/doc/salome/gui/GEOM/input/projection_on_cylinder_operation.doc @@ -14,12 +14,11 @@ To make a projection it is necessary to define: - \b Object to be projected. It can be either a planar wire or a face; - \b Radius of the cylinder; - Starting angle from the cylinder's X axis around Z axis. This is -the angle of the projection starting. -- Length angle in which to project the total length of -the wire. If it is unchecked the projection is not scaled and natural +the angle of the projection start. +- Length angle where the total length of +the wire should be projected. If it is unchecked the projection is not scaled and the natural wire length is kept for the projection. - -\ref restore_presentation_parameters_page "Advanced options". +- \ref restore_presentation_parameters_page "Advanced options". \image html proj_on_cyl_dlg.png @@ -29,8 +28,8 @@ wire length is kept for the projection. \n TUI Command: geompy.MakeProjectionOnCylinder(theObject, theRadius, theStartAngle=0.0, theAngleLength=-1.0), -where \em theObject is a shape which has to be projected, \em theRadius -is a cylinder radius, \em theStartAngle the starting angle of projection in +where \em theObject is a shape to be projected, \em theRadius +is a cylinder radius, \em theStartAngle is the starting angle of projection in radians, \em theAngleLength the projection length angle in radians. The \em Result will be a \em GEOM_Object. diff --git a/doc/salome/gui/GEOM/input/sewing_operation.doc b/doc/salome/gui/GEOM/input/sewing_operation.doc index 0008dc80a..9d293dec4 100644 --- a/doc/salome/gui/GEOM/input/sewing_operation.doc +++ b/doc/salome/gui/GEOM/input/sewing_operation.doc @@ -3,18 +3,18 @@ \page sewing_operation_page Sewing \b Sewing operation allows uniting several faces (possibly contained -in a shell, solid or compound) into one shell while geometrically +in a shell, solid or compound) into one shell. Geometrically coincident (within a specified tolerance) edges (or parts of edges) of different faces are replaced by one edge thus producing a shell of faces with shared boundaries.

      This operation is similar to New Entity - > Build - > Shell operation, the difference is that with \b Sewing you can specify the -tolerance and can get a non-manifold result.

      -Possibility to create a non-manifold shell can be used e.g. to create a +tolerance and get a non-manifold result.

      +The possibility to create a non-manifold shell can be used e.g. to create a shell forming several closed domains and then to create several solids with shared boundaries from this shell. -\note Geometrically coincident faces (or part of faces) won't be +\note Geometrically coincident faces (or parts of faces) will not be replaced by one face during \b Sewing. To produce a \b Sewing operation in the Main Menu select Repair - > Sewing. diff --git a/doc/salome/gui/GEOM/input/shape_processing_operation.doc b/doc/salome/gui/GEOM/input/shape_processing_operation.doc index c92d48b8c..643c70638 100644 --- a/doc/salome/gui/GEOM/input/shape_processing_operation.doc +++ b/doc/salome/gui/GEOM/input/shape_processing_operation.doc @@ -56,22 +56,22 @@ merge with neighboring edges.

    17. 3D Tolerance (DropSmallEdges.Tolerance3d) - defines minimum possible distance between two parallel edges.
    18. -
    19. Drop Small Solids (DropSmallSolids) - either removes small +
    20. Drop Small Solids (DropSmallSolids) - removes small solids or merges them with neighboring ones.
      • Width factor tol. (DropSmallSolids.WidthFactorThreshold) - - defines maximum value of 2V/S of a solid which is - considered small, where \a V is volume and \a S is surface area of + defines the maximum value of 2V/S of a solid, which is + considered small, where \a V is the volume and \a S is the surface area of the solid.
      • Volume tol. (DropSmallSolids.VolumeThreshold) - defines - maximum volume of a solid which is considered small.
      • + the maximum volume of a solid, which is considered small.
      • To merge solids (DropSmallSolids.MergeSolids) - if activated, small solids are removed, else small solids are merged to - adjacent non-small solids or left untouched if cannot be merged. + adjacent non-small solids or left untouched if they cannot be merged.
      If the both tolerances are activated a solid is considered small if -it meets the both criteria. +it meets both criteria.
    21. Split Angle (SplitAngle) - splits faces based on conical surfaces, surfaces of revolution and cylindrical surfaces in segments using a certain angle.
    22. diff --git a/doc/salome/gui/GEOM/input/shared_shapes.doc b/doc/salome/gui/GEOM/input/shared_shapes.doc index 802fc45a1..23d94d2f0 100755 --- a/doc/salome/gui/GEOM/input/shared_shapes.doc +++ b/doc/salome/gui/GEOM/input/shared_shapes.doc @@ -15,22 +15,22 @@ Shared Shapes.
      The following dialog box will appear. In this dialog: - Name is the base name of the resulting shapes. -- Shapes are the shapes to fing shared sub-shapes of. +- Shapes are the shapes whose shared sub-shapes should be found. - Sub-shapes Type is the type of required sub-shapes. - Shared by all option specifies what type of shared sub-shapes should be checked: - - \b On: causes to search sub-shapes from the first input shape shared with all other input shapes; - - \b Off: causes to search sub-shapes shared between couples of input shapes. + - \b On: searches for sub-shapes from the first input shape shared with all other input shapes; + - \b Off: searches for sub-shapes shared between couples of input shapes. \note For the case when "Shared by all" option is switched off - if an input list of shapes -contains single compound, the sub-shapes shared between all possible couples of its top-level shapes -are searched; otherwise, only sub-shapes that are shared between first input shape and all rest input -shapes are searched. +contains a single compound, the sub-shapes shared between all possible couples of its top-level shapes +are searched for; otherwise, only sub-shapes that are shared between the first input shape and +all other input shapes are searched. Advanced options: \ref preview_anchor "Preview" TUI Command: geompy.GetSharedShapesMulti( Shapes, Type ), -
      where \em Shapes is a list or compound of shapes to fing shared sub- -shapes of and \em Type is the type of required sub-shapes. +
      where \em Shapes is a list or compound of shapes, whose shared sub- +shapes should be found and \em Type is the type of required sub-shapes. Our TUI Scripts provide you with useful examples of the use of Get Shared Shapes functionality: diff --git a/doc/salome/gui/GEOM/input/size_models_range.doc b/doc/salome/gui/GEOM/input/size_models_range.doc index 5f77a22e3..c8594abff 100644 --- a/doc/salome/gui/GEOM/input/size_models_range.doc +++ b/doc/salome/gui/GEOM/input/size_models_range.doc @@ -4,37 +4,33 @@ \tableofcontents -This document determines the range of numbers (tolerances, locations -and sizes) that are to be taken into account for any 3D model design -in Salome. Although it is not obligatory to create models within this range, -algorithms can fail or return unexpected result in this case. +In Salome and Open CASCADE Technology (OCCT), which is a modeling core +of Salome %GEOM module, any model has its location in the 3D-space and size. + +This document defines the range of values (tolerances, locations +and sizes) that should be taken into account for any 3D model design. -This document refers mainly to Open CASCADE Technology (OCCT). However it -concerns Salome as well as OCCT is a modeling core of Salome %GEOM module. - -Any model in 3D-space has its location and sizes. The last two things in Salome -and OCCT are represented by the double precision floating point numbers. - -The goal of the document is to define the range of numbers that can be used in -modeling algorithms provided by Salome and Open CASCADE Technology. +It is not obligatory to create models within this range, +however, algorithms can fail or return unexpected results if the +recommendations are not followed. \section sec1 Maximal Size of the Model -The Maximal Size of the model is a number defined as the maximal diameter of +The Maximal Size of the model corresponds to the maximal diameter of enclosed sphere built for the model. In OCCT any model has a location defined -relative the absolute origin. Thus the maximal diameter above should be built +relatively to the absolute origin. Thus the maximal diameter should be built taking into account the model itself and its location. -In Open CASCADE there are two tolerances: Tolerance Confusion (TolC) +In OCCT there are two tolerances: Tolerance Confusion (TolC) and Tolerance Angular (TolA) (see OCCT Precision package for more details). -These values are used for geometric comparisons. They are not used inside -low-level algorithms (intersection for e.g.), where more precise values are +These values are used for geometric comparisons. However, they are not used inside +low-level algorithms (e.g. intersection), where more precise values are used instead. The value TolC guarantees that the error associated with -the computations for given geometric entity is not greater than TolC. +the computations for a given geometric entity is not greater than TolC. -- TolC - precision value when checking coincidence of two points +- TolC - precision value used to check the coincidence of two points [by default 1.e-7]; -- TolA - precision value when checking the equality of two angles +- TolA - precision value used to check the equality of two angles [by default 1.e-12]. For more information on tolerance definition please see @@ -43,8 +39,8 @@ that are due to modeling errors or inaccuracies of tolerance usage please refer to Chapter 9.2.2 of the same document. To provide robust geometric modeling the computations should be consistent, -i.e. the one tolerance value should be used for all computations. To provide -consistent computations the values TolC and TolA should be consistent: +i.e. the one tolerance value should be used for all computations. Thus, the +TolC and TolA values should be consistent:
      Smax = TolC / TolA             (1)
      @@ -56,16 +52,16 @@ In accordance with (1) the Maximal Size for the Model is [by default]: \section sec2 Minimal Size of the Model -The Minimal Size of the Model is defined as maximal diameter of enclosed +The Minimal Size of the Model is defined as the maximal diameter of enclosed sphere built for the smallest BRep entity of the Model. -All models in Open CASCADE Technology are represented using double precision +All models in OCCT are represented using double precision floating point numbers. This representation contains approximately 14-16 significant digits. -From the experience of using it is considered that the least four significant +From the experience, it is considered that the last four significant digits contain rounding-off errors occurring during the computation. So -(taking in account the worst cases), there are ten reliable significant digits +(taking into account the worst cases), there are ten reliable significant digits for double precision floating point numbers. Having the estimation it is possible to compute the value of the Minimal size of the model: @@ -78,7 +74,7 @@ In accordance with (2) for the default value it will be [by default]: \section sec3 Full Range of Sizes The values Smax (2), Smin (4) are theoretical. Taking into -account the practical purposes of improving the reliability the lower limit +account the practical purposes of improving the reliability, the lower limit should be restricted by one order. Thus, the full Range of Sizes of the Models is: diff --git a/doc/salome/gui/GEOM/input/transfer_data.doc b/doc/salome/gui/GEOM/input/transfer_data.doc index b34b34f31..87a64860f 100644 --- a/doc/salome/gui/GEOM/input/transfer_data.doc +++ b/doc/salome/gui/GEOM/input/transfer_data.doc @@ -21,24 +21,23 @@ In this dialog:
      • Source Shape is an object that is a source of non-topological data.
      • Destination Shape is a data destination object.
      • -
      • Type of detection operation is the method to search sub-shapes of - Source Shape in Destination Shape. Data are transferred - from these corresponding sub-shapes. This is a combo-box with the following - possible values: +
      • Type of detection operation allows choosing how to search sub-shapes of the + Source Shape in the Destination Shape. The data are transferred + from these corresponding sub-shapes. The following methods are possible:
          -
        • Get In Place - current implementation of Get In Place algorithm +
        • Get In Place - the current implementation of Get In Place algorithm (default value).
        • -
        • Get In Place (old) - old implementation of Get In Place +
        • Get In Place (old) - the old implementation of Get In Place algorithm.
        • Get In Place By History - Get In Place By History algorithm.
      -To copy data click on \b Apply or Apply and Close button. As the result -it is possible to see how many names and materials are copied as well as -maximum number of names and materials available for copying. This information is -provided on the following message box: +To copy the data click on \b Apply or Apply and Close button. +It is possible to see how many names and materials are copied as well as +the maximum number of names and materials available for copying. This information is +provided in the following message box: \image html transfer_data2.png "Transfer Data Information" diff --git a/doc/salome/gui/GEOM/input/whatis.doc b/doc/salome/gui/GEOM/input/whatis.doc index fad70f01c..43dc0f6f7 100644 --- a/doc/salome/gui/GEOM/input/whatis.doc +++ b/doc/salome/gui/GEOM/input/whatis.doc @@ -5,13 +5,13 @@ This operation provides the list of types and quantities of all topological entities, composing the selected geometrical object. -For the \em COMPOUND or \em COMPSOLID shape, additionally the information about -"flat" content is shown - a number of "simple" top-level shapes enclosed into the compound. +The information about \em COMPOUND or \em COMPSOLID shapes additionally shows +"flat" content - the number of "simple" top-level shapes enclosed into the compound. \image html measures8.png \note This dialog supports navigation through the selectable objects (in OCC 3D viewer only): -- Scroll mouse wheel with pressed \em Ctrl key or press \em "S", \em "P" keys when input focus is +- Scroll mouse wheel with pressed \em Ctrl key or press \em "S", \em "P" keys when the input focus is in the viewer to navigate between selectable objects. - Press left mouse button to select an appropriate object to the dialog box. . diff --git a/doc/salome/gui/GEOM/input/working_with_groups.doc b/doc/salome/gui/GEOM/input/working_with_groups.doc index 36a0d49a3..2ca5154dc 100644 --- a/doc/salome/gui/GEOM/input/working_with_groups.doc +++ b/doc/salome/gui/GEOM/input/working_with_groups.doc @@ -81,24 +81,24 @@ creation of other groups), or skip it by clicking \b Close button. \n The Result of the operation will be a \b GEOM_Object. -The \b Filter controls allow to automatically pick up entites which satisfy specified +The \b Filter controls allow to automatically pick up entities, which satisfy specified threshold value(s). The numerical functor for each sub-shape that is compared with threshold value(s) is computed according to the shape's topological properties: -- length for edges and wires -- area for faces and shells -- volume for solids, compounds, compsolids +- length for edges and wires; +- area for faces and shells; +- volume for solids, compounds, compsolids. Filtering capabilities are not available for vertices. In order to filter out some entities: -- Activate one or two filtering controls by switching on corresponding check boxes; -- Select required threshold comparator type; the following choices are available: +- Activate one or two filtering controls by switching on the corresponding check boxes; +- Select the required threshold comparator type; the following choices are available: - Less Than or Equal or Less Than for the first comparator; - Greater Than or Equal or Greater Than for the second comparator; -- Enter required threshold value (values); +- Enter the required threshold value (values); - Press \b Apply button in the \b Filter group. -The entities which satisfy entered filtering parameters will be automatically highlighted +The entities, which satisfy the entered filtering parameters, will be automatically highlighted in the 3D viewer. \n TUI Command: geompy.CreateGroup(MainShape, From f312091eb5bf90096c0a8d4d0ed4be68f34fbd9b Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 26 May 2015 13:56:05 +0300 Subject: [PATCH 09/54] Remove redundant code --- src/EntityGUI/EntityGUI_FeatureDetectorDlg.cxx | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/EntityGUI/EntityGUI_FeatureDetectorDlg.cxx b/src/EntityGUI/EntityGUI_FeatureDetectorDlg.cxx index 8a35f1681..00b35eaec 100644 --- a/src/EntityGUI/EntityGUI_FeatureDetectorDlg.cxx +++ b/src/EntityGUI/EntityGUI_FeatureDetectorDlg.cxx @@ -400,7 +400,6 @@ void EntityGUI_FeatureDetectorDlg::SelectionIntoArgument() // TODO supprimer les lignes qui ne servent à rien le cas échéant SUIT_ViewWindow* theViewWindow = getDesktop()->activeWindow(); - std::map< std::string , std::vector >::iterator AISit; SOCC_Viewer* soccViewer = (SOCC_Viewer*)(theViewWindow->getViewManager()->getViewModel()); if (!myEditCurrentArgument->isEnabled()) @@ -434,17 +433,6 @@ void EntityGUI_FeatureDetectorDlg::SelectionIntoArgument() if ( myEditCurrentArgument == mySelectionGroup->LineEdit1 ) { myFace = aSelectedObject; - AISit = soccViewer->entry2aisobjects.find(myFaceEntry.toStdString()); - if (AISit == soccViewer->entry2aisobjects.end()) - return; - - Handle(AIS_InteractiveObject) myAIS = (*AISit).second[0]; - Handle(GEOM_AISShape) myAISShape; - if( myAIS->IsInstance( STANDARD_TYPE(GEOM_AISShape) ) ) { - myAISShape = Handle(GEOM_AISShape)::DownCast( myAIS ); - } - else - return ; SalomeApp_Study* study = dynamic_cast( SUIT_Session::session()->activeApplication()->activeStudy() ); if ( !study ) return; @@ -455,7 +443,7 @@ void EntityGUI_FeatureDetectorDlg::SelectionIntoArgument() PropMap propMap = study->getObjectProperties( vm->getGlobalId(), myFaceEntry ); QString theImgFileName = propMap.value( GEOM::propertyName( GEOM::Texture ) ).toString(); if ( theImgFileName.isEmpty() ) - return ; + return; // Setting the image caracteristics myDetector->SetPath( theImgFileName.toStdString() ); From 44ee08e8492cdceb03d6633b4c855936fc8b636f Mon Sep 17 00:00:00 2001 From: vsr Date: Wed, 27 May 2015 10:50:06 +0300 Subject: [PATCH 10/54] Fix error in the script which takes place when generating documentation in plugins --- doc/salome/gui/GEOM/collect_geom_methods.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/doc/salome/gui/GEOM/collect_geom_methods.py b/doc/salome/gui/GEOM/collect_geom_methods.py index 3639181c4..2f489aefb 100644 --- a/doc/salome/gui/GEOM/collect_geom_methods.py +++ b/doc/salome/gui/GEOM/collect_geom_methods.py @@ -117,16 +117,22 @@ if __name__ == "__main__": if len( args ) < 1: sys.exit("Plugin name is not specified") f = open(options.output, "w") - + + if len(args) > 1: + plugins_names = " ".join(args) + " plugins" + elif len(args) == 1: + plugins_names = args[0] + " plugin" + else: + plugins_names = "" output = [] if options.dummygeomhelp: output.append( "## @package geomBuilder" ) - output.append( "# Documentation of the methods dynamically added by the " + plugin_name + " Geometry plug-in to the geomBuilder class." ) + output.append( "# Documentation of the methods dynamically added by the " + plugins_names + " to the @b %geomBuilder class." ) # Add dummy Geometry help # This is supposed to be done when generating documentation for Geometry module plug-ins output.append( "# @note The documentation below does not provide complete description of class @b %geomBuilder" ) output.append( "# from @b geomBuilder package. This documentation provides only information about" ) - output.append( "# the methods dynamically added to the %geomBuilder class by the " + plugin_name + " plugin" ) + output.append( "# the methods dynamically added to the %geomBuilder class by the " + plugins_names + "." ) output.append( "# For more details on the %geomBuilder class, please refer to the SALOME %Geometry module" ) output.append( "# documentation." ) pass From 7c036f24ffc367e0d6d83240860a5c39591d25aa Mon Sep 17 00:00:00 2001 From: akl Date: Tue, 28 Apr 2015 12:21:22 +0400 Subject: [PATCH 11/54] 0022762: [EDF] Fast detection of face/face face/solid solid/solid interference - Part 2: introduce CheckSelfIntersectionsFast function --- doc/salome/examples/CMakeLists.txt | 1 + .../examples/check_self_intersections.py | 16 +- .../examples/check_self_intersections_fast.py | 21 + doc/salome/gui/GEOM/images/measures11.png | Bin 33219 -> 36082 bytes doc/salome/gui/GEOM/images/measures13.png | Bin 0 -> 36327 bytes .../GEOM/input/check_self_intersections.doc | 31 ++ .../tui_check_self_intersections_fast.doc | 6 + .../gui/GEOM/input/tui_measurement_tools.doc | 1 + .../gui/GEOM/input/tui_test_measures.doc | 5 +- idl/GEOM_Gen.idl | 15 + src/GEOMGUI/GEOM_msg_en.ts | 12 + src/GEOMGUI/GEOM_msg_fr.ts | 12 + src/GEOMGUI/GEOM_msg_ja.ts | 12 + src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx | 104 +++- src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx | 5 + src/GEOM_I/GEOM_IMeasureOperations_i.cc | 43 ++ src/GEOM_I/GEOM_IMeasureOperations_i.hh | 5 + src/GEOM_SWIG/GEOM_TestMeasures.py | 24 +- src/GEOM_SWIG/geomBuilder.py | 31 ++ .../MeasureGUI_CheckSelfIntersectionsDlg.cxx | 484 +++++++++++++----- .../MeasureGUI_CheckSelfIntersectionsDlg.h | 50 +- 21 files changed, 719 insertions(+), 159 deletions(-) create mode 100644 doc/salome/examples/check_self_intersections_fast.py create mode 100644 doc/salome/gui/GEOM/images/measures13.png create mode 100644 doc/salome/gui/GEOM/input/tui_check_self_intersections_fast.doc diff --git a/doc/salome/examples/CMakeLists.txt b/doc/salome/examples/CMakeLists.txt index a437b4078..e9dc70f96 100644 --- a/doc/salome/examples/CMakeLists.txt +++ b/doc/salome/examples/CMakeLists.txt @@ -56,6 +56,7 @@ SET(GOOD_TESTS center_of_mass.py check_compound_of_blocks.py check_self_intersections.py + check_self_intersections_fast.py check_shape.py complex_objs_ex01.py complex_objs_ex02.py diff --git a/doc/salome/examples/check_self_intersections.py b/doc/salome/examples/check_self_intersections.py index 8df91b9fe..f70a54540 100644 --- a/doc/salome/examples/check_self_intersections.py +++ b/doc/salome/examples/check_self_intersections.py @@ -7,9 +7,15 @@ from salome.geom import geomBuilder geompy = geomBuilder.New(salome.myStudy) # create a box -box = geompy.MakeBoxDXDYDZ(100,30,100) -IsValid = geompy.CheckSelfIntersections(box) -if IsValid == 0: - raise RuntimeError, "Box with self-intersections created" +box = geompy.MakeBoxDXDYDZ(100,100,100) +# create a cylinder +cylinder = geompy.MakeCylinderRH(100, 300) +# make a compound +compound = geompy.MakeCompound([box, cylinder]) + +# check self-intersection +IsValid = geompy.CheckSelfIntersections(compound) +if not IsValid: + print "Shape is self-intersected!" else: - print "\nBox is valid" + print "No self-intersection detected in a shape" diff --git a/doc/salome/examples/check_self_intersections_fast.py b/doc/salome/examples/check_self_intersections_fast.py new file mode 100644 index 000000000..83c8a741e --- /dev/null +++ b/doc/salome/examples/check_self_intersections_fast.py @@ -0,0 +1,21 @@ +# Detect Self-intersections fast + +import salome +salome.salome_init() +import GEOM +from salome.geom import geomBuilder +geompy = geomBuilder.New(salome.myStudy) + +# create a box +box = geompy.MakeBoxDXDYDZ(100,100,100) +# create a cylinder +cylinder = geompy.MakeCylinderRH(100, 300) +# make a compound +compound = geompy.MakeCompound([box, cylinder]) + +# check self-intersection +IsValid = geompy.CheckSelfIntersectionsFast(compound) +if not IsValid: + print "Shape is self-intersected!" +else: + print "No self-intersection detected in a shape" diff --git a/doc/salome/gui/GEOM/images/measures11.png b/doc/salome/gui/GEOM/images/measures11.png index 6ee44987416555bf22ca65b9ea84c5a5835cb1b6..562714d31227c690518d3a8011b2e264e248096d 100644 GIT binary patch literal 36082 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 C_0W9) literal 33219 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 K0<^<(Q; zXD$<0;u2}@q61sDWEI*F+*=fRlqnLQ-H$hmN-P$MBJ%p@_F{kFBi$sBXD; z+uHhq4iy}Eu#vceNvvH`LYIdZc9l~%!H^;VOM#BYM0t!y3K<}oNP6(-5jl}wB@v!# zO-)J>w7zn=Z5pd0{W(n~qhe&E2(IjrxiCOuT>7WVN(E;N3ERl?F8!4blI+VE>O(fa zY0ig9KL+KocpJeS!ZnU428n@{l?u_C#dQ==TZZCv^w-u=clpA3RMOJIf>q{5ByJYb z$G9B0KaHR#EIU|`nwglHNla5y*8^W3^(+SEO7xB*EMdYTFM;P0_|Iw`9z#b9_o=+R zJUpysn;Z8}1V_-#cKi9zBfHmIYC+x*X-hG&3Xj2s&zZOisq%pKlmk7zg+WJDV~VGG z3)xwl=r|8Okhog)bIEsP3xOnhO01}Uu?Dsz>r!8OL6g2~JAU#GtSWeCJ$a^iX=**+ zcAOHbr$uLus$od2AMA1nR*H8OCGm(X7lSpTpd- ze*56cJ7IVJApEzJYg6+H=a$jbzG7H1;rSjV`AA_#DBPuR==6_}ZQRJp&2CHwxHhIrg`8;agGPP`LzDKJ?^O;tNDF+%EMxTgunm8UOV-Ymg@TP33gRyY z%Icf#3$SPOmD9_~5B|P@)-{A`kIqoZbN2hYUq3#_A=Q(4MrB-q;MI&jt;7@{>eVwa zf>Q>(sX(IM2c4qil{E_VCq*Bcw{T}d0nz)wo_3&B_S;su>)B1t(VO{L{+e`_ak~Pe zjL5+Yv2hGW?vYdKr?bnld$#*={`Nh8JNGkdwYz1VZV66ZOlsAdLk6E$f`^gXk@dkV z2dgdz$u-TBy6qXsI!56)l5K08zt1#{rTA(D`s4iXoeS*{%5K~*e%#Jk0=-Xy=dT#X z&oPJC;aL;dcgggfW|;?=%z6)64qna9kS$$n%Nx0<)=_-v3-dulcuB|B*H#mBUH)_) z{$@%K^;Jhl2g&OT3#V8mQ`G4CE%lhvEV~+(-G!o&sa1m{}Qh} zZP9i~)l^H_yU|QaH{{@{kn9TCZ*Qpv7f2-1pEL5u)z$HRFRjnU-`rU-r$rf{x$XI3 zBOVkMFJShytj)WoyOoT3lHya|u9n?o)EpsV21Y0`wrjIDP$kG3h?uiw368w5JyUyN zkoE;Cp7iG5lxIXVIZ!zX{F{jSSMl@j6%g?%vg$&DpzamjE0=8K<<;d}6#{lK**c){ z=>J-5{i{y<+djm$?dG$l{o;nc42-I)2U&}L)U&-CEH&w{XD>nIl?vb-= ZT>HvOx3_pmrr^p+XB5uMC!a8I`wyB{j7tCj diff --git a/doc/salome/gui/GEOM/images/measures13.png b/doc/salome/gui/GEOM/images/measures13.png new file mode 100644 index 0000000000000000000000000000000000000000..6e9deb5663330caa773d7354ecb713482f5ccb2c GIT binary patch literal 36327 zcmbrm1yo#J+AdfLAtAWCySoKVaCg_>?(QKt1h?Ss?hXm=?hb{!yUa;{f6sJ(-Lvk! zGqq|}7Kc+D+xvYV+X<1A5ru=sh6aH^aN=S@3Lwy%SPDpCu|@P zAxK>4i;`>V(Ta-}%I+)ZY*(NYisXnFS?;r)?-7xp+%h-}=Fs$Us#r~UgU0-@)QOmy zvwgI1WK3Z(^2DBQ2&-V-Q(??Cm~ZTr<0!U}bPeAh;wB z@v7;4p$D$EhsoyU*3dr+ZKb@0LaPGVXQR3S#5yN(IO$W3hOaXUm zzc=~5S{0v3e}1N9j=Rn~?2xl6%(@)rvD>@bkeQ&KS39T5>A7CJCnv1S@#CY!Q))70_K8`ZGanT4qr3P% zj31bWk9DW(eht;uJRT&aU$aD)*eo3TBT&Al#}(0CnO4>Gy-@7T;iIALi7DtE$P^Lu=oVa#E zhinSl1_+vnJG@}8N*Q2jQ?hTGKyoY6G_D7Lz@1}zD{TF7S1G(840`MG6cYH|m&uW)a1KfV*g0-MPv z7a96;6-~gRsa`l1+d(+P6qO4XRY8I;lbyt9N!UhVhKsBy+J0QQdj77Nw8z)|hNwU5 z0KYn@gSbad=5Wo%L8&+E@_nCx0=0ru43x6$K6jD@FR-VZz+MnZ~s+liEP>yFkE|Bj z@!2j_mvu*f$Nf=w1FzTeI^R9o4Bw5T6WVs{ZHD{2#?1rw-6cYXMN!cx?&hAEMP5;U z%wsw8&EoSW_3VSV?>!n@Is1-L>4RWHO$W{a*RM&;u1dw*4D#hy6r$X`e6AtYT;+?l zP3nZYtdm#B#;XQaYx51@GPd+*FB>cRZkT6ZE#e7wo_L&G4=$f@#&iw~OGa++j#ifx z6s5PNu~^9Wt@VV%BYC}2!vwuQO%)&rY72kbSS9#)`@%Rg@j%~i^)2sXpkBerYm)6L z0@dROIj!uDSI0nJV1TV{k=1ih_30}-Ai>Ed)CP2W*B1t1uvD7J#C_07M&N~m`GCW5 zZGyRUbz@uUa%59(maUYpbBReKWkEk!UgD~%Lt(lEA<#do_UeSCSSutcofkMF3{|Ai zza-$NOeqmfQ9iotQQunc-NU(77&~W+o8hxH8BmI$PlGwdS}%o@p7v_}kUq6kkvj%w zJCR>3k|xz_=efGErkO|QKVHQh*>QuHdiES=WZ>!f$QU;uA=E@2fXnOU4}9J)&0u-R zB-UW7L|l^SsWFhWwN@8;-!i5Y(loJd(4OD za{QaM;*C5-j2&)<%UpK$y;SGDFjGG1b190FBdVZJR_hyh1an)c(E~acQ|Ss z4IGEKwBsBUODk*NEGgsmb#S}BJayqB2VS$WcxtQUm1pC!7_iC`-o5PQjnDgc4kjBJ zcp(Wm=fAHfe*g}Z-$&l9-G*_%D;6TO$mn!elUE}58Q&vy zCe+kjxEc>XbU;hB$zT+)^CI?P-Jn)yOqJiU#e6uE`0eW4bPeY+j5@=JlNoRx+jVfX@Tv*{hz;Jr zjb$+GFkNRiX{BFqAc>_woKMDt(yX)RI~3kKQGB%K5rU$_+pn`5WZdiusPcPMs=;ZX z$m^&mGO%mhtw~QgG*{o7KoscSPfsiQvidlSaS;ODqfF}`l@{{S6!dAoDc~(GLxokL zwds?~nO6x8=Mu^(^0RKgyLEYqk=WF@g5tuRhq;+kSvvWQl4wb5y)VPB(_OTnBTipL z?A_&hG^=Wl*Wo#`T>?Ivb#|jx`c<#vH?rTBlJ*j7Ua*G*WK)98vn@KZi<4IdZfVSM z)NoIFg2wjWb9FbT4tY9rG{}7e8`WLUz=c0_?>WJF`mTHH$cqhE9G?(>o)}1nZ;oc< z!2+W?)b}e+ZXI527w^@W>vni+eHEw4N#T{Bqbx20?l^Yq{exU>=&D-MDJt zHl%@5K-{NQ0P0h4EwTbRjoVedl#jC7+`QwX@XImAy`!JWV>_0K&=h5f)!FG#CeEH# zNHW=CQ(4GM3UfZF4=A2L>ezG>S&#(6{CNF7EE4~c@pdu7-r znwT9G;=lFE^J~&OS^!t$6Sl9|epfI~$Z!P=>6+T3E z?*qEZtk$r%-Q@yK_RI|0tNFIRLDi-C1AoaADF)H>-16S`BXsuo>hQXgdOWDl>yh!M zz!17(^3bBFqon+iW*P^}C&1i1>ajfg&tJX%pvd!HB>bADw6y7Gyo2J_rQ+GWd~j`m zkPM3vPYId}KSqeZ*ny|?5LYo$f!k+wgZrf?;*}kKYEJVy^Bvq~7KJGi8VkZ|XyWL1 zP+9B*mJ8U24w|mn7)@SB`&O^mAdp8O0$Sz!%lSv*eNgEi`={9Q}p}#ZP+FHD4MkCzaeFEZlyUoC2aY$RUb)9cs!d%lNueCL?Tn_;sraEJB0cL~J%YGlu{dwjaU zpiH^7?%ReDdDaT_pa6WUmkl3{q{E2=&hP^CAm+nQK4sN-cwOTw%bo2zfk{4*!due* zQAOnmmE?irloXHL3^25CwMYU1K0%9p!)NMt3m}@opP#eJL$7K+MsGs*>xw`>G`RBMbU1ISs%#&lgfrnaz&6ddH(Q=TB4gRbudX)zHQw+r*;ucIi8! zznmh>=~zs4|5{8~@yi3agYEnz1}VKGP}@1mh(_`Qss@^SCLmo)-O+Ol#K zO(ORD-#(&`Kk$|d;?!Gc?!U;GeG(`v46U=XAMeZw$>tC_yZg?ztFQy-#LH>Y`uST2 zUBwI8@p)S-vHpI-kV`_u*@M-_R_{)NDC8-Lcbme{h6c_7a)Z!((w@n717EOWR@8nV zSNBACT8J;>hkc8pscEIlp^~tlrQwP}bWhs~W=_Wml4g>k4^KDG)4ll#q5-D~y%bgR z%d5Q)ZUiStWj9(rj4Mlat8#OTz4<@^Pod8z_OI8H(BvB2?anSr%}?lqJWart1)!|6 zc3XpG=_w~hkb?2?D9x?C#30h2#~`if*X4cRRvj_II6dH{>x;PfLE5-4H8oCUr!}2_&p%1V}K94tbEiN|6Ka*+09=;@~bi5?kf*-b30xow) zq9;iW754f>sc<$BCrQlaQs%~BVC-w~SJOTjJh)u8`@FPXYt`$2h@U9<;KuNrU`sAf zJngaHz*kNKYEH*x#)trqrSrn1u?wq;il#|uS8sVpOG_6a6ue4G!%51@Rw(N!Df!2d zFDyjzQ>kD<1x4Y9{HU$1?G49ye(t>YxW$h$lEWI{5Cfq`0Dmn|4D;T-=xDdih8$Al zdhh36a36dcufwMCpcQUk5Box;UQJfk7w6fwdF_c3)e4g;^Cgiw?`IMJtlC-}mr3gw zs;%oo4hd*kXb6bs>S}xOC7}m*C-o?(tmvHYv9T2-{_o!YK23}vmwGykZgFyQ!oo76 zAN89ndsLs)0FB2lrr5{}iS%|oeeYBW$eJPtbC%}{rE~A5obGsQ>gZHCSqvXl?COX& zpAnLeo2Z{XL}EGN}cNNuWOF&hhcUw!QFB-c_sN05JrFmw!}A z%1}ZX6A=;0W+Xu`qm*UrQo~fat}JQn0K^CQ#+3Bzav3X})#K^ft&+s)A|-#h>FVHL znbDmgE2IH)D#}Lj(a~8~{bY2<)r3d__$StRd8eyw93}N$o}BQxH`^g+vXK{5aLks7Z(?o_^RsCq%bi};JU)J55~v#58}gSXJJW5x(K}0 zcJ|S}fjOna65?Eae`k{TbEb-*hmqAEm&KLDyq_5#{|r@^_ESY-?BT&jo0HqqRM-9C znZ<;myDx*&iCM=I1wTWU_<812O{lnvLblusTf89+DRS>F%pzPxS)67O#KUbYep7Cq zHae+5u#^fmAJ5)m9nL*u01EjJs}&ZJPRO_W7DQ$UZ!)#JGkCFL6H86P6eiIF^sHyqm;_-MKr@Ok~x+>S#GaDPdEZJMCtIbcAD|tO`hd2`)dGKW=#=0vgBf#l8 zFXZICFc_ml18%Hhv@E<@LNhByMNtfkFE-3^4||Dfjx|JE3qmE}G}3a|!#4YdeG2rgv@!R|^RV z34TEljm=GttFq{x8v+H=)*dPpA)e(9J(g?5#ra(B!`*say{&G~#^7EjsI2~eTe9ky zNZIwujhvBTX&*JL>wO5wcXw`XA8MCa0`)F;Mm{E?VqNif_ULMzG;BjnV7vqb2zwnJ2Ty6fjR23*>tJCa%#}UM4+6v9sIv3B7EQBu3yV>P z7$+RXTisx@tQr9U@+Xr`*G;-Ky|o);Qc&8L1RfNms?-rZmvv~~yQ6d0Rt}p>-S%NP zeEjK^Di9%@rw!5*cxPlOYs$Dx`!c7wxw(?jeJS4>_9Lij{U^*52`48dXXEvRide8E zN;|}O0I>1@Q?vMw&Qf4vMDKJx6eu$4=C*WraDXVVoS(nBsX*UQ)B=7Bx}xRXqvB9H zfTMOAN#h0|9(dBx#WzVybJ*nad0*uEbhLwe!^xxFRbn8ufAnFrR&2|O1xpYqD)*x@ zH`UiS)x+l~D6>u97Z`q4~EvAzZ9yu?_3{4Fth(EJSl^`mSXQVUA+i~ZM z%+WK>w9pe{nzE`MFF3F$_PUxT`drn|@4!3kuB4(Op0lr}uKuTT`=py#TCQ(ylD45) zjd>5w*)XhRSXf&d8ydRqj{0qF9TE|NA>aC@X;(ZvxU;b-qoJWSiNZ9miXIW2n$LIe zQne|nb@d?$KnX$#a$*7KeP&SkG+vj6ist-1R#D*NZPjGr{urs8qy4DX{yr90^Lsr# z#gGO*K0c@{VBD>?WbAM6lNZJJj!Z3zx?~C&ws)0AK7VFUiPe=8BaYTcP8k`NqN5!i zFdXbE6`dJA(Cd0TGrivZ+1INZztegr%~LD&p+5Q5j(_w!?8bE>Y%2#)+*B;sW5e2zRsf%D-9EFkLVW7_zDzU*h)a;Hqge+A0en&nb`uOqV^TV~Gipt4S zgN=Z|_bc8lBdWulA!=p;F+xPmH@lbb-o6QnT=CKzF!vvGXos>N(yFU-BH&Yc2MPJH z`y)I&J(ZWPuI^fWR{E+r`DLUgIgv|fzOmuFX`wFhAOY`7*L=U6pdcQRlDvG9El`L9 z+!R@k5A(>rAK1(Y?)Y$;4XB4Id3 zmccg6e5^G{0<`q64`D7cDi7MV5}A+v3=Ybwnrdod16nF7SH*)av$H=`wr6Hw-&h+P zbTKk9$;-ptKi}Tg(dGj)!Fk!)U+$tV#n)HRo3t09_~g)*7*6Cjeh%F?TL+EZqBNfvev|~$e@_?(A2Mk)PuG1L4vyKOIPn83(=gG~#IMYa-%=EUW4hyDHinc3Ok zwtnG4qbgX~ZrolREG%BHo7Q$;hxK)N=m6$^yUgflB0v{qpO~f<6;4`~Tl;EiYHDEu z%<6Jz7hG!E4g6~R?Ln0=m2xdABZMzdW@Z~Rxd^J%Yg&{(UPsCz8hX}Nf(}+N!sE+g zn{0=LX4eH+*KFfIH!bsW;2TCgk+u?=Oj+qz6v10thFYn>L{U@w2^=EWDomY`T6sDp zS)<-ETwYl|iOWgh%ga)AHBwhl9VeVKE@P!nhqo8q@W{G1Q~>$1Ah~q%)eu9+{K5hi z71hGh5&^%r=Vo`vYtwWX@Tx^0SW|$)_hi( zMSdYN7!{~{^cSr(oik3h1_oYBTTa`9@d-O3CMM?%*pvGSf>v}?+dcXDJGHzXt8K%1oZPR!Gc}7!N@%F42AGt_>HIzVbH!uvdEJ#XHB-{kq;u)0JfH-i zx)}L2yWaF-V+wEzl;-D?FyPxl=FxjEo(L*EKaX>ugp;@2lGFTdplwIBZ%3IKnxdmQ zJb!t9G-b8oN|Tq1(pA;8Ff!WN*dQ+Y7$RhkeI%Bruz*`%S2uDGli04y`6{R$ke6p9 z4Odpro*__<4&}IwL$OCsP!)uD#ipDHIj`Sv@p31py7r@lGS+>GX2Nt(8-;z(Z0q%y z00V=<<8d`UURhb0zfjIYl#$su-cB`u3Q+f14eFfUmZ= zIANsS)SxE6npoz|G3ma?`i}hxG1WJ9f1(y~X=y zq0W67I7rYL8F#epV)BrEG$>FiQ$B=iEv{}%it;l2q1Qi zqyJlE@~@*skChrZ2DY8C1qkdL*xXLZmVAK6J=f6HVB`d$hnn#se6*6b-{OB@Ga1da@?-w@$Xp)kcrs?;Q{Yh7w;fF;Sz^ zy=l%b+$1H#wrNy|{B3ao^%;C_5HyPF~#pBCm1& zXW5c7;)-?T0-N{KPyW|_9!FDM$152<>7~^+a3sNMyH{dz^5O`NcnerxAABPLjQ|?I zbXte@`WM=S!T{V>8FCsT|K#N42m<~p^XrG9#8KYjG$Cr2kIBmvC8rsgI< zenmlMCVIKkgYDv@ze-{eWP-iCx!JOB5^7MbczQWfAMFWCWFauFtF48yh`>gZB9BE9 zSo7qKl_Gz9cwl8?Bl7PK6#ce)56B=~+f*Dvi^w}vR7y%p0tK=QRV?U4LQ~mfWIA6N z_n?U23!;1Uk(}TO78BFGUxyc9&d(`i(tcoAjT+Y&!HNqCLJ*NA-|dX(=H};fIUnuy z2cNN+jKU02p+cX3@7L`lkLeU7#=-)PvjulS{>4(5^Xa}9he8KU1tUVk!-s|~^%>XD z(3I?q!Y$Rf@C!io*~v2aprC*QV0O2+S_wzdlfGY%87hqaw~3FsIyBzCE=qC z)Ei0=mP%n~VKi0J)^5vKiz1WE$>l)8!3SmTc0t3~m+d(V2UO(F0n-y(CKCiollUk6 z?`rV*Ux+#XI@|v@l%E~VBYJ%TMmW%(FV|J&jx&|*4)J6{#p(D7{5#Nidu=T$>19{) zQr@pW>@__-eFYB+l&5jSUN{X>W89rU37uvC`0CpQNT*H*zGA2Vg|5FpCGzxT+<;Onfu zkxZa1DJ+cRqyNLMUt-Cnn?3KDQ$}XT$2r|DNCWkZjEsPd%#4hgQ~NB&!*^#Jex@aQ zU4caY05YS<)7%J~Dv-TBUDK77wb>m_%eEqe^VL%W0CjmeePka{>MBD*LekS$Bk;Hp z1@u!GlZFRkDGvAduMcJp=c^3LI!TC&%FEN)EE1~zyv~1MvHX-;);gf8BStxKAP|B>=cc}SJ%`W zOJWhN9k@Q6LlRIJMHg=Kdc4`6Dgc-RfSFLOXpDlVr>EoMP?1AW@$u7BQ&ZE^z3(rK z{%BL`&5lJOA>!)l3n3^J==54@+S)7Zt!HPpuwARIZkIR5n$Q8r`1tfxJmP`ycwFvR zrs}g8-_oV59kec8pLE*rfH{XG091QJUQfr(?upg<=MZGRj8~xkrEuIQA=Hefev(B6 zI!481dh~!{pi>4%g+sp~a|9UnkS_qT$qNtnQ>uvGE-=O;307=yV$NigaQp5(+hbyo z1NBbVI&`b_dw>U*!Q+;lmG#@WCO{e%7M7Zt8WE_&NV_qe7@G|dVs(p)8gz7YxP9WJ zF{YYSf}VG0zvt&MiCE32DRKKu0KrqQ^Br^maeaud?-v=Fi0Eh}fx_Zq2}wywb@e9Y z)Q5)$*$h55Ha20X_{7B9L`p2U+mJ~6KM zS}lG6&OuJJk&>3q$;r`ea}NMFMnu4$zwJ8*W;rm|B6X;MYau;h;iD2nG=m~?yuaA) z3B%BBv?ZdX6jMOKj}#?-z6KW-7OvZJPJ)S|#XMj5=TOK3KKwE%Qe;jH4IP}NwW|o`uJZ?@BbqKmDqe(=|0fyHVgpik)$Hc@0 zOft+s=~Pa;u0Xi!>uX?of%_uYYRzJ`ROAZt@`MKwh46pdEl*BP0wpGhz}xldjwu4H zp8|`+ZaI}N4O~Jb0l%}8Q(0LV8a&aF?N)y@Fd7YO0KVeU6N(0izWz#(?NVt@6vZ_) zQ*l&8-4?K233OpU*{zJfju!%ii@$?NGNJww%g4~L5m|kpkHU8TY{GaapTE@dHT@fK zHi|{lzx_Vk9?qQt_vi8UR20f;zS38UTvJmM*f<6dOfIg6DOG9H=|Xu&uC^5-M%b{> z(2JWJd@e^*DJj@MJ^hsK-rk+vU4Yz#6Y%rV(~k}gN&p&LNgB5c^t-nf78dXQCZ?xR z0rcB9^X9W}|1p>997-F2=k_+XJknswCx}TmE~01~{I1n9*0A3YLNj9sWPmHKb{j-M z!QXAPApVIs<=1P3E#C9e(e;dumbXB>0o9)V@@<=iZEkf}Tpt$ZLB9ch{HsMU`t|ZJ zuV`;K(g6+YZTbI+DPcIGH4FO?;y;xJ#0b|VoryPUk8}}YuJPSBRh-0hK;L90vnoC~ ztpk3JG5`}1-pu{49FBi&iWdV~mh6wa;hNw5`fm2QDLGw_dc!prEbDEl0JW_?WWF<^ z({33M=)amU;72lel++7OVcjs_tZ(CeHkl850ebk}=Wga8(pz#o?Zdz9kt0(jJhH?U zkf-lfRMWiWO`$wWaS|K1i}lcGI{`{fUUBFr_bVaxAdFta-A~upO759gk|a;H527NTn*ssR_j)7JLMF6kwV-+h3erz^eh)g|IN0K;hpk z4kQ5lmp|L^_0BloLN14|XUf`}O!Cg|NK!}6FI1pwx&1US+RZEoss zEbZ*<4FBLh0g^DP6&Pjp|7pRX37B>Tjsyn2Ur@i*cM%2@sq~)W@c&^0^0ihfvm^!v z1~@o}fW?4?g|*Uh`?;~Ov5@rBy@HnI@T?Wk*$-!*hj-6Ub5~kp95=@J(~Z?+_BFpgKZHXGnwfE&v zT1aR#+ksVdU`|g~QpCkE2#k#zu$zzTJMBC@hRe^veNXqIJ6VE{**Pu}2s%gTDAv$a zZ%hmg)9;Q8V~{@*87{TBJe_wfHJmCaDz>)&`=WDUa5~d4-g2krN>Z6Jk3`QehCIvVI z6&u;L!?F8dd@hWTo}uC0fTGC@n`4SqfZqHJO$Wb6g2Vad_Hd9o&@3kXFj{&H)$7P4 z(XlZ1P-aBJp~+(hpt5Y*)5XbSy}Y~tP8Li@CCR8Df`o&~W3^v1O(okzG^w&zJ79%z z|L}nO$=>tvW+Xd6Gy)f}jVzR7{iFL0Lrp*a%^eCr+&sT0oz(3Z9;PN&7Y`B0syztp z18X9#I$yTm9eDgt077c=qG zaMES9|B88-I6_Ef#p{?d;|4--zi#%kBkNCv@y<2353)#6qCKXz@ z_3Ru>ffPOD;Ghdo_ok)_;@1{pn#YOn_phFoj(-_C5FZdc+?&Hr0{*kRi$cMjpD)(j zf+G6>V~NT7Dfi*weRlPk1iHZ9YTJiJ*5vSTw)5H1Q58i+@aT$%KFQVX?eqO^8DKO5 zy?ScLYH}{F54^#7vcGMkuit9B(VCiyahy)~@OW>%g5I^kYR?(2S>Jp2h=5d1QnmR3 z0ng6K;Wwj{gtYkcyLWe1z&<;+janx+Kj&2h8&*^}BMJ)EG%MFzvfg+X6}f0wHAKW9 zSJL`Goe(EdI)!0$FD07BOwKlHw%v;m3dxp3QQrk&TIko?Zmv;26W* z&FjuudpvFA9%#?baDW8~X=nl0`PTEXAhS|TT)ap#P=#|rJyNAiM_0LrmWF1n_LF;e zu-*zD5@@9YhZ!TKD~Z!?uwkvX9rEZBrOj%pz@^&M?q@`Oz0c>fpH;6+<8v@DDYyGx zZ!`C}Y*qbR3l)oG@l70`8?_lo4Lb{5vSsp4=Buu!9^b4xyd4V#{r`wnG;er>t;3Ms z$ggK)3(CGgW)SpiWlkZPSuFT;ZO`ulH9UIw|K7Zff$H61tK;R>hWnVxYw<8)&=E4C zWzXLZVNbNyWe9weW}S2O1pLIkm^E)tY<2$t9}iahOg}lP5cLEfOXT27PkcH|)}Hzg zf^Lrs(;twQw&Dxnu^rz8;I(lyTU-pN#rr<+d4W{gC->#yA3sVH(9^F5p$1qG-UdMQ zX=R4hdJG5X{RC(F(nf5Y>oOD<7GCWe$YzNx^KW~+`+y3M3moLTGsU5~7;N>N|WL5NoodU$ek(vy6<(Q!l&r<@av`4(sJXfbU4|!#>ta zccXtFi;R00m!aF}HWXpdLCyv(MIobWGP9&T)-Al`xK#wRAR5`Ls-)ztzvKRJWhN&V z6%i4Um9+uzRDdpVIZ5+F4oA{(HyP2hr|_Cj`e$oqYnSyf|k#iqlGH(--vZCFCO zg~qc5I6YB{+m9#(sHo^jWZet;0A2bH83u$$T3aC!Xw_BZ@*2na zWLemM{0G(=p?@G80bRwk`7#$Q!+dPaskoVf3O7F^)bw^kSi#tKb# z)RGVP_V?{MaoJP4b}#u)ESY$Dc}Yoy?oHyi&R9UQ{nwFj( zz1_;%dUUuEe6rK*e(gSC{$F)kcFTE7Q`4w4CkAKLD?l<)FJ1g+T4o!KWsg~(LCFpq z2l6c$`v+x}Y8~DdZO!xGA8f347E1AIv#<_|CdG0YX9I{4k2iDy0v{1xcT>dS;o;}XwKeO^(c&e%&Nq7irN-xBpJGD+Jxp0cj=6DIv4#-JKOSPJiiE4qZ_>s53M!+-V@w}6BU&;~;iol2SsedJIXd$Mh z9S#eV#KnCGMF-MB8k#KrHU%GWq z0y4cV2d}Vp8g+%-mj=@m3&+|zJHCQYbw9A0m2^mcpoF$Ii*(My+L)}evaqP;(rkSL z5R3rOY>1Hgj8=jmJ!}^(E$wQDkByZT9W9U3!SpX*hzhNyi>rObKNw^@UpnRC=9p%g zh(bD9C`%4eAPj>cUykzk@84SVs`F2P&Zi6v${#;!tEzt6X-V+w17lMU6CD+GdVW3_ zu^BMqGJIZ&a&r6-7n_|dJb~o~7LbSn_QP83?R)@gS_6oX=|(h3-^$90#tf+*DRUCB zhQQxsXd-`CPri_=Is9Lx`Z4iw!OtHliK|4#xwsaM$!j@I9j?OhCMA4Oq;PdwL0#(mwd2R?dfLH}+u0MHmhg0<399z(m# zhDW^6?$^-N7b4MzGe}Au{tX$uqykR-=H^Y+!qMPhag#&W&CyCEBK9V@&gAqBeq>_o zrT+4r`1LiMkkQ>&;V&V)dVtP!7nMPcc*bT%4y8CTGXIK+uy#**}sF z0a-3IBI0H3^+i=#84!;+tQJ{0I2wF`N)I4Xz#|0g*%9LkwJLo;0AVJN0Q40O4h}$_ z@#>Ev!VDBY5ET~Q-Wf^ZjOgp>5#P50_5xnC=q122p{ABd0D-<(CrN5+^D>>cmY0ua z_aMpm@wTVj@`j7FxNe}@9f-;)D?8a;kB)j*8(&LI)c-euz4ku?IaC6aguljyxIgPK z`O%Zy)Cl{63Z}}mQr&rdJjK@vF-m-==lk;%iZnDdSh1z0!$b9QWuI;k{C+n&A8P=r zXsQMS;dJRUpke zv&(8n{gc*yGCnRDJK-~7)T9t_YlQtnrdGaObFL&b&Et-ChbXo`=U>x(U3Va(dZUMF ztgp}PZ7JuY$!6fS{hmE&#Q4&+75`_G_x*MvJ!W1|sU^ak)mW%pfkFn)=wA86m$}%B z!-7&Nz43h#(LydxRKWTq_D@bp0mREVgK+D6qjX*m=Q#xE?(YT5-^#y%yN#U08L8vV z4GgRd4Cp3>+}*!-MKNF-(vJ&odBl+xvHVk4l8G>Q)5K}}wSvu$zG9Wo!MB|7HjFLC zodh4Aj!z8x~U#q`^og0iQh&<+yHy*J`7i<|Kiwi;L>dk)xUqNidFF#F5Lu z#t5%YsVZI0KN#wl9by!ND?IQ2YYY~_vmUBh;4drfB;u_jMI#CtCFUQz)fs!q$6;nh z6^#^TSc==mi~j88uvXwV49SHTUC*^|=97s73<*|tdjLKd7V&^fiq1RIMh1A9Iv}Tx|?r01pcWU?@J-)DYZd zM42HF7>ieQcs}`U3z&ajr~0tGN4Y+#!ti8!%MSorOy|lmIE$7Ls35iriuNC)48MqCxKuJ?5lp+W2YzKJdcA!f({n6|t+I zhsP45hiQ>91`3GeTgZgy4Ov5Fy%%Shq77dw;#=4oi*M6gdn`7~rD-xfvjt zqn?nb4+H4fygWP?7Z=T}?q@atRttMBU{u|MgS{FW1d{9j6)$XpBMJS>btO@O)3o|e zQO9b@_P^*a)b!NiGVQ1sI5kd7@DuZk&NTHX`_T>IxmFF6b264uRxQuNT8*}P6WPK_ z)K0+X?pQ{mQPI4BsAwOX#jK;*UM3uF-=Pu7nnAftYeq?N^1@Vt)U0$N(A209WZYs^m=7$Q~&W5AYN zT}{`bztxpqbOcTbizIQf?5d7L4EmzRAAHy1a#~tiiYTC>qC&vuiTF}UN+%2zV)Zsw z;Pzb*Jb^`r0>xhUa6BN`e17$YB1%T5qdI@<_eB&6VEeS_l9paoGk^75>ydx-TuRi? zxG&;>;P6UO2Uv21{);l+GxeHPY5kZ@an=D768jPgQ5iIP#l-Z{{nbkDDC6OV9YO8Y z)d%zEC>PibilgXC3;bBxFRK)e&Z9GEDM)zw8t#6O8 zAFpn(7MG`6t&gdzp2N(S%I0MZe`rbk85}VxGR1IV|(0o(^9+C@v?;`kc~n3ptAte$MC}j8+$~7Y?m>YUfwI)dMMDHYd6}1N`PBM zdOcm-DVqBq60Od%2UKEb=dz9n7(R$@-mB{AR%hNGAjLA*7}fN-fCS&qZT;6OU|;uV z9Nmt0Iqdmv+5rJ{!SIK zhk=+=;USN`8shYAp2*OLFYak{n%>qaP5!ZSfPH**ILBeWprERX;U+xeF#ZpGF)7KH z#{p^Q zkhJgp()y_z23X}nqz6HmwigR2JcUlg?rcNBt1g$Wy2pRs)cjW;FlJ5y7Ea99m=xri zd+5vlMm|Zc^B)1eXe7_i33qdKOW^&|dD`hPV=-s_ zE)sKh+@>%09zf13rR{ygmnIE;-}Db3+0vNx;Grve;kkp-Is1` zEVqdL$)!?b9Lcbry%d(I)4_c{Fxc$w>x6TDAAFFGCDg(J89rF;;R9BH|u{3~T~DL~IFnJb-}oo#ob5!PAxZatyx z@Y>JfuyGunhw|5o2vR*RkB#AL{Y2~e%7yW9LheJIqw+oA|6!<6tFtm`UTd_YsR(en zJsHW(4MSk535d4&TM~$0)bn50O(YdI{o68)iFjySY}?%vUjOmuM=TMMz=cTsxw*OB zo%V~%You8-G+Ax!=WB~ZFgQ}k=5>xKzjE>68V4zGa?*NPyhS`eYOZ39QbYPkgwXIG z`aWfdzqm%lW_HZhmZV)3lV-y)V#|K6<4cIWeY(2`LY7=yTU*c;&!gg>%l*QmE{D#0 z16RKQx26X~T7Q43V192k$HB>8zrF$MXaKIV zi-GFN>#@^z^%#yDQBo4t+}vH0Rnd{|t2h7c!8P)Yk%oAXM zXsXRjsDJcX$E!XrUo8Xg^Gi|<#wJ)cl?#iZbgHERPM5IJk!rwh{Bs78&g=6jw2Xm) zTxRV@-8|B|dNI<{nVPmdOJXlC-u=V8tSnzdA_M`a_G09sMd-W zBW#!5^3>2;cem?Cr`xAb3_=JjOt3Jx2OYfRvqM8&qxCKTHw-_d^4(-kH04n^bLIKZ zr61Wr6bkG}^3sFub(79h;`>jEUorEAbCBGkdW!QVYB#<~X0fr`TNq6_RE+yvIRO?w z-X5%n3C5{zMDOXVZmOT4E~y*W<2MjL!zrjra<2Tjs;9s z`8*5x{{5e9M%NTx7o#kK3$Vh-z#vD3W{DbKJlOm{mWR9?>c{3vlad;>X_&R_FCIVT zTs!P#B%Oo$&V!N=0G(!_M01?3`4E~{MJ>ugxPgY+ldMgrrN$Uo57K5jp|GC@xcjx- z*Uly_c9#ilX=MQcp9CoRJJy$8Q+ys(s&fZzy9%^Y#W?96+Io8bulC+LDy#3^7sWsj zknZm8kP?uVMnDiLK~j*EE|mu9k`@pU5Req4zDjq4ba!{deek#Ux%=#~_dRFa^T++? zuEB7i!uzgwt-0oWo=?r@W*mmO>DahLo#%>4N3n^CFOL0@M8~p~#JbXsy-CpnTofim zrh|8s&z6?re51|AlxQ}y1OJ*Gt6TJz*Q@|y2j18CphD>pxy``R3KosOqqCF&DIZ_C zO?}EZSei~TYttaQ z?=Ip!U%#$sH9@eWu%n_ONJ~vfa(Gk&0W(>B&EUcI^J~DAGSNR`f zB_-(JzUD+={8=$wnJVVpUFV4eMesl#Se{`ut$X~pEO1!%8n5^sAi8)DLGByT0Z7#V zn7vu|DeN$6S@~d!DK_n0XdgDLxmORoJp@+A@eSvFp;NLkrVIu}g=tvf$B4H(lg&2SJp^ z_Qs{jdsFYIJ`&+~_=R_-@>E+pHqkBT+c#agAgLUk)6)m(YE7MQ$D^fXw?BSFlSKyV z&im|O^aJ8_klxs)n=-9IOlne9L=6Ss<>J@;d@;|nWbb#|ABjqJTs|x;e1X*yL@+XM z^~bwy_ZAXz)fw7~C23x{jRstZU3(B$*rvaKFDLC9X&afp{?f=|M2gx3c{TE#@@-iE zC6BkwDk}xf&+ZKkal5ivi5YAUm~}@oX;{C~%LzN*nncnQ835aX{f0W_KO`ho_wLc- zEz)J2`^3kaNs1`+llK!vJ|PB8-RFUWl~?S4NJN{Vm+<-UVSQcO%83jF zzvY1~FE}_DEckKwUS6VLf14KacYdX>gwtg6e_TQ_U*u! zvb*-Wm&Rf1=;&lm+-U0XWl+p{i&}z_-gLYymntI#`3@K~k6R;uB_wEDJsj`qYU;Cl zSsl4CQRNP#(+}$`&*RA-90p4jBxvy+N^){+OiTb<+BrC^j*sXIG{S30(dx4Ev$5%I zRJ_5{A7|@j68^QUT-TPauv~dB3i!bFRg#DHYkqXMZ`Id)I~gv}fSHI@`=>_}^MeOt zK1kYxGQaIesRr|%r-^t>C+gEcw?~9u!TI*=V*o}eAFpFz7Ou(R&JJBgh3D3EkD3}a zj-TmLZD4oM2>AMLIuQ1H_v81Wp^j3GC3FhcmZqi&aZYJcYS<4r_zt(qEC%p>+1!o` z74>|a_Lta-4}&Hj|0zh1%ra;Ajesd3Kn;to_kcwGPj4|vJ)dD~TIBS^ME}(RNhQSs zll$~+n}z=VZW@EZL_B6W*;CSl+PuuvQGY54-z{r;F<86+dx;MwFC_*LH>yKOdV4mykE3 zt}ZbjY#fEiGqm#L{w;M<>@uTf(fb_c0JoNGjD6f{|{s``ibR^$3&*l!F11a! zsv_slT|GREqMVlw-R0Pim#*|KhyAnYys<`6$SLgwS=KMtM~bkqqXNBOTU!3$GG}m^ z9R^86S(&?DwYGBdO5u?FaznsHao4>Qa>hS2 z%$8Zdd48B%GnH5wO73ImVj)+@8r#;@rL#64K%=YfBkX;J(cDZHjB-us#K_u8hyUfE z!2Hk`g^mTyIH&)(iqf7hEGWpXIl86R-ErAo5H!^R(aFi&mPgLW>6!&)EbU@@r;kXN z_fKmyUkFJt03_Ls6CmM^x!i7eIA@2ALF>KyLwBAI4&7Ll7-qDfNKH<6fXbGLW z>*H#tX5@6BQ^v*;T(?vaH8H`S%Jdb+|#W|9nzLG5qI`V zhVYj4{wC^088z$fbuA7auSaFuYq4plDE5f?&U*_)?92P_ZdEijHTlbs(Qa~lVk_R! z@^aGOTCbTH$F zk!GhJUZCKm_nHUktCCa6%I^^qQZZ18B|UsYuabIky8S|wf0e#>{P6qLj@iSfjo-BOrL4QVeT-Li zjI_V15-x{InB*8%2^MvA7VOziKbhuWKKqSUWYO>ZoYPy`#DvZ-*3$Y##h_8K;)^mX zzxj)?v9*$ZYVz>>^mGez^Ng&55X>`O9laMXp41#nlqhU(e49ojXk7%hYHI>d|EYe) z^w{UZt&WyC5A+;#s==RN0(nmr-oaMHXfaZFC$hb<%%KDSh41QyL>Ka(!i>~_*>~gA~Jns7Pl^Y&UZ=`b2{z2kvg@WES0PpjOL6(wJ)T0CNo|W zih3}9cy&tyO^RJLd~32AAMfgZ%k8hYL!r910s4*_8Zk`OCyox2DKi0@hv;bj7$965Xc|L`p{%}4;oDJ&3MX7evcynFkzHZn4d zPMqZ|WYbRp8C6!hn)gpRt|>YK0&P1rWHfN-*L<2ie4}&c4%wT{ z#SYKIgM*iA$O!Kqsp400qB+>x>y{XghQZDz9qw+q;v46 z*x?xA{1?_a#^$8+%N0(obwwGB0tG%@4qwMCJISJ8x zdodhLc?ds(oZsVgFKeoR(7&lg&vTc0zdiO(z-qVvDSCqOsl6BtjU;>g@vNkm*OkGk z_vKKw(mJ{3&>xeqoaZn$5o)lzI)wf%pKGrM=gQXQDUW6 z_Gi1XZQu>s*xi#-#Arg|5=;p+|D~0_!l0lwF0K)n&(;1sMtB$ec~3Mxq@x#9hIja)I5S# ztmUKAGbcR+1p9RVdYu|O8b|+l=bdIpAt9mmLR5su?1MYWmYswnT(4%VP!Sxn{g>f+ zC`XEf{}RIlQSrf@|NO0nDBkXjxSNwQyC2bQghBr-zpBj4JI|_~;#UQJHyNrWd3N*9 zZAm}2F(ot*Ip8tCs-Ra&Ret7=fZ(`y(AIF`OPfbcFtL0ap%+7n9RcC;@xp)mZMX-` z2q?k8tV{!J*M@Y=k$FS15v-1xc~?qpva#o?L4gcU*B{U@ z@7@aqcpL<)MpfW(116h3uHNIc1O|Ct9^1*<9;aM-m=zI^}w9lSP> zps^0xkS9;TGupBXvJQ~ic%SYyO-xMm^r)P*yiio^1Utvaj~`zEkZJhb$Y>7w2I9yb z0Iqw|#CjI(`E8~?Vy;cqo_|0@{lYH@E_pgSI#$+?q}5W@)HG1|s{;fYnU+R@i3v9L zor{YL5%(iXkj>o=6wxZue`9XWn3bxntqm6t1r?Qrg#}b6_LSfOxchx?`|W}aFOtR{fLcXV`Uv&L0d3s>n|RTKB6 zJ=jEIIt?sfh{&8s9uWvzUaE<^GFu<+I^5dn=;=H0o~&^lfZrJz;isq1&dUqdtp}E! zO{W6011^v$afIC6a=o0iHU?ovu74y0f5PDHbNd+(|NJ^;U zY$htXj9W2@_QjEdmgt?b-b%<}N`U#H(ca0a0t9~tomnF|K=CYf0%v#QOA(#gIRbf2 z)aCWor0_i-s#mZ4D&z&jjK*1VQ=`BfWeskLMtdo#yV^fvt}Il&AC^(jF4E+tKJJbF zh*aVm>GrB`L5}=Yb7lK6OdcT$8XANC4@f{8k)xPU;=HYIbP0U=Qcs!+Yfp;s@kEt_ zF}8z)!`#o#KYu@%uh;27PJViUjkg*CmeuzPEt`(p%So9fO z9qzck++obZV6J)yJ{xu1jm)IbX2tGH-oJeauLbwCb@*RU7d2iN!iYWE7>y=u%+Ah+ zVa3nQO+5_WnRvpx3lDA^y}!sQEVNcqdXVr2>azBZjw}uTmU)ZUuk8hr2{`nVMLmCh z|Gsl^x?i$DbA&EUW37Ws7rCcWoS;yYV;<#S@k6iL34#Y`i|(4(eCr){3(r(#hLdaT z?cJHIc7}U^oDND65d3VrnE!|Cj9GqMwcy^(2TwkXdF&4G_0ZMpBnvt$K~WyGm?<0X zbv)_Zzpq{ERzA~YTD!~&<{ywsDbf#gcXzk6Kw&8y+97-E;P7yNZ!d5W{2)*F<8@lS)~ABL|u za*CjXDM(}B(S+Ow4rXSf;^$DzfsQE=(CG&QgGIyf5L1fTjHsqXWiC*L_o?nCMf?5h-|ZQNiEOxdAmd za{9`OIoJjvmGo5$K8OB9fet?zSqj{R8>UxQR#r_!T}^Fne!i^}COs&%CjyT^_xTF) zDfX9pKwI{TlW-v0^D+iUhoX41q`Vx@owT8$fv#LjO@wZ=%E3%kwKs}R;o#sPIVA-P zr1%A>=;(3WhGd$WMQZ* zbzdGzR!j*{VB!v=L3#WB{C`zA|A)%@zpkN~grUTx#Q**KXzY-J)*`<@S6Rut!0wf# zlkKNO68IgI>mkqcLpdd-8i!?n3-^I%?=4N_9FKJ0+N*u*ZEp%$Qjp^|S^L;LqV~`j ztKagr@nB`~t#`CB((I%y1~o2R4eR3-_wGSq-4TDjwz>*rhRyH2JrszRD&ywtHIR>L z3Fk@F&?1VEeo}NlLOQeM9zxWAUzi{5zG?%n&BjLZJ>l@@bso>`c4dEQl$u_?!?Y(6 z(P!k}TbQ26XenRc&6HL7UQFgPC-vnewwxe*$iSegsh;Nd9gCL-13gFR-4847zzpJt ziJkPNrp9Phts-<2jMS4LH40WO2uuX~_}O_8`AadEcb7AZ9a^#RT2J!GC7yg$rL?g6 ze67EDpFLoE(#CRmMR0XIdE!wYTGP?a>cFz@Wb<*Uoq*c`Z81F;muu%A8#kTfAI`R- z9t#56?Xxs3n;Xg5iYdFxX%rE@PpNWoKU06LdGYA2?RM)^cC2&su|ww<&FGXe|A6pQ zrYh`-LbWT~ks3^;nn(o%iuOyL_kC5>=J=RKuOg4lBqS6Y>n4Srwy+eb>6Vc&$YoN5 zv(n##llbuMLU9_0%;XcfCOciLsECL+n`1;GUT>YJr}RKVR`~TRZo$w}mkyS{*CpTS zQ4v3(Vl(`e?ioglUAhF*iuM_f@WU?v;<}&ARLnmP0C6npo2bEtG|^{tbj_)P4n|tf z1&Ve4Y}JyJdx-5ec^I*}4QCeXo)ZpXTu%=t|efLXuR?jF^`cKy%n3jg-`KIol9 zw}P{>{EF?W%PqAY5I+LP>hM`Xk-?9swV{940#sYwcoOmoE_I(irFyv872_f|`qzRK z7=kLUW>5bcQ(^^tRu&e=>{lMAoe5vly3??dd^_eX%rBx{E##Oa)uY>tIu_;I5>7bY&!2q$#STF(qM{+(JO*<`;|seCXi1g|Wv~ zP63mAqWeN`VL=tQRr8n-h3=$jXQYgO;0^l|`|n9JzoU3uc}@MlC;Ix{=S?t%=t})@+nsX;$cLAXxaM!q znWVOMN2Bq7YB_C_6LTrwF}HSj?$ge%M(6abO%4oarxm1xPM5ed@$XC1{HrfzPkViP z(R^hGP_00fCu&u#h=Ukh>^?s0-s94?JNSr$NMB?8(J>rQ9Z(bkgbyB58|m(yy3~5t z)YeBYmJ)o$SwzPWOm#3MY@W5%FeKJRYj|l|DKo$8(q4F5Rj-|xTwZt?x)9ChSnuB} zC3f#X50fbqDuG;8SqU|shB-@oM|nvJcJkwAT|35<+d_flAD}WkS{qUT#(JeUy~v=! zLq|UI+iZGStK;#Oo*!QEoAHY51&8e^5h&$A2M;bL%k}FCuc>m&_~_^XC^M6y>Vt8J z{lWUsYj9;i1sBh*M+_=7Xxb5f+$h8^TxLfm@`&s&%DGO2o_UbmQTLN(?~|OF zofY@^Xje4>p$^c(kSzsi;hQ|bK$I@bQizA3&b76((|xmFhu|!PyAI0=A206&gs8Z= z2~}Bu{l2220!~;m0Q~_93JiK_BO_{XyGJ)RH5F)=`nMSi2?#7KEMVGT<6sjI{BT^? zgrp@X^?Q4Jfw0{3d7*ZQDRFdk1PDK<7QsqeSXc;lB3$QC;FL}tk*Asbd1@}w@tvkv zZimdeWTh_?$=^`wTVxsQlYXke@Nf#wm+v5IK}t$WeGf@V{B$QG@%5dOFp~Q_5Vo+1c5Scn(?QNP-{$O9h~5ldsCE_r`SHNH#{+Z`D$ zGIT7_v9XS;{dAzc$X>um4BVTgqA?NeX_~c#XfRxCY&9?vK7YP4JBvkp<``zXml6cz z>DFNG0CdN&MuQD3sj;hzjh8p3VHOlV0s;aMZWtvULG-h_x=6be1~eS>jEt?5leJUf z1`m@wuP#mzQSoO4tW8Zd)ztbYe&eehIfocw{2I#F8WAJNLpW^H6trXb9>w5S z0TyCrZB34i4a1uiVAX;GNCb4+9HT2E@i%<`{yns(5SlPi>&}03CpX4_a0m;J|M~N$ zp@D{)`gdpNM_7`WA3aL$S=NC@@%eK=N~Kq@C8Gc^fsyh?!_b8_#(Y(8CD2@kdS}j8v$bfq9Tq{ z6|g7u(SlY&t56r~g&e;4!Z08|5YVB(p>UAt4#-sFhm~kuHMLxvEF{D}NlYv(s(B=g z2!0s6i()hA8p&=gCcRSd6z)_@Qz|Jdr$#lM^Lp_G z#b-5Qp+{fYQs!Fy43oZgVKVkD8n`h6rXPs3toxXn$jpHHE|QHnvZ=@$nVX+XNkgS3 z_$sSM7I1Cwh)QWTbBfCHfEMqxp34eF;JnfaB1tJ%0V#Ge?|^I1HF{L#th z+@Qk^i+Do)dW5g>*U!Xu zR_*p!I5<#Opw4crY>Gplm7Ptm$yAuyH!8}M%9oob{?n%wcnS{ZTVkuKHh9b)fo!Uc zR$qVE#N<7ifAd6D1tQ{AR#tu-hqDwiJXl5+dX=2zWp9VhkG-a*F7JjszSd_0{uz&G z_33j$)#rq^OCK3RvgmT%Bx0xQr#&~vsC2jPy?RB4ZYEOI_WSqDLK{Ok`Qyw^?Y6gOBz|EwT%c+V5v-Dbj(`TD$Nqzl#t4Sejs)Z$|dsN16 zJa<<5?sIY3bapkIAB!cY=y@HiNO8CA%r4Q$%Iuw9?Ce0zlkDgu%4PTg&mUG8r)_dQ zRaFzC63ga~21nb@HshKh@T_n?@<0pAEYv%8TrG)jm<Wut|MC#0YNLpkwa z;Bb9AIXNsksZiIo*29%rBJfx5$@H~MvRGPfvr3ZpJXhV+;yn=S6Z*pxsaNCjbY)rh zZNUXT;^@aXgSC66Ec5adP++rUV;2d`%iK@OPs=AOlC(KwoChOyvpf*4E^=0t|bB zi-Q9X)R5YtA;%0yTj%ZJAKO$$>Z-k=@f@&9P#cAQS)=kL7iqT{QHC|Je|4ZBI=U1F zA!S*^pJF{pNm&?mI`yLEyJTO+WWwzV3NDvXEdT6KK}uj_Ny9(4PEWo0*j1Qpw0>~{ zsAL8;pD1(|0DP~n)sZWuCk#Sz0ZbDQ-H)t{^1-+CWscpT?&9Lq!N|V7`5EC?Tv)JF z(&{LErCJnSPtAm@8*HZIsD0nQ{lq#vqLU*nJ=FNy_kLetVcfL0O{sCv<<4wQBfTLf z@5zO?J)ATM=|+a+&Z*;iTKM?tQ*Gq)$dfiJ&3epzFUplwxY2l`bil%;yZN!a*IWgV< zCo#Oy*VwlgT3O_D1Di?6C@0(B*b8_|7 z+MBqk_KpzT#1OA*^8HDC+OEMIx%egs`|*i!;5y zI@aS$N_t@Gem#(lH?f>?H*CHQ@Ii5Lc(&k>y-qPxiikO#^u0Kl4;KiV7f?3#n-}n9 zLwV}OlddlxqB~Ml-_d1Kq~jdjv1n$-(b1_J6|Y5v89`e{5|+6+KG5Iq^+YbA)<~K< z43_hYi#ay72f@Lb`c>SMBmC?fMN#mq1a~R-_Wn~+8o#*kU8iF3;4m~gE7j+oA>aUst!#TDcQQR9OLj&^pdu=YXQ42WUd zx;WKg_x3&9$K?DtYkvQMqpJV9g342qEjMcTyRngg!%Oz7NY>Du_A<3z^H8 zK6z6rG+H^EcD%%FVt$(v@rHNey$^pf2kReKy_?G&@&vrXTvds{r9#pAO2PzJ2FTQdAFwx5Cx4cc3O~&qbnz;Dc-`L9Qx6HhP+ceWCz~o1Y&qP=PSk`-`#x1nLIRVC zR~FQOz#u{5>-W(OUtiy{GG3!#?EllUyG_Z>&CS}{T3T8fgb=CRCO2xG$TPL=(<%Yd zZeU!1!eBUPyK9_|-s2!g&0Byi*M1=n6b3gJ7fcOgLcENOE9cwwDvFA<^bA-^P(Q~f zBmjX-MoJ0+dk_&Ry^cvhaC|cfs>8X%?P_Jgl^c>ohTvHO0sO0a({X}GH!UqKIXM`U{>@@UJ7)1OM>Hs$!;g0m9J$c_X6wlAnLxfFTC^9;h9m-|C0y(-n$2R(zN~rEF_gE_9=s z!!hl>*yp~XG<=5}gO%j+XbN03acnyDITi4bKH|;nT!u>+7IPXK*cUVpvEC^_eSr0J z40M-}HAfE;KbQv=Z3SSl1P3=HN*ZGs`)_S+flnX$7&z{upx8S*7ahlOCUt?J=>phE zTT*@=9>~oVblM=SDu2}y24of3g=h9p;q^;POEbSaB=R8k^nhM>3|I^6$r-*Mp*a=D zRZ^iO{M{21HB+atoM=FCymfLS7qnjhod_2iPLeSgaKT##g)Eqnv9Pc}WdtXq2~CBE z==8rb&7ix0|0o&UhnoPb-ucd~B#eURtZ_5+_#uv46IIZU5D^lB#2A8n%Yr;_Bcr7L zWyczi1wY#jZi*7PN&?VvyUJs8jL%4XW$T+cHW0#a?4`jF%#iyS8Vc@i>N1#MTMM8$ z2B&(Qe%y*uM6LTVHmZb*JytV3i(WNC*9!s+3@YTK@`*L?b+>`+U0#-DJwHDW$)=8L zLch04h~}@ldUGRH(I4aevyJ~=s^Z}#HI2!o!5hng?bT8@YYygnojpUOK$v5Xj*Yq~ zo;~C^e!yi}cu=n(pO58MxWP{TKlPr;C#6Am@1ft!2b<3 zdDMscp&1*=xcHBT>(dVG2)Mp`35eIO6*yO#KJ^r0{toPvp~-dsL?SLO>+Yz#^Sz&U z(Jy3&vR;n(3=zFNt7APGmCARXB%$-#uFB(ei1}U8=|IDz7(LX)_wc)V45ft?P7h1G zD*&}teJ<3blF{zf9UFIar(9Zr$>{uuzU%8NOH2FtW-DLS*LgoeLxWb(p)fBmw@gy= zMSi|mc7MG+Jv$| zKG6@ey;Il7D8qesZZMoeYiX&ZCwZ5bZ-_41#Z@~#7Ll8f*kO4LANM3auJA?O1Qr$T z!}}pwjKJ(d?c#hnBJbMD8Sdgn_%d2LP#pBSG~2~Z^9AKfPq0l zlk4^YieocVd>tK%WZu=B^^s{o!AmpjLN*P zcW+S*O;YMhtOi(mGG$LU$5v}x)rCBN!eTV+gJiI5d33PR_oHan_x{t@r=fWlbvhe; znJr2DHi6W%Y^YltLehx`Z570cV&=*IsSXxuZi!z$pX;WHdV*2_{nOrFkCRitbR8Hu zS64W-zZE&_galumra@(2mY=_PJUz~;Z6xM#!c;6ri1tAAI&EUSd|=l8)Y0+L?C-lE z@yvcK`(M_wdnJ#%huYUsR=g#7CB=g+Sjkwg4Yix!tkpdr(JadzmnlOa8V&-T+F z(}D#{%4FH1)OH32CKL~(qtsyYRRU8a-oU_M-o z+P6}dJ-W@;fia8In90F~akIJ!h8Mhn`@tV58vbl-m=OBwRqY8;Qp(XvmU+6rcrk`S zif+>sEJZ52K0Jx5G`CFPeX`@5kr4~MQC*##t1GNFWI`MCB}SzbHcQ;o*6s`m>b>82(u_NELNGV-={pLK6Mp^P{zhUM>5{9r**=Ov8qT ziQmb;`-?%I(nyr@e{(|t@QMaCCuHeIxSHsUSYh)d{DX){MRXhuS*;!CG~9a|17?#@ z3K_kUL46bYKg!lcb@k7r|9#oYxKb_sSa_j|N9A670kbMK;3!!lk{BAKr&M<%QJBvVEo-By5jH<8;LYAwT8L?b{XBlg#Hu9K_4e%Yv{1`Y0&8J_ZKv936R` z>`)coUpjq_Vlug?(I^NzTM@A9uE1WiAx$V47_!J%9FjjOD%e?BlZ71fpw)!|`%SwP z1qG#*wy&=bmhVOTs+MpHh$%8De(rv>0rP~C+J99#)BmT^nHhF<(SXu9L>XP$1rnZN zd!D2uogC#9z!21*J)@iU(!j3r`U;6OzJ7j(8>8xsR(f?FHuD}BXKqakaFgcUl zysXB50ea7s#31c^@P(FiSK+=b{}da02%4Lfl@;*AQv!Mvg((53G{`s71ni8gt+(JI zG_|l0^uF@oZiD(*O-&8bAR#PPLPFxj3u3PPpg*)Mn%_A2_}D-$24SkZyG$%BG$E8c z0CW@j*Lq)zvakTKRx)ZOH-tm$WX~vJXIGq(q6gG8>YKywp1M(Lsiv z01AeF2yk~QjXBWCfN)0}-U$b%)Ou3LKDswDirdTA#l;0P%|n;n8KfovHZmB|b?y(r z4hQ6iYP~~q{aFfJXbz5!ctQ*+N=mg*al*I>@&+~`5-PSaVZ8* ze9~z~ok+{h&d$RF2>rjX@RhaTgl334+5!@wF<z{aUw3Eyk$4fJP;BX=`Fp4*|i_ zc8Kuw|G*7*Dj!wr`mHHxpm2BqTm7E5neHvL0WhhruMZr?P5jOX>fe(@PU|_|-EC`c|M_+` zDl3bw82X&2?T-u|3oX`_D<<^7b^*z9(e!@4z8cS-L0jVH;^OP?AEguYe^%r3_d-(# z!;a(mcZ3!@9-dN=LULPC`HF%>&vkDB+D3rTT_HmQlGAaW!kAt54ib``;y|?yyailT zXxiWawp&(QtvNgb1gqIOIXL_(u;&&Wwxrj)Efhf=MAY7-EmT%*%GwP+pUbxKTmE9~ zS1`;>I^tlM%?WJH&K6sau%}P{dy@cOZRpLLIa#6c;cbJ|bV$WEx3c<{pHG5?WoT+D zgAck$6=OVda!B6~@&!RzSYTj8R;n6(Kq9B%Z(z~jO>R(NIK%DnAK@Roo^q9R)*Wo8 z#whjq89p~R{~8h!0)rmnwVPo$!RP_iRi6kH^2Gol%XP~?QH>0EV4=j+;6vF$BReIG zSrhb_-Jsej^f~5FVV1Ld}N#Q_9&BWYW zlPZ*q{*=bT!=ug>&K;=S^o;%GleB=+PRf~{&_4SQadyAl7fOl z&?#fD)zO^U%8Q-WkokYYJ4hzumgG`s2-F5nK^aw5RVC#M=ol8t>(`PZOUn{!IdgNi z0uIaFlOXB*NiKEz9)2ui`~sk5oc+&NSLfRxnn{Kw62@NQn0j90aJB(3&NkcIYm+?O zdsdQWRZn*=bo+DWK$}a#`SLLg29qK&;Hp1YyakBr#o?Ep9>^>NeQR3Ujb;?)&l|mn zDG%z{*eIp1ae`0VU&gzut<_xvPwDhRR}Ho$+jRl8F9hD+dlqX$4|Gd=2MZ%BSx1*E zq;$l_pUa$ifh^k8MJc*O(#6HJy~_g?RRo0vX@!m<=k-D$x>ZGa?-^(TN*(N5!tB)L z3*H3-Z(dTy>HPL>M2X6O5Sx@Zup8CfQ2NZ0kA;mI@FfBXzwO?aLn*>ir8@L4xR<{7 zIG~P;F#md&1nZeOo&W!MGiIw^611Qly3U{2L ziR>cq-sM1em(07eEdJo+5aZ(A9fZ%+Got^!@{o9ElA4R5XyWy41oPpAJ&n6q6>BNf z#0Ut)0WP{4%`eKt6Q-jO>3;z5cH=<((N3I}~!=dpkCHj%)hWD;Y_+ zD}kqaYI5)}K$H8b=1$^tauNs4U!goUPN74FdSK%b{94{e5<*{pGnv*f8)#h+UmWC0qsAw+Jnikx=Q!56HFim3aYcDNUY33TO|sV>Bi0j?JHy?Bn%$NRze8s2-5H ziC$Z3HhzFto)BdA>^{T`ZwUzvP2z5Hm}|7N+YMR>vJ42*!yp$L%PFc2SpMPaeZgcx z7dhMh%#wy09m^6#5#-nx>l}kajy7z5 zaS>0!Gwyh8(z|yCi$OV6hI)Bnbu}E;EXgZ%9UT_YEtHUiae^ofWH%DHli6@ku?p8Bs}EA1FMxl_FqGCpp>kh4|Hz(kYzNzYlQU9=>?f^gNO)yjmy=_LJ)=X#vdj6 z&aQJBL8haBu0+Nw0%is34Ck+1bf+fENbc`yrHQ(-Yv{nH6krUhc9MzuNz$?lAD7b? zFgysJ0lNL+y#UPnK0cDL$B@@*|LFn=|Eb4Sd#t6Np6o=uGt1W5B4C*Xx>ea&NJa1G z#nBModd;_1p9VjQ3H|&jQzg#Cx-aupj&&o2LkPLlQq-6qYd}QEd()G$o^i zjzw*!RoK5G#wiljs6`Uzse77&{<1D9`tsS~Nes!zzP-WnVx97n%EX9>i^UFtU%g?5 zgm&|)XY!CJ*q5m{j}rxf6icguPZ@(bbXVNxq>Q0pzkLx;^&aB^85!BHd03;Ua8La9 zic3qYh#gWc%#@Ti_we3>pM*Z2>eF3A!ti4iIzUNzmjg!c-*1D&{P1}f;9S+!aRN2# z-A)%?Y;c60{P~q6W0*3HjACB*`(~#2eEPv8NRK90@58lcAmXpx$IoKFQWu@;f-G?i zoW>Rw;uiyX?))MmlLj_9Smk2Z13jQ3k_}6>wIzIaMW$$^h21teDcjQA+{8c&@c_!- zX-+(@Qp&1B;#mo~jGn(Yi<{v&2{J1?i_gY81P)3wM7(RP4Kgh9R ze`tdr4>4Q%g7LhF6BD~7btfn2%eH$(%@5^&sSzJ+s%2g?X77{i%5rsSb*5{KE}`Nc zr+o|j=hyOl)R^Dhx)5A442{8n_SXMQDE3d=i8xQqf!4GTy0;&#?0N;IQ)cZYYQ3G? zUZ1!}8wMPVYESdI$;0bi+Dc&eX1P%YFzmvvWX7v)GOE_gu-8qRcNMiKWn1}ayL9~0 zh%h;^Z1a-B^sRqW$jS(oP6SRu!_OX{6dSvLHbkN|f;E_G%bdD#NmC!kT)h7*{Zw8m zbEzZq_TWRm6-hM-fE7t2thb-zsN zSIdZ&mRmFPbF8yZ3deLiK61@0eIwMwn>M)O6~RrO_+cs%!U4^U)Ul>@f|Tagg!+dZ zzpy6ci#C1KD^B@HdtCZk$e^mr#;8ImXQp-NU%w>bNJF4JS%g2Rb!V%uy_&flp)1}n zXKB)d=oc$LO4f-P)-x1dgC&t9$9y*E6**|1#G0AHQGXUta16D`}Ok39@wTy_d(W zp-@u86z5W)z89+DH~1vo*j0;>mx6B|eyTmc3A`^Id$-M0Ib>y#P{O%3AMYpKyzB1v zjUVLJ|DFj%cDU8V!jK%#Q@rrmEd*XOs7{TqT_e8r^x|L~O6=T5XqEHvA|HHbaQ#m> zHUa|k?JWpM`F~+EAw*8Enc%;=%8%8Detect Self-intersections in the Main Menu select +Inspection - > Detect Self-intersections. + +There are two ways to check self-intersections. + +\anchor check_self_intersections_topological +

      Check topological intersections

      + This operation checks the topology of the selected shape to detect self-intersections. \image html measures11.png @@ -29,5 +37,28 @@ where: \n See also a \ref tui_check_self_intersections_page "TUI example". +\anchor check_self_intersections_fast +

      Fast intersection

      + +This operations allows to quickly detect self-interferences of the given shape by means of algorithm based on mesh intersections. + +\image html measures13.png + +This algorithm works on the faces level, i.e. it computes only face-to-face intersections. No additional types of intersections is computed. +This case can be useful in order to detect all the intersections between the subshapes of type "surface" inside assembly. +Quality of result will depend on the quality of tesselation (managed via the deflection parameter). However, small values of deflection can +significantly decrease performance of the algorithm. +Nevertheless, performance of Fast Intersect algorithm is much higher than topological intersection. + +\n Result: Boolean. +\n TUI Command: geompy.CheckSelfIntersectionsFast(theShape, theDeflection, theTolerance), \n +where: \n +\em theShape is the shape checked for validity. \n +\em theDeflection is a linear deflection coefficient that specifies quality of tesselation. If theDeflection <= 0, default deflection 0.001 is used. +\em theTolerance Specifies a distance between shapes used for detecting gaps: + - if theTolerance <= 0, algorithm detects intersections; + - if theTolerance > 0, algorithm detects gaps. + +See also a \ref tui_check_self_intersections_fast_page "TUI example". */ \ No newline at end of file diff --git a/doc/salome/gui/GEOM/input/tui_check_self_intersections_fast.doc b/doc/salome/gui/GEOM/input/tui_check_self_intersections_fast.doc new file mode 100644 index 000000000..c8266e331 --- /dev/null +++ b/doc/salome/gui/GEOM/input/tui_check_self_intersections_fast.doc @@ -0,0 +1,6 @@ +/*! + +\page tui_check_self_intersections_fast_page Detect Self-intersections fast +\tui_script{check_self_intersections_fast.py} + +*/ diff --git a/doc/salome/gui/GEOM/input/tui_measurement_tools.doc b/doc/salome/gui/GEOM/input/tui_measurement_tools.doc index 6e83325c3..be111dbb1 100644 --- a/doc/salome/gui/GEOM/input/tui_measurement_tools.doc +++ b/doc/salome/gui/GEOM/input/tui_measurement_tools.doc @@ -19,6 +19,7 @@
    23. \subpage tui_check_compound_of_blocks_page
    24. \subpage tui_get_non_blocks_page
    25. \subpage tui_check_self_intersections_page
    26. +
    27. \subpage tui_check_self_intersections_fast_page
    28. \subpage tui_fast_intersection_page
    29. diff --git a/doc/salome/gui/GEOM/input/tui_test_measures.doc b/doc/salome/gui/GEOM/input/tui_test_measures.doc index b954b7f60..3e147f388 100644 --- a/doc/salome/gui/GEOM/input/tui_test_measures.doc +++ b/doc/salome/gui/GEOM/input/tui_test_measures.doc @@ -17,7 +17,10 @@ \until Detect Self-intersections \anchor swig_CheckSelfIntersections -\until Detect Fast intersection +\until Detect Self-intersections fast + +\anchor swig_CheckSelfIntersectionsFast +\until Fast intersection \anchor swig_FastIntersection \until WhatIs diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 87a912edc..88edc8f07 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -4448,6 +4448,21 @@ module GEOM in long theCheckLevel, out ListOfLong theIntersections); + /*! + * \brief Detect self-intersections of the given shape with algorithm based on mesh intersections. + * \param theShape Shape to check validity of. + * \param theDeflection Linear deflection coefficient that specifies quality of tesselation. + * \param theTolerance Specifies a distance between sub-shapes used for detecting gaps: + * - if \a theTolerance <= 0, algorithm detects intersections + * - if \a theTolerance > 0, algorithm detects gaps + * \param theIntersections Output. List of intersected sub-shapes IDs, it contains pairs of IDs. + * \return TRUE, if the shape does not have any self-intersections. + */ + boolean CheckSelfIntersectionsFast (in GEOM_Object theShape, + in float theDeflection, + in double theTolerance, + out ListOfLong theIntersections); + /*! * \brief Detect intersections of the given shapes with algorithm based on mesh intersections. * \param theShape1 First source object diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 8c43d9c84..9d86a99db 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -7274,6 +7274,10 @@ Do you want to create new material? MeasureGUI_CheckSelfIntersectionsDlg + + GEOM_CHECK_INTERSECT_TYPE + Self-intersection Detection Type + GEOM_CHECK_INTE_INTERSECTIONS Self-intersections @@ -7338,6 +7342,14 @@ Do you want to create new material? GEOM_CHECK_INTE_ALL Face to Face + all above + + GEOM_CHECK_INT_DEFLECT + Deflection coefficient + + + GEOM_CHECK_INT_DETECT_GAPS + Detect gaps with tolerance + MeasureGUI_FastCheckIntersectionsDlg diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 0d8d4623c..06169dafb 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -7274,6 +7274,10 @@ Voulez-vous en créer un nouveau ? MeasureGUI_CheckSelfIntersectionsDlg + + GEOM_CHECK_INTERSECT_TYPE + Self-intersection Detection Type + GEOM_CHECK_INTE_INTERSECTIONS Auto-intersections @@ -7338,6 +7342,14 @@ Voulez-vous en créer un nouveau ? GEOM_CHECK_INTE_ALL Face à Face + tout au-delà + + GEOM_CHECK_INT_DEFLECT + Deflection coefficient + + + GEOM_CHECK_INT_DETECT_GAPS + Detect gaps with tolerance + MeasureGUI_FastCheckIntersectionsDlg diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts index 6efba76e0..a92a3e60b 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -7271,6 +7271,10 @@ MeasureGUI_CheckSelfIntersectionsDlg + + GEOM_CHECK_INTERSECT_TYPE + Self-intersection Detection Type + GEOM_CHECK_INTE_INTERSECTIONS 自己交差 @@ -7335,6 +7339,14 @@ GEOM_CHECK_INTE_ALL 面から面と上記すべて + + GEOM_CHECK_INT_DEFLECT + Deflection coefficient + + + GEOM_CHECK_INT_DETECT_GAPS + Detect gaps with tolerance + MeasureGUI_FastCheckIntersectionsDlg diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index d1d23d51c..5e33ac622 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -50,8 +50,9 @@ #include #include #include -#if OCC_VERSION_LARGE > 0x06080000 #include +#if OCC_VERSION_LARGE > 0x06090000 +#include #endif #include #include @@ -71,10 +72,13 @@ #include #include #include +#include #include #include #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC +#include + //============================================================================= /*! * Constructor @@ -1510,7 +1514,6 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections Handle(TColStd_HSequenceOfInteger)& theIntersections) { SetErrorCode(KO); - bool isGood = false; if (theIntersections.IsNull()) theIntersections = new TColStd_HSequenceOfInteger; @@ -1518,13 +1521,13 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections theIntersections->Clear(); if (theShape.IsNull()) - return isGood; + return false; Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); - if (aRefShape.IsNull()) return isGood; + if (aRefShape.IsNull()) return false; TopoDS_Shape aShape = aRefShape->GetValue(); - if (aShape.IsNull()) return isGood; + if (aShape.IsNull()) return false; // 0. Prepare data TopoDS_Shape aScopy; @@ -1546,7 +1549,6 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections aCSI.Perform(); Standard_Integer iErr = aCSI.ErrorStatus(); - isGood = true; // Standard_Integer aNbS, n1, n2; BOPDS_MapIteratorMapOfPassKey aItMPK; @@ -1570,14 +1572,82 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections theIntersections->Append(anIndices.FindIndex(aS1)); theIntersections->Append(anIndices.FindIndex(aS2)); - isGood = false; } if (!iErr) { SetErrorCode(OK); } - return isGood; + return theIntersections->IsEmpty(); +} + +//============================================================================= +/*! + * CheckSelfIntersectionsFast + */ +//============================================================================= +bool GEOMImpl_IMeasureOperations::CheckSelfIntersectionsFast + (Handle(GEOM_Object) theShape, + float theDeflection, double theTolerance, + Handle(TColStd_HSequenceOfInteger)& theIntersections) +{ + SetErrorCode(KO); + + if (theIntersections.IsNull()) + theIntersections = new TColStd_HSequenceOfInteger; + else + theIntersections->Clear(); + + if (theShape.IsNull()) + return false; + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return false; + + TopoDS_Shape aShape = aRefShape->GetValue(); + if (aShape.IsNull()) return false; + + // Prepare data + TopoDS_Shape aScopy; + + GEOMAlgo_AlgoTools::CopyShape(aShape, aScopy); + GEOMUtils::MeshShape(aScopy, theDeflection); + + // Map sub-shapes and their indices + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aScopy, anIndices); + +#if OCC_VERSION_LARGE > 0x06090000 + // Checker of fast interferences + BRepExtrema_SelfIntersection aTool(aScopy, (theTolerance <= 0.) ? 0.0 : theTolerance); + + // Launch the checker + aTool.Perform(); + + const BRepExtrema_OverlapTool::OverlapSubShapes& intersections = aTool.OverlapElements(); + + std::set processed; + + for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator it(intersections); it.More(); it.Next()) { + Standard_Integer idxLeft = it.Key(); + if (processed.count(idxLeft) > 0) continue; // already added + processed.insert(idxLeft); + const TColStd_PackedMapOfInteger& overlaps = it.Value(); + for (TColStd_MapIteratorOfPackedMapOfInteger subit(overlaps); subit.More(); subit.Next()) { + Standard_Integer idxRight = subit.Key(); + if (processed.count(idxRight) > 0) continue; // already added + const TopoDS_Shape& aS1 = aTool.GetSubShape(idxLeft); + const TopoDS_Shape& aS2 = aTool.GetSubShape(idxRight); + theIntersections->Append(anIndices.FindIndex(aS1)); + theIntersections->Append(anIndices.FindIndex(aS2)); + } + } + + if (aTool.IsDone()) + SetErrorCode(OK); +#endif + + return theIntersections->IsEmpty(); } //============================================================================= @@ -1593,8 +1663,6 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1, SetErrorCode(KO); bool isGood = false; -#if OCC_VERSION_LARGE > 0x06080000 - if (theIntersections1.IsNull()) theIntersections1 = new TColStd_HSequenceOfInteger; else @@ -1646,12 +1714,22 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1, aBSP.Perform(); // 2. Get sets of IDs of overlapped faces - for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) { +#if OCC_VERSION_LARGE > 0x06090000 + for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) +#else + for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) +#endif + { const TopoDS_Shape& aS1 = aBSP.GetSubShape1(anIt1.Key()); theIntersections1->Append(anIndices1.FindIndex(aS1)); } - for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) { +#if OCC_VERSION_LARGE > 0x06090000 + for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) +#else + for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) +#endif + { const TopoDS_Shape& aS2 = aBSP.GetSubShape2(anIt2.Key()); theIntersections2->Append(anIndices2.FindIndex(aS2)); } @@ -1661,8 +1739,6 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1, if (aBSP.IsDone()) SetErrorCode(OK); -#endif // OCC_VERSION_LARGE > 0x06080000 - return isGood; } diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx index 3798af25e..e81e5db1f 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx @@ -158,6 +158,11 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations { const SICheckLevel theCheckLevel, Handle(TColStd_HSequenceOfInteger)& theIntersections); + Standard_EXPORT bool CheckSelfIntersectionsFast (Handle(GEOM_Object) theShape, + float deflection, + double tolerance, + Handle(TColStd_HSequenceOfInteger)& theIntersections); + Standard_EXPORT bool FastIntersect (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2, double tolerance, float deflection, Handle(TColStd_HSequenceOfInteger)& theIntersections1, diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.cc b/src/GEOM_I/GEOM_IMeasureOperations_i.cc index f75787a3c..407d71f05 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.cc +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.cc @@ -765,6 +765,49 @@ CORBA::Boolean GEOM_IMeasureOperations_i::CheckSelfIntersections (GEOM::GEOM_Obj return isGood; } +//============================================================================= +/*! + * CheckSelfIntersectionsFast + */ +//============================================================================= +CORBA::Boolean GEOM_IMeasureOperations_i::CheckSelfIntersectionsFast + (GEOM::GEOM_Object_ptr theShape, + CORBA::Float theDeflection, + CORBA::Double theTolerance, + GEOM::ListOfLong_out theIntersections) +{ + // Set a not done flag + GetOperations()->SetNotDone(); + + bool isGood = false; + + // Allocate the CORBA arrays + GEOM::ListOfLong_var anIntegersArray = new GEOM::ListOfLong(); + + // Get the reference shape + Handle(GEOM_Object) aShape = GetObjectImpl(theShape); + + if (!aShape.IsNull()) { + Handle(TColStd_HSequenceOfInteger) anIntegers = new TColStd_HSequenceOfInteger; + + // Detect self-intersections + isGood = GetOperations()->CheckSelfIntersectionsFast + (aShape, theDeflection, theTolerance, anIntegers); + + int nbInts = anIntegers->Length(); + + anIntegersArray->length(nbInts); + + for (int ii = 0; ii < nbInts; ii++) { + anIntegersArray[ii] = anIntegers->Value(ii + 1); + } + } + + // Initialize out-parameters with local arrays + theIntersections = anIntegersArray._retn(); + return isGood; +} + //============================================================================= /*! * FastIntersect diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.hh b/src/GEOM_I/GEOM_IMeasureOperations_i.hh index 27e2e5d42..71e6194ba 100644 --- a/src/GEOM_I/GEOM_IMeasureOperations_i.hh +++ b/src/GEOM_I/GEOM_IMeasureOperations_i.hh @@ -100,6 +100,11 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i : CORBA::Long theCheckLevel, GEOM::ListOfLong_out theIntersections); + CORBA::Boolean CheckSelfIntersectionsFast (GEOM::GEOM_Object_ptr theShape, + CORBA::Float theDeflection, + CORBA::Double theTolerance, + GEOM::ListOfLong_out theIntersections); + CORBA::Boolean FastIntersect (GEOM::GEOM_Object_ptr theShape1, GEOM::GEOM_Object_ptr theShape2, CORBA::Double theTolerance, diff --git a/src/GEOM_SWIG/GEOM_TestMeasures.py b/src/GEOM_SWIG/GEOM_TestMeasures.py index 87c9a0d11..7ad571552 100644 --- a/src/GEOM_SWIG/GEOM_TestMeasures.py +++ b/src/GEOM_SWIG/GEOM_TestMeasures.py @@ -33,8 +33,12 @@ def TestMeasureOperations (geompy, math): p678 = geompy.MakeVertex(60, 70, 80) p789 = geompy.MakeVertex(70, 80, 90) + vz = geompy.MakeVectorDXDYDZ(0, 0, 1) + cube = geompy.MakeBoxTwoPnt(p678, p789) + cylinder = geompy.MakeCylinder(p0, vz, 5, 70) + ####### PointCoordinates ####### Coords = geompy.PointCoordinates(p137) @@ -52,18 +56,20 @@ def TestMeasureOperations (geompy, math): ####### Detect Self-intersections ####### - [Face_1,Face_2] = geompy.SubShapes(box, [33, 23]) - Translation_1 = geompy.MakeTranslation(Face_1, 5, -15, -40) - Compound_1 = geompy.MakeCompound([Face_2, Translation_1]) - if geompy.CheckSelfIntersections(Compound_1) == True: + selfIntersected = geompy.MakeCompound([box, cylinder]) + if geompy.CheckSelfIntersections(selfIntersected): raise RuntimeError, "Existing self-intersection is not detected" - ####### Detect Fast intersection ####### + ####### Detect Self-intersections fast ####### - if salome_version.getXVersion() > "0x70501": - cylinder = geompy.MakeCylinderRH(100, 300) - if geompy.FastIntersect(box, cylinder)[0] == False: - raise RuntimeError, "Existing intersection is not detected" + if salome_version.getXVersion() > "0x70600": + if geompy.CheckSelfIntersectionsFast(selfIntersected): + raise RuntimeError, "Existing self-intersection is not detected" + + ####### Fast intersection ####### + + if not geompy.FastIntersect(box, cylinder)[0]: + raise RuntimeError, "Existing intersection is not detected" ####### WhatIs ####### diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index f932a632a..982a45dc5 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -11257,6 +11257,37 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): RaiseIfFailed("CheckSelfIntersections", self.MeasuOp) return IsValid + ## Detect self-intersections of the given shape with algorithm based on mesh intersections. + # @param theShape Shape to check. + # @param theDeflection Linear deflection coefficient that specifies quality of tesselation: + # - if \a theDeflection <= 0, default deflection 0.001 is used + # @param theTolerance Specifies a distance between sub-shapes used for detecting gaps: + # - if \a theTolerance <= 0, algorithm detects intersections (default behavior) + # - if \a theTolerance > 0, algorithm detects gaps + # @return TRUE, if the shape contains no self-intersections. + # + # @ref tui_check_self_intersections_fast_page "Example" + @ManageTransactions("MeasuOp") + def CheckSelfIntersectionsFast(self, theShape, theDeflection = 0.001, theTolerance = 0.0): + """ + Detect self-intersections of the given shape with algorithm based on mesh intersections. + + Parameters: + theShape Shape to check. + theDeflection Linear deflection coefficient that specifies quality of tesselation: + - if theDeflection <= 0, default deflection 0.001 is used + theTolerance Specifies a distance between shapes used for detecting gaps: + - if theTolerance <= 0, algorithm detects intersections (default behavior) + - if theTolerance > 0, algorithm detects gaps + + Returns: + TRUE, if the shape contains no self-intersections. + """ + # Example: see GEOM_TestMeasures.py + (IsValid, Pairs) = self.MeasuOp.CheckSelfIntersectionsFast(theShape, theDeflection, theTolerance) + RaiseIfFailed("CheckSelfIntersectionsFast", self.MeasuOp) + return IsValid + ## Detect intersections of the given shapes with algorithm based on mesh intersections. # @param theShape1 First source object # @param theShape2 Second source object diff --git a/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx index a07e919e5..97b3d170e 100644 --- a/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx @@ -26,6 +26,7 @@ #include "MeasureGUI_CheckSelfIntersectionsDlg.h" #include "MeasureGUI.h" +#include #include #include #include @@ -58,80 +59,144 @@ //================================================================================= MeasureGUI_CheckSelfIntersectionsDlg::MeasureGUI_CheckSelfIntersectionsDlg (GeometryGUI* GUI, QWidget* parent) : GEOMBase_Skeleton (GUI, parent, false), - myTextView (0), - mySelButton (0), - myEditObjName (0), + myTextView1 (0), + myTextView2 (0), + mySelButton1 (0), + mySelButton2 (0), + myEditObjName1 (0), + myEditObjName2 (0), myLevelBox (0), - myComputeButton (0), - myInteList (0), - myShapeList (0) + myComputeButton1 (0), + myComputeButton2 (0), + myInteList1 (0), + myShapeList1 (0), + myInteList2 (0), + myShapeList2 (0), + myCurrConstrId (-1) { SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_CHECK_SELF_INTERSECTIONS"))); QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT"))); + QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_FAST_CHECK_INTERSECTIONS"))); setWindowTitle(tr("GEOM_CHECK_SELF_INTERSECTIONS")); /***************************************************************/ - mainFrame()->GroupConstructors->setTitle(tr("GEOM_CHECK_SELF_INTERSECTIONS")); + mainFrame()->GroupConstructors->setTitle(tr("GEOM_CHECK_INTERSECT_TYPE")); mainFrame()->RadioButton1->setIcon(image0); - mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose ); - mainFrame()->RadioButton2->close(); + mainFrame()->RadioButton2->setIcon(image2);; mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose ); mainFrame()->RadioButton3->close(); - QGroupBox *aGrp = new QGroupBox(tr("GEOM_CHECK_INFOS")); - QLabel *anObjLbl = new QLabel(tr("GEOM_OBJECT")); - QLabel *anInteLbl = new QLabel(tr("GEOM_CHECK_INTE_INTERSECTIONS")); - QLabel *aShapeLbl = new QLabel(tr("GEOM_CHECK_INTE_SUBSHAPES")); - QLabel *aLevelLbl = new QLabel(tr("GEOM_CHECK_INTE_CHECK_LEVEL")); - QLabel *aSummaryLbl = new QLabel(tr("GEOM_CHECK_INTE_SUMMARY")); + /***************************************************************/ + /* SIMPLE SELF-INTERSECTION constructor + /***************************************************************/ + mySimpleGrp = new QGroupBox(tr("GEOM_CHECK_INFOS")); + QLabel *anObjLbl = new QLabel(tr("GEOM_OBJECT")); + QLabel *anInteLbl = new QLabel(tr("GEOM_CHECK_INTE_INTERSECTIONS")); + QLabel *aShapeLbl = new QLabel(tr("GEOM_CHECK_INTE_SUBSHAPES")); + QLabel *aLevelLbl = new QLabel(tr("GEOM_CHECK_INTE_CHECK_LEVEL")); + QLabel *aSummaryLbl1 = new QLabel(tr("GEOM_CHECK_INTE_SUMMARY")); QFont aFont (TEXTEDIT_FONT_FAMILY, TEXTEDIT_FONT_SIZE); aFont.setStyleHint(QFont::TypeWriter, QFont::PreferAntialias); - myTextView = new QTextBrowser; - myTextView->setReadOnly(true); - myTextView->setFont(aFont); + myTextView1 = new QTextBrowser; + myTextView1->setReadOnly(true); + myTextView1->setFont(aFont); - mySelButton = new QPushButton; - mySelButton->setIcon(image1); - mySelButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + mySelButton1 = new QPushButton; + mySelButton1->setIcon(image1); + mySelButton1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - myEditObjName = new QLineEdit; - myEditObjName->setReadOnly(true); + myEditObjName1 = new QLineEdit; + myEditObjName1->setReadOnly(true); myLevelBox = new QComboBox; - myComputeButton = new QPushButton(tr("GEOM_CHECK_INTE_COMPUTE")); + myComputeButton1 = new QPushButton(tr("GEOM_CHECK_INTE_COMPUTE")); - myInteList = new QListWidget; - myInteList->setSelectionMode(QAbstractItemView::ExtendedSelection); - myShapeList = new QListWidget; - myShapeList->setSelectionMode(QAbstractItemView::ExtendedSelection); + myInteList1 = new QListWidget; + myInteList1->setSelectionMode(QAbstractItemView::ExtendedSelection); + myShapeList1 = new QListWidget; + myShapeList1->setSelectionMode(QAbstractItemView::ExtendedSelection); - QGridLayout *aGrpLayout = new QGridLayout(aGrp); + QGridLayout *aGrpLayout1 = new QGridLayout(mySimpleGrp); - aGrpLayout->setMargin(9); - aGrpLayout->setSpacing(6); - aGrpLayout->addWidget(anObjLbl, 0, 0); - aGrpLayout->addWidget(anInteLbl, 5, 0); - aGrpLayout->addWidget(aShapeLbl, 5, 2); - aGrpLayout->addWidget(aLevelLbl, 1, 0); - aGrpLayout->addWidget(myLevelBox, 1, 1, 1, 2); - aGrpLayout->addWidget(myComputeButton, 2, 0, 1, 3); - aGrpLayout->addWidget(aSummaryLbl, 3, 0); - aGrpLayout->addWidget(myTextView, 4, 0, 1, 3); - aGrpLayout->addWidget(mySelButton, 0, 1); - aGrpLayout->addWidget(myEditObjName, 0, 2); - aGrpLayout->addWidget(myInteList, 6, 0, 1, 2); - aGrpLayout->addWidget(myShapeList, 6, 2); - - QVBoxLayout* layout = new QVBoxLayout (centralWidget()); - layout->setMargin(0); layout->setSpacing(6); - layout->addWidget(aGrp); + aGrpLayout1->setMargin(9); + aGrpLayout1->setSpacing(6); + aGrpLayout1->addWidget(anObjLbl, 0, 0); + aGrpLayout1->addWidget(mySelButton1, 0, 1); + aGrpLayout1->addWidget(myEditObjName1, 0, 2); + aGrpLayout1->addWidget(aLevelLbl, 1, 0); + aGrpLayout1->addWidget(myLevelBox, 1, 1, 1, 2); + aGrpLayout1->addWidget(myComputeButton1, 2, 0, 1, 3); + aGrpLayout1->addWidget(aSummaryLbl1, 3, 0); + aGrpLayout1->addWidget(myTextView1, 4, 0, 1, 3); + aGrpLayout1->addWidget(anInteLbl, 5, 0); + aGrpLayout1->addWidget(aShapeLbl, 5, 2); + aGrpLayout1->addWidget(myInteList1, 6, 0, 1, 2); + aGrpLayout1->addWidget(myShapeList1, 6, 2); /***************************************************************/ + /* FAST SELF-INTERSECTION constructor + /***************************************************************/ + + myFastGrp = new QGroupBox(tr("GEOM_CHECK_INFOS"), centralWidget()); + QLabel *anObjLbl2 = new QLabel(tr("GEOM_OBJECT"), myFastGrp); + QLabel *aDeflectLbl = new QLabel(tr("GEOM_CHECK_INT_DEFLECT"), myFastGrp); + QLabel *aSummaryLbl2 = new QLabel(tr("GEOM_CHECK_INTE_SUMMARY")); + QLabel *anInteLbl2 = new QLabel(tr("GEOM_CHECK_INTE_INTERSECTIONS"), myFastGrp); + QLabel *aShapeLbl2 = new QLabel(tr("GEOM_CHECK_INTE_SUBSHAPES"), myFastGrp); + + mySelButton2 = new QPushButton(myFastGrp); + mySelButton2->setIcon(image1); + mySelButton2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + myEditObjName2 = new QLineEdit(myFastGrp); + myEditObjName2->setReadOnly(true); + + myDeflection = new SalomeApp_DoubleSpinBox(myFastGrp); + myDetGaps = new QCheckBox(tr( "GEOM_CHECK_INT_DETECT_GAPS" )); + myTolerance = new SalomeApp_DoubleSpinBox(myFastGrp); + + myComputeButton2 = new QPushButton(tr("GEOM_CHECK_INTE_COMPUTE")); + + myTextView2 = new QTextBrowser; + myTextView2->setReadOnly(true); + myTextView2->setFont(aFont); + + myInteList2 = new QListWidget(myFastGrp); + myInteList2->setSelectionMode(QAbstractItemView::ExtendedSelection); + myShapeList2 = new QListWidget(myFastGrp); + myShapeList2->setSelectionMode(QAbstractItemView::ExtendedSelection); + + QGridLayout *aGrpLayout2 = new QGridLayout(myFastGrp); + aGrpLayout2->setMargin(9); + aGrpLayout2->setSpacing(6); + aGrpLayout2->addWidget(anObjLbl2, 0, 0); + aGrpLayout2->addWidget(mySelButton2, 0, 1); + aGrpLayout2->addWidget(myEditObjName2, 0, 2); + aGrpLayout2->addWidget(aDeflectLbl, 1, 0); + aGrpLayout2->addWidget(myDeflection, 1, 1, 1, 2); + aGrpLayout2->addWidget(myDetGaps, 2, 0); + aGrpLayout2->addWidget(myTolerance, 2, 1, 1, 2); + aGrpLayout2->addWidget(myComputeButton2, 3, 0, 1, 3); + aGrpLayout2->addWidget(aSummaryLbl2, 4, 0); + aGrpLayout2->addWidget(myTextView2, 5, 0, 1, 3); + aGrpLayout2->addWidget(anInteLbl2, 6, 0); + aGrpLayout2->addWidget(aShapeLbl2, 6, 1, 1, 2); + aGrpLayout2->addWidget(myInteList2, 7, 0); + aGrpLayout2->addWidget(myShapeList2, 7, 1, 1, 2); + + /***************************************************************/ + + QVBoxLayout* layout2 = new QVBoxLayout (centralWidget()); + layout2->setMargin(0); layout2->setSpacing(6); + layout2->addWidget(mySimpleGrp); + layout2->addWidget(myFastGrp); + + /***************************************************************/ myHelpFileName = "check_self_intersections_page.html"; @@ -161,32 +226,65 @@ void MeasureGUI_CheckSelfIntersectionsDlg::Init() myLevelBox->insertItem(GEOM::SI_E_F, tr("GEOM_CHECK_INTE_E_F")); myLevelBox->insertItem(GEOM::SI_ALL, tr("GEOM_CHECK_INTE_ALL")); myLevelBox->setCurrentIndex(GEOM::SI_ALL); + myComputeButton1->setEnabled(false); + connect(mySelButton1, SIGNAL(clicked()), + this, SLOT(SetEditCurrentArgument())); + connect(myInteList1, SIGNAL(itemSelectionChanged()), + SLOT(onInteListSelectionChanged())); + connect(myShapeList1, SIGNAL(itemSelectionChanged()), + SLOT(onSubShapesListSelectionChanged())); + connect(myLevelBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(clear())); + connect(myComputeButton1, SIGNAL(clicked()), this, SLOT(onCompute())); + + /***************************************************************/ + myObj2.nullify(); + myEditObjName2->setText(""); + myEditObjName2->setEnabled(true); + + myDetGaps->setChecked(false); + initSpinBox(myTolerance, 0, MAX_NUMBER, 1); + myTolerance->setValue(0); + myTolerance->setEnabled(false); + myComputeButton2->setEnabled(false); + + // Obtain deflection from preferences + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + initSpinBox(myDeflection, 1e-3, 1.0, 1e-3); + myDeflection->setValue(qMax(1e-3, resMgr->doubleValue("Geometry", "deflection_coeff", 1e-3))); + + connect( mySelButton2, SIGNAL(clicked()), + this, SLOT(SetEditCurrentArgument())); + connect( myDetGaps, SIGNAL(toggled(bool)), this, SLOT(OnGaps(bool))); + connect( myTolerance, SIGNAL(valueChanged(double)), this, SLOT(clear())); + connect( myDeflection, SIGNAL(valueChanged(double)), this, SLOT(clear())); + connect( myInteList2, SIGNAL(itemSelectionChanged()), + SLOT(onInteListSelectionChanged())); + connect( myShapeList2, SIGNAL(itemSelectionChanged()), + SLOT(onSubShapesListSelectionChanged())); + connect( myComputeButton2, SIGNAL(clicked()), this, SLOT(onCompute())); + + /***************************************************************/ + + connect(this, SIGNAL(constructorsClicked(int)), + this, SLOT(ConstructorsClicked(int))); 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(mySelButton, SIGNAL(clicked()), - this, SLOT(SetEditCurrentArgument())); - connect(myInteList, SIGNAL(itemSelectionChanged()), - SLOT(onInteListSelectionChanged())); - connect(myShapeList, SIGNAL(itemSelectionChanged()), - SLOT(onSubShapesListSelectionChanged())); - connect(myLevelBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(clear())); - connect(myComputeButton, SIGNAL(clicked()), this, SLOT(onCompute())); - LightApp_SelectionMgr* aSel = myGeomGUI->getApp()->selectionMgr(); - connect(aSel, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); initName( tr( "GEOM_SELF_INTERSECTION_NAME") ); buttonOk()->setEnabled(false); buttonApply()->setEnabled(false); - myComputeButton->setEnabled(false); + + ConstructorsClicked(0); + activateSelection(); SelectionIntoArgument(); } @@ -197,20 +295,56 @@ void MeasureGUI_CheckSelfIntersectionsDlg::Init() //================================================================================= void MeasureGUI_CheckSelfIntersectionsDlg::clear() { - myTextView->setText(""); + getTextView()->setText(""); + getComputeButton()->setEnabled(true); - myInteList->blockSignals(true); - myShapeList->blockSignals(true); - myInteList->clear(); - myShapeList->clear(); - myInteList->blockSignals(false); - myShapeList->blockSignals(false); + getInteList()->blockSignals(true); + getShapeList()->blockSignals(true); + getInteList()->clear(); + getShapeList()->clear(); + getInteList()->blockSignals(false); + getShapeList()->blockSignals(false); erasePreview(); - buttonOk()->setEnabled(false); buttonApply()->setEnabled(false); - myComputeButton->setEnabled(true); +} + +//================================================================================= +// function : ConstructorsClicked() +// purpose : Radio button management +//================================================================================= +void MeasureGUI_CheckSelfIntersectionsDlg::ConstructorsClicked(int constructorId) +{ + if (myCurrConstrId == constructorId) + return; + + disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); + + switch (constructorId) { + case 0: + mySimpleGrp->show(); + myFastGrp->hide(); + break; + case 1: + mySimpleGrp->hide(); + myFastGrp->show(); + break; + } + + myCurrConstrId = constructorId; + + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + + qApp->processEvents(); + updateGeometry(); + resize(minimumSizeHint()); + + processPreview(); + //updateButtonState(); + activateSelection(); + SelectionIntoArgument(); } //================================================================================= @@ -223,7 +357,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute() QString anErrMsg(""); if (!findSelfIntersections(hasSelfInte, anErrMsg)) { - myTextView->setText(anErrMsg); + getTextView()->setText(anErrMsg); return; } @@ -243,12 +377,12 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute() aMsg += anErrMsg; } - myTextView->setText(aMsg); + getTextView()->setText(aMsg); // Pairs QStringList anInteList; QString anInteStr (""); - int nbPairs = myInters->length()/2; + int nbPairs = getInters()->length()/2; for (int i = 1; i <= nbPairs; i++) { anInteStr = "Intersection # "; @@ -256,8 +390,8 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onCompute() anInteList.append(anInteStr); } - myInteList->addItems(anInteList); - myComputeButton->setEnabled(false); + getInteList()->addItems(anInteList); + getComputeButton()->setEnabled(false); } //================================================================================= @@ -291,7 +425,23 @@ void MeasureGUI_CheckSelfIntersectionsDlg::DeactivateActiveDialog() //================================================================================= void MeasureGUI_CheckSelfIntersectionsDlg::activateSelection() { - globalSelection(GEOM_ALLSHAPES); + switch (getConstructorId()) { + case 0: + globalSelection(GEOM_ALLSHAPES); + break; + case 1: + TColStd_MapOfInteger aTypes; + aTypes.Add(GEOM_COMPOUND ); + aTypes.Add(GEOM_SOLID ); + aTypes.Add(GEOM_SHELL); + aTypes.Add(GEOM_FACE); + globalSelection(aTypes); + + std::list needTypes; + needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ), needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPOUND ); + localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + break; + } } //================================================================================= @@ -313,7 +463,11 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::ClickOnApply() if ( !onAccept() ) return false; + clear(); initName(); + + ConstructorsClicked(getConstructorId()); + return true; } @@ -341,7 +495,7 @@ GEOM::GEOM_IOperations_ptr MeasureGUI_CheckSelfIntersectionsDlg::createOperation //================================================================================= bool MeasureGUI_CheckSelfIntersectionsDlg::isValid( QString& ) { - return !myObj->_is_nil(); + return !getObj().isNull(); } //================================================================================= @@ -350,37 +504,51 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::isValid( QString& ) //================================================================================= void MeasureGUI_CheckSelfIntersectionsDlg::SetEditCurrentArgument() { - myEditObjName->setFocus(); + getEditObjName()->setFocus(); SelectionIntoArgument(); } +//================================================================================= +// function : OnGaps() +// purpose : +//================================================================================= +void MeasureGUI_CheckSelfIntersectionsDlg::OnGaps(bool checked) +{ + clear(); + myTolerance->setEnabled(checked); +} //================================================================================= // function : SelectionIntoArgument // purpose : //================================================================================= void MeasureGUI_CheckSelfIntersectionsDlg::SelectionIntoArgument() { + QList typesLst; + + if ( getConstructorId() == 0 ) { + typesLst << TopAbs_COMPOUND + << TopAbs_COMPSOLID + << TopAbs_SOLID + << TopAbs_SHELL + << TopAbs_FACE + << TopAbs_WIRE + << TopAbs_EDGE + << TopAbs_VERTEX + << TopAbs_SHAPE; + } else { + typesLst << TopAbs_FACE + << TopAbs_SHELL + << TopAbs_SOLID + << TopAbs_COMPOUND; + } + // Clear the dialog. clear(); - myObj = GEOM::GEOM_Object::_nil(); - LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); - SALOME_ListIO aSelList; - aSelMgr->selectedObjects(aSelList); + GEOM::GeomObjPtr aSelectedObject = getSelected( typesLst ); - GEOM::GEOM_Object_var aSelectedObject = GEOM::GEOM_Object::_nil(); - - if (aSelList.Extent() > 0) { - aSelectedObject = GEOMBase::ConvertIOinGEOMObject( aSelList.First() ); - } - - if (aSelectedObject->_is_nil()) { - myEditObjName->setText(""); - return; - } - - myObj = aSelectedObject; - myEditObjName->setText(GEOMBase::GetName(myObj)); + (getConstructorId() == 0 ? myObj1 :myObj2) = aSelectedObject; + getEditObjName()->setText(getObj() ? GEOMBase::GetName(getObj().get()) : ""); } //================================================================================= @@ -400,7 +568,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::enterEvent(QEvent *) bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections (bool &HasSelfInte, QString &theErrMsg) { - if (myObj->_is_nil()) { + if (getObj()->_is_nil()) { return false; } @@ -413,10 +581,14 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections SUIT_OverrideCursor wc; try { - HasSelfInte = !anOper->CheckSelfIntersections(myObj, aLevel, myInters); - nbPairs = myInters->length()/2; + if ( getConstructorId() == 0 ) { + HasSelfInte = !anOper->CheckSelfIntersections(myObj1.get(), aLevel, myInters1); + } else { + HasSelfInte = !anOper->CheckSelfIntersectionsFast(myObj2.get(), getDeflection(), getTolerance(), myInters2); + } + nbPairs = getInters()->length()/2; - if (nbPairs*2 != myInters->length()) { + if (nbPairs*2 != getInters()->length()) { isOK = false; } } @@ -426,7 +598,7 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections } if (!anOper->IsDone()) { - if (myInters->length() == 0) { + if (getInters()->length() == 0) { theErrMsg = tr(anOper->GetErrorCode()); isOK = false; } else { @@ -447,24 +619,24 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::findSelfIntersections void MeasureGUI_CheckSelfIntersectionsDlg::onInteListSelectionChanged() { erasePreview(); - myShapeList->clear(); + getShapeList()->clear(); TopoDS_Shape aSelShape; - if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) { + if (!getObj()->_is_nil() && GEOMBase::GetShape(getObj().get(), aSelShape)) { TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(aSelShape, anIndices); - int nbSelected = myInteList->selectedItems().size(); + int nbSelected = getInteList()->selectedItems().size(); - for (int i = 0; i < myInteList->count(); i++) { - if ( myInteList->item(i)->isSelected() ) { + for (int i = 0; i < getInteList()->count(); i++) { + if ( getInteList()->item(i)->isSelected() ) { if ( nbSelected > 1 ) - myShapeList->addItem(QString("--- #%1 ---").arg(i+1)); + getShapeList()->addItem(QString("--- #%1 ---").arg(i+1)); for (int j = 0; j < 2; j++) { - TopoDS_Shape aSubShape = anIndices.FindKey(myInters[i*2+j]); + TopoDS_Shape aSubShape = anIndices.FindKey(getInters()[i*2+j]); QString aType = GEOMBase::GetShapeTypeString(aSubShape); - myShapeList->addItem(QString("%1_%2").arg(aType).arg(myInters[i*2+j])); - myShapeList->item(myShapeList->count()-1)->setData(Qt::UserRole, myInters[i*2+j]); + getShapeList()->addItem(QString("%1_%2").arg(aType).arg(getInters()[i*2+j])); + getShapeList()->item(getShapeList()->count()-1)->setData(Qt::UserRole, getInters()[i*2+j]); } } } @@ -480,7 +652,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged() erasePreview(); // Selected IDs - QList selected = myShapeList->selectedItems(); + QList selected = getShapeList()->selectedItems(); QList aIds; foreach(QListWidgetItem* item, selected) { int idx = item->data(Qt::UserRole).toInt(); @@ -492,7 +664,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged() TopoDS_Shape aSelShape; TopoDS_Shape aSubShape; TopTools_IndexedMapOfShape anIndices; - if (!myObj->_is_nil() && GEOMBase::GetShape(myObj, aSelShape)) { + if (!getObj()->_is_nil() && GEOMBase::GetShape(getObj().get(), aSelShape)) { TopExp::MapShapes(aSelShape, anIndices); getDisplayer()->SetColor(Quantity_NOC_RED); getDisplayer()->SetWidth(3); @@ -500,11 +672,11 @@ void MeasureGUI_CheckSelfIntersectionsDlg::onSubShapesListSelectionChanged() foreach(int idx, aIds) { aSubShape = anIndices.FindKey(idx); try { - SALOME_Prs* aPrs = !aSubShape.IsNull() ? getDisplayer()->BuildPrs(aSubShape) : 0; - if (aPrs) displayPreview(aPrs, true); + SALOME_Prs* aPrs = !aSubShape.IsNull() ? getDisplayer()->BuildPrs(aSubShape) : 0; + if (aPrs) displayPreview(aPrs, true); } catch (const SALOME::SALOME_Exception& e) { - SalomeApp_Tools::QtCatchCorbaException(e); + SalomeApp_Tools::QtCatchCorbaException(e); } } } @@ -526,15 +698,15 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects) TColStd_IndexedMapOfInteger aMapIndex; QList pairs; - int nbSelected = myInteList->selectedItems().size(); + int nbSelected = getInteList()->selectedItems().size(); // Collect the map of indices - for (int i = 0; i < myInteList->count(); i++) { - if ( nbSelected < 1 || myInteList->item(i)->isSelected() ) { - aMapIndex.Add(myInters[i*2]); - aMapIndex.Add(myInters[i*2 + 1]); - pairs << myInters[i*2]; - pairs << myInters[i*2 + 1]; + for (int i = 0; i < getInteList()->count(); i++) { + if ( nbSelected < 1 || getInteList()->item(i)->isSelected() ) { + aMapIndex.Add(getInters()[i*2]); + aMapIndex.Add(getInters()[i*2 + 1]); + pairs << getInters()[i*2]; + pairs << getInters()[i*2 + 1]; } } @@ -547,7 +719,7 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects) for (int i = 1; i <= aMapIndex.Extent(); i++) anArray[i-1] = aMapIndex.FindKey(i); - GEOM::ListOfGO_var aList = shapesOper->MakeSubShapes(myObj, anArray); + GEOM::ListOfGO_var aList = shapesOper->MakeSubShapes(getObj().get(), anArray); // Make compounds for (int i = 0; i < pairs.count()/2; i++) { @@ -562,6 +734,27 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects) return true; } +//================================================================================= +// function : getDeflection +// purpose : +//================================================================================= +float MeasureGUI_CheckSelfIntersectionsDlg::getDeflection() +{ + return (float)myDeflection->value(); +} + +//================================================================================= +// function : getTolerance +// purpose : +//================================================================================= +double MeasureGUI_CheckSelfIntersectionsDlg::getTolerance() +{ + double aVal = myTolerance->value(); + if (!myDetGaps->isChecked() || aVal < 0.0) + return 0.0; + return aVal; +} + //================================================================ // Function : getFather // Purpose : Get father object for object to be added in study @@ -570,5 +763,54 @@ bool MeasureGUI_CheckSelfIntersectionsDlg::execute(ObjectList& objects) GEOM::GEOM_Object_ptr MeasureGUI_CheckSelfIntersectionsDlg::getFather (GEOM::GEOM_Object_ptr) { - return myObj; + return getObj().get(); +} + +//================================================================================= +// function : getSourceObjects +// purpose : virtual method to get source objects +//================================================================================= +QList MeasureGUI_CheckSelfIntersectionsDlg::getSourceObjects() +{ + QList res; + res << getObj(); + return res; +} + +//================================================================================= +// GETTERS +//================================================================================= +QTextBrowser* MeasureGUI_CheckSelfIntersectionsDlg::getTextView() +{ + return ( getConstructorId() == 0 ? myTextView1 : myTextView2 ); +} + +QListWidget* MeasureGUI_CheckSelfIntersectionsDlg::getInteList() +{ + return ( getConstructorId() == 0 ? myInteList1 : myInteList2 ); +} + +QListWidget* MeasureGUI_CheckSelfIntersectionsDlg::getShapeList() +{ + return ( getConstructorId() == 0 ? myShapeList1 : myShapeList2 ); +} + +QPushButton* MeasureGUI_CheckSelfIntersectionsDlg::getComputeButton() +{ + return ( getConstructorId() == 0 ? myComputeButton1 : myComputeButton2 ); +} + +QLineEdit* MeasureGUI_CheckSelfIntersectionsDlg::getEditObjName() +{ + return ( getConstructorId() == 0 ? myEditObjName1 : myEditObjName2 ); +} + +GEOM::GeomObjPtr MeasureGUI_CheckSelfIntersectionsDlg::getObj() +{ + return ( getConstructorId() == 0 ? myObj1 : myObj2 ); +} + +GEOM::ListOfLong_var MeasureGUI_CheckSelfIntersectionsDlg::getInters() +{ + return ( getConstructorId() == 0 ? myInters1 : myInters2 ); } diff --git a/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.h b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.h index f05dd8109..ac0f2d935 100644 --- a/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.h +++ b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.h @@ -54,6 +54,7 @@ protected: virtual bool execute(ObjectList &); virtual bool extractPrefix() const; virtual GEOM::GEOM_Object_ptr getFather (GEOM::GEOM_Object_ptr); + virtual QList getSourceObjects(); private slots: @@ -67,6 +68,9 @@ private slots: void DeactivateActiveDialog(); void SelectionIntoArgument(); void SetEditCurrentArgument(); + void ConstructorsClicked (int); + void OnGaps(bool); + private: @@ -76,18 +80,46 @@ private: bool findSelfIntersections (bool &HasSelfInte, QString &theErrMsg); + float getDeflection(); + double getTolerance(); + +// Getters + QTextBrowser* getTextView(); + QListWidget* getInteList(); + QListWidget* getShapeList(); + QPushButton* getComputeButton(); + QLineEdit* getEditObjName(); + GEOM::GeomObjPtr getObj(); + GEOM::ListOfLong_var getInters(); + private: - - QTextBrowser *myTextView; - QPushButton *mySelButton; - QLineEdit *myEditObjName; + int myCurrConstrId; + // simple + QPushButton *myComputeButton1; + QGroupBox *mySimpleGrp; + QTextBrowser *myTextView1; + QPushButton *mySelButton1; + QLineEdit *myEditObjName1; QComboBox *myLevelBox; - QPushButton *myComputeButton; - QListWidget *myInteList; - QListWidget *myShapeList; - GEOM::GEOM_Object_var myObj; - GEOM::ListOfLong_var myInters; + QListWidget *myInteList1; + QListWidget *myShapeList1; + GEOM::GeomObjPtr myObj1; + GEOM::ListOfLong_var myInters1; + // fast + QPushButton *myComputeButton2; + QGroupBox *myFastGrp; + QTextBrowser *myTextView2; + QPushButton *mySelButton2; + QLineEdit *myEditObjName2; + QCheckBox *myDetGaps; + SalomeApp_DoubleSpinBox *myTolerance; + SalomeApp_DoubleSpinBox *myDeflection; + QListWidget *myInteList2; + QListWidget *myShapeList2; + GEOM::GeomObjPtr myObj2; + GEOM::ListOfLong_var myInters2; + GEOM::GEOM_IShapesOperations_var myShapesOper; }; #endif // MEASUREGUI_CHECKSELFINTERDLG_H From fe74d236e05f37685de15cf5c2420a1e0ffea78d Mon Sep 17 00:00:00 2001 From: mnt Date: Mon, 8 Jun 2015 10:17:23 +0300 Subject: [PATCH 12/54] Fix pb with make test on OCCT 6.9.0 --- doc/salome/examples/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/salome/examples/CMakeLists.txt b/doc/salome/examples/CMakeLists.txt index e9dc70f96..afd0a3a6a 100644 --- a/doc/salome/examples/CMakeLists.txt +++ b/doc/salome/examples/CMakeLists.txt @@ -56,7 +56,6 @@ SET(GOOD_TESTS center_of_mass.py check_compound_of_blocks.py check_self_intersections.py - check_self_intersections_fast.py check_shape.py complex_objs_ex01.py complex_objs_ex02.py @@ -69,6 +68,7 @@ SET(GOOD_TESTS complex_objs_ex09.py complex_objs_ex10.py complex_objs_ex11.py + fast_intersection.py free_boundaries.py free_faces.py GEOM_box.py @@ -132,9 +132,9 @@ SET(GOOD_TESTS working_with_groups_ex05.py working_with_groups_ex06.py ) -IF(CAS_VERSION_STR VERSION_GREATER "6.8.0") +IF(CAS_VERSION_STR VERSION_GREATER "6.9.0") LIST(APPEND GOOD_TESTS - fast_intersection.py + check_self_intersections_fast.py ) ENDIF() From ce07ba70beb68cd740469c399212bb03dc1e5b18 Mon Sep 17 00:00:00 2001 From: skv Date: Mon, 8 Jun 2015 13:06:39 +0300 Subject: [PATCH 13/54] 0022776: [CEA 1269] Project a wire or a face on a cylinder: add rotation angle --- .../gui/GEOM/images/proj_on_cyl_angles.png | Bin 0 -> 14235 bytes .../gui/GEOM/images/proj_on_cyl_dlg.png | Bin 25225 -> 27219 bytes .../projection_on_cylinder_operation.doc | 12 ++- idl/GEOM_Gen.idl | 6 +- src/GEOMGUI/GEOM_msg_en.ts | 4 + src/GEOMImpl/GEOMImpl_IProjOnCyl.hxx | 21 +++-- .../GEOMImpl_ITransformOperations.cxx | 18 ++-- .../GEOMImpl_ITransformOperations.hxx | 3 +- src/GEOMImpl/GEOMImpl_ProjectionDriver.cxx | 81 ++++++++++++++---- src/GEOMImpl/GEOMImpl_ProjectionDriver.hxx | 3 +- src/GEOM_I/GEOM_ITransformOperations_i.cc | 5 +- src/GEOM_I/GEOM_ITransformOperations_i.hh | 3 +- src/GEOM_SWIG/geomBuilder.py | 20 ++++- .../TransformationGUI_ProjectionOnCylDlg.cxx | 19 +++- .../TransformationGUI_ProjectionOnCylDlg.h | 1 + 15 files changed, 147 insertions(+), 49 deletions(-) create mode 100644 doc/salome/gui/GEOM/images/proj_on_cyl_angles.png diff --git a/doc/salome/gui/GEOM/images/proj_on_cyl_angles.png b/doc/salome/gui/GEOM/images/proj_on_cyl_angles.png new file mode 100644 index 0000000000000000000000000000000000000000..0d36e4e381af19ad4bc4c5ef71bf0b310b2c48c9 GIT binary patch literal 14235 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 F{{v+YC}#iw literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GEOM/images/proj_on_cyl_dlg.png b/doc/salome/gui/GEOM/images/proj_on_cyl_dlg.png index 38d81b51e0461caac799cb46997592cb84b20fa2..7ce80c1e897a60b40a0bbb02acbd830a3d34a59a 100644 GIT binary patch literal 27219 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 angle where the total length of the wire should be projected. If it is unchecked the projection is not scaled and the natural wire length is kept for the projection. +- Rotation angle the desired angle between the tangent vector to +the first curve at the first point of the theObject's projection in 2D space +and U-direction of cylinder's 2D space. - \ref restore_presentation_parameters_page "Advanced options". \image html proj_on_cyl_dlg.png +\n The following figure explains meaning of each input angle: + +\image html proj_on_cyl_angles.png "Input angles of projection on the cylinder" + \n Example: \image html proj_on_cyl_preview.png "The curve (in red) and its projection on the cylinder" \n TUI Command: geompy.MakeProjectionOnCylinder(theObject, theRadius, -theStartAngle=0.0, theAngleLength=-1.0), +theStartAngle=0.0, theAngleLength=-1.0, theAngleRotation=0.0), where \em theObject is a shape to be projected, \em theRadius is a cylinder radius, \em theStartAngle is the starting angle of projection in -radians, \em theAngleLength the projection length angle in radians. +radians, \em theAngleLength the projection length angle in radians, +\em theAngleRotation projection rotation angle in radians. The \em Result will be a \em GEOM_Object. Our TUI Scripts provide you with useful examples of the use of diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 88edc8f07..c301b79ae 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -1439,13 +1439,17 @@ module GEOM * to project the total length of the wire. If it is negative the * projection is not scaled and natural wire length is kept for * the projection. + * \param theAngleRotation the desired angle between the tangent vector + * to the first curve at the first point of the theObject's + * projection in 2D space and U-direction of cylinder's 2D space. * \return A wire or a face or a compound of faces that represents a * projection of the source shape onto a cylinder. */ GEOM_Object MakeProjectionOnCylinder (in GEOM_Object theObject, in double theRadius, in double theStartAngle, - in double theAngleLength); + in double theAngleLength, + in double theAngleRotation); }; /*! diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 9d86a99db..9bed663c4 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -7572,5 +7572,9 @@ Do you want to create new material? GEOM_PROJ_ON_CYL_LENGTH_ANGLE Length angle + + GEOM_PROJ_ON_CYL_ROTATION_ANGLE + Rotation angle + diff --git a/src/GEOMImpl/GEOMImpl_IProjOnCyl.hxx b/src/GEOMImpl/GEOMImpl_IProjOnCyl.hxx index a5162534e..8e0dd2bb5 100644 --- a/src/GEOMImpl/GEOMImpl_IProjOnCyl.hxx +++ b/src/GEOMImpl/GEOMImpl_IProjOnCyl.hxx @@ -28,6 +28,7 @@ #define PROJCYL_ARG_RADIUS 2 #define PROJCYL_ARG_START_ANGLE 3 #define PROJCYL_ARG_ANGLE_LENGTH 4 +#define PROJCYL_ARG_ANGLE_ROTATION 5 class GEOMImpl_IProjOnCyl { @@ -36,14 +37,16 @@ public: GEOMImpl_IProjOnCyl(Handle(GEOM_Function) theFunction): _func(theFunction) {} - void SetShape (const Handle(GEOM_Function) &theShape) - { _func->SetReference(PROJCYL_ARG_SHAPE, theShape); } - void SetRadius (const Standard_Real theRadius) - { _func->SetReal(PROJCYL_ARG_RADIUS, theRadius); } - void SetStartAngle (const Standard_Real theStartAngle) - { _func->SetReal(PROJCYL_ARG_START_ANGLE, theStartAngle); } - void SetAngleLength (const Standard_Real theAngleLength) - { _func->SetReal(PROJCYL_ARG_ANGLE_LENGTH, theAngleLength); } + void SetShape (const Handle(GEOM_Function) &theShape) + { _func->SetReference(PROJCYL_ARG_SHAPE, theShape); } + void SetRadius (const Standard_Real theRadius) + { _func->SetReal(PROJCYL_ARG_RADIUS, theRadius); } + void SetStartAngle (const Standard_Real theStartAngle) + { _func->SetReal(PROJCYL_ARG_START_ANGLE, theStartAngle); } + void SetAngleLength (const Standard_Real theAngleLength) + { _func->SetReal(PROJCYL_ARG_ANGLE_LENGTH, theAngleLength); } + void SetAngleRotation (const Standard_Real theAngleLength) + { _func->SetReal(PROJCYL_ARG_ANGLE_ROTATION, theAngleLength); } Handle(GEOM_Function) GetShape() { return _func->GetReference(PROJCYL_ARG_SHAPE); } @@ -53,6 +56,8 @@ public: { return _func->GetReal(PROJCYL_ARG_START_ANGLE ); } Standard_Real GetAngleLength() { return _func->GetReal(PROJCYL_ARG_ANGLE_LENGTH ); } + Standard_Real GetAngleRotation() + { return _func->GetReal(PROJCYL_ARG_ANGLE_ROTATION ); } private: diff --git a/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx b/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx index 0373f9b05..6cc201000 100644 --- a/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_ITransformOperations.cxx @@ -2278,7 +2278,8 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::MakeProjectionOnCylinder (const Handle(GEOM_Object) &theObject, const Standard_Real theRadius, const Standard_Real theStartAngle, - const Standard_Real theAngleLength) + const Standard_Real theAngleLength, + const Standard_Real theAngleRotation) { SetErrorCode(KO); @@ -2312,6 +2313,7 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::MakeProjectionOnCylinder aProj.SetRadius(theRadius); aProj.SetStartAngle(theStartAngle); aProj.SetAngleLength(theAngleLength); + aProj.SetAngleRotation(theAngleRotation); //Compute the Projection try { @@ -2328,16 +2330,10 @@ Handle(GEOM_Object) GEOMImpl_ITransformOperations::MakeProjectionOnCylinder } //Make a Python command - GEOM::TPythonDump pd(aFunction); - - pd << aResult << " = geompy.MakeProjectionOnCylinder(" - << theObject << ", " << theRadius << ", " << theStartAngle; - - if (theAngleLength >= 0.) { - pd << ", " << theAngleLength; - } - - pd << ")"; + GEOM::TPythonDump(aFunction) + << aResult << " = geompy.MakeProjectionOnCylinder(" + << theObject << ", " << theRadius << ", " << theStartAngle + << ", " << theAngleLength << ", " << theAngleRotation << ")"; SetErrorCode(OK); diff --git a/src/GEOMImpl/GEOMImpl_ITransformOperations.hxx b/src/GEOMImpl/GEOMImpl_ITransformOperations.hxx index 155dbfdd9..3742157bf 100644 --- a/src/GEOMImpl/GEOMImpl_ITransformOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_ITransformOperations.hxx @@ -195,7 +195,8 @@ class GEOMImpl_ITransformOperations : public GEOM_IOperations (const Handle(GEOM_Object) &theObject, const Standard_Real theRadius, const Standard_Real theStartAngle, - const Standard_Real theAngleLength); + const Standard_Real theAngleLength, + const Standard_Real theAngleRotation); }; diff --git a/src/GEOMImpl/GEOMImpl_ProjectionDriver.cxx b/src/GEOMImpl/GEOMImpl_ProjectionDriver.cxx index 0c34bc8c2..db0fae349 100644 --- a/src/GEOMImpl/GEOMImpl_ProjectionDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ProjectionDriver.cxx @@ -33,6 +33,8 @@ #include #include +#include +#include #include #include #include @@ -428,10 +430,11 @@ Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) cons } // Get the face. - const TopAbs_ShapeEnum aType = aShape.ShapeType(); - const Standard_Real aRadius = aProj.GetRadius(); - const Standard_Real aStartAngle = aProj.GetStartAngle(); - const Standard_Real aLengthAngle = aProj.GetAngleLength(); + const TopAbs_ShapeEnum aType = aShape.ShapeType(); + const Standard_Real aRadius = aProj.GetRadius(); + const Standard_Real aStartAngle = aProj.GetStartAngle(); + const Standard_Real aLengthAngle = aProj.GetAngleLength(); + const Standard_Real aRotationAngle = aProj.GetAngleRotation(); if (aType != TopAbs_WIRE && aType != TopAbs_FACE) { return 0; @@ -441,8 +444,8 @@ Standard_Integer GEOMImpl_ProjectionDriver::Execute(TFunction_Logbook& log) cons return 0; } - TopoDS_Shape aProjShape = - projectOnCylinder(aShape, aRadius, aStartAngle, aLengthAngle); + TopoDS_Shape aProjShape = projectOnCylinder + (aShape, aRadius, aStartAngle, aLengthAngle, aRotationAngle); if (aProjShape.IsNull()) { return 0; @@ -504,6 +507,8 @@ GetCreationInformation(std::string& theOperationName, AddParam(theParams, "Length angle", aLengthAngle); } + AddParam(theParams, "Rotation angle", aProj.GetAngleRotation()); + break; } default: @@ -523,7 +528,8 @@ TopoDS_Shape GEOMImpl_ProjectionDriver::projectOnCylinder (const TopoDS_Shape &theShape, const Standard_Real theRadius, const Standard_Real theStartAngle, - const Standard_Real theAngleLength) const + const Standard_Real theAngleLength, + const Standard_Real theAngleRotation) const { TopoDS_Shape aResult; @@ -596,8 +602,6 @@ TopoDS_Shape GEOMImpl_ProjectionDriver::projectOnCylinder // Compute 2d translation transformation. TopoDS_Wire anOuterWire = BRepTools::OuterWire(aFace); - Standard_Real aU[2]; - Standard_Real aV[2]; BRepTools_WireExplorer aOWExp(anOuterWire, aFace); if (!aOWExp.More()) { @@ -605,21 +609,63 @@ TopoDS_Shape GEOMImpl_ProjectionDriver::projectOnCylinder return aResult; } - // Compute anisotropic transformation from a face's 2d space - // to cylinder's 2d space. - BRepTools::UVBounds(aFace, anOuterWire, aU[0], aU[1], aV[0], aV[1]); - + // Rotate 2D presentation of face. TopoDS_Vertex aFirstVertex = aOWExp.CurrentVertex(); TopoDS_Edge aFirstEdge = aOWExp.Current(); gp_Pnt aPnt = BRep_Tool::Pnt(aFirstVertex); BRepAdaptor_Curve2d anAdaptorCurve(aFirstEdge, aFace); Standard_Real aParam = BRep_Tool::Parameter(aFirstVertex, aFirstEdge, aFace); - gp_Pnt2d aPntUV = anAdaptorCurve.Value(aParam); + gp_Pnt2d aPntUV; + gp_Vec2d aVecUV; + gp_Vec2d aVecU0(1., 0); + anAdaptorCurve.D1(aParam, aPntUV, aVecUV); + + if (aVecUV.Magnitude() <= gp::Resolution()) { + return aResult; + } + + if (aFirstEdge.Orientation() == TopAbs_REVERSED) { + aVecUV.Reverse(); + } + + const Standard_Real anAngle = aVecUV.Angle(aVecU0) + theAngleRotation; + const Standard_Boolean isToRotate = Abs(anAngle) > Precision::Angular(); + gp_Trsf2d aRotTrsf; + Bnd_Box2d aUVBox; + Standard_Real aPar[2]; + + if (isToRotate) { + aRotTrsf.SetRotation(aPntUV, anAngle); + } + + for (; aOWExp.More(); aOWExp.Next()) { + TopoDS_Edge anEdge = aOWExp.Current(); + Handle(Geom2d_Curve) aCurve = + BRep_Tool::CurveOnSurface(anEdge, aFace, aPar[0], aPar[1]); + + if (aCurve.IsNull()) { + continue; + } + + if (isToRotate) { + aCurve = Handle(Geom2d_Curve)::DownCast(aCurve->Transformed(aRotTrsf)); + } + + BndLib_Add2dCurve::Add(aCurve, aPar[0], aPar[1], 0., aUVBox); + } + + Standard_Real aU[2]; + Standard_Real aV[2]; + + aUVBox.Get(aU[0], aV[0], aU[1], aV[1]); + + // Compute anisotropic transformation from a face's 2d space + // to cylinder's 2d space. GEOMUtils::Trsf2d aTrsf2d (1./theRadius, 0., theStartAngle - aU[0]/theRadius, - 0., 1., aPnt.Z() - 0.5*(aV[1] - aV[0]) - aPntUV.Y()); + 0., 1., aPnt.Z() - aPntUV.Y()); // Compute scaling trsf. const Standard_Boolean isToScale = theAngleLength >= Precision::Angular(); @@ -640,7 +686,6 @@ TopoDS_Shape GEOMImpl_ProjectionDriver::projectOnCylinder new Geom_CylindricalSurface(gp_Ax3(), theRadius); GeomAdaptor_Surface aGACyl(aCylinder); TopExp_Explorer anExp(aFace, TopAbs_WIRE); - Standard_Real aPar[2]; TopTools_ListOfShape aWires; Standard_Real aUResol = aGACyl.UResolution(Precision::Confusion()); Standard_Real aVResol = aGACyl.VResolution(Precision::Confusion()); @@ -659,6 +704,10 @@ TopoDS_Shape GEOMImpl_ProjectionDriver::projectOnCylinder continue; } + if (isToRotate) { + aCurve = Handle(Geom2d_Curve)::DownCast(aCurve->Transformed(aRotTrsf)); + } + // Transform the curve to cylinder's parametric space. GEOMUtils::Handle(HTrsfCurve2d) aTrsfCurve = new GEOMUtils::HTrsfCurve2d(aCurve, aPar[0], aPar[1], aTrsf2d); diff --git a/src/GEOMImpl/GEOMImpl_ProjectionDriver.hxx b/src/GEOMImpl/GEOMImpl_ProjectionDriver.hxx index ee703af55..47dfc4413 100644 --- a/src/GEOMImpl/GEOMImpl_ProjectionDriver.hxx +++ b/src/GEOMImpl/GEOMImpl_ProjectionDriver.hxx @@ -87,7 +87,8 @@ private: TopoDS_Shape projectOnCylinder(const TopoDS_Shape &theShape, const Standard_Real theRadius, const Standard_Real theStartAngle, - const Standard_Real theAngleLength) const; + const Standard_Real theAngleLength, + const Standard_Real theAngleRotation) const; public: diff --git a/src/GEOM_I/GEOM_ITransformOperations_i.cc b/src/GEOM_I/GEOM_ITransformOperations_i.cc index c18c87b6c..fbfe591f1 100644 --- a/src/GEOM_I/GEOM_ITransformOperations_i.cc +++ b/src/GEOM_I/GEOM_ITransformOperations_i.cc @@ -1402,7 +1402,8 @@ GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::MakeProjectionOnCylinder (GEOM::GEOM_Object_ptr theObject, CORBA::Double theRadius, CORBA::Double theStartAngle, - CORBA::Double theAngleLength) + CORBA::Double theAngleLength, + CORBA::Double theAngleRotation) { GEOM::GEOM_Object_var aGEOMObject; @@ -1418,7 +1419,7 @@ GEOM::GEOM_Object_ptr GEOM_ITransformOperations_i::MakeProjectionOnCylinder //Perform the transformation Handle(GEOM_Object) aResObject = GetOperations()->MakeProjectionOnCylinder - (anObject, theRadius, theStartAngle, theAngleLength); + (anObject, theRadius, theStartAngle, theAngleLength, theAngleRotation); if (!GetOperations()->IsDone() || aResObject.IsNull()) { return aGEOMObject._retn(); diff --git a/src/GEOM_I/GEOM_ITransformOperations_i.hh b/src/GEOM_I/GEOM_ITransformOperations_i.hh index e507c1f77..96aa0c23d 100644 --- a/src/GEOM_I/GEOM_ITransformOperations_i.hh +++ b/src/GEOM_I/GEOM_ITransformOperations_i.hh @@ -201,7 +201,8 @@ class GEOM_I_EXPORT GEOM_ITransformOperations_i : (GEOM::GEOM_Object_ptr theObject, CORBA::Double theRadius, CORBA::Double theStartAngle, - CORBA::Double theAngleLength); + CORBA::Double theAngleLength, + CORBA::Double theAngleRotation); ::GEOMImpl_ITransformOperations* GetOperations() { return (::GEOMImpl_ITransformOperations*)GetImpl(); } }; diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 982a45dc5..0a3d2c832 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -9581,6 +9581,10 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # The angle in which to project the total length of the wire. # If it is negative the projection is not scaled and natural # wire length is kept for the projection. + # @param theAngleRotation The desired angle in radians between + # the tangent vector to the first curve at the first point of + # the theObject's projection in 2D space and U-direction of + # cylinder's 2D 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. @@ -9592,6 +9596,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # @ref tui_projection "Example" def MakeProjectionOnCylinder (self, theObject, theRadius, theStartAngle=0.0, theAngleLength=-1.0, + theAngleRotation=0.0, theName=None): """ Compute a wire or a face that represents a projection of the source @@ -9608,6 +9613,10 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): to project the total length of the wire. If it is negative the projection is not scaled and natural wire length is kept for the projection. + theAngleRotation The desired angle in radians between + the tangent vector to the first curve at the first + point of the theObject's projection in 2D space and + U-direction of cylinder's 2D 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. @@ -9624,14 +9633,19 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): flagAngleLength = False if isinstance(theAngleLength,str): flagAngleLength = True - theRadius, theStartAngle, theAngleLength, Parameters = ParseParameters( - theRadius, theStartAngle, theAngleLength) + flagAngleRotation = False + if isinstance(theAngleRotation,str): + flagAngleRotation = True + theRadius, theStartAngle, theAngleLength, theAngleRotation, Parameters = ParseParameters( + theRadius, theStartAngle, theAngleLength, theAngleRotation) if flagStartAngle: theStartAngle = theStartAngle*math.pi/180. if flagAngleLength: theAngleLength = theAngleLength*math.pi/180. + if flagAngleRotation: + theAngleRotation = theAngleRotation*math.pi/180. anObj = self.TrsfOp.MakeProjectionOnCylinder(theObject, theRadius, - theStartAngle, theAngleLength) + theStartAngle, theAngleLength, theAngleRotation) RaiseIfFailed("MakeProjectionOnCylinder", self.TrsfOp) anObj.SetParameters(Parameters) self._autoPublish(anObj, theName, "projection") diff --git a/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.cxx b/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.cxx index 7c5dd6176..21125e57e 100644 --- a/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.cxx +++ b/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.cxx @@ -60,7 +60,8 @@ TransformationGUI_ProjectionOnCylDlg::TransformationGUI_ProjectionOnCylDlg myRadiusSpin (0), myStartAngleSpin (0), myUseAngleLen (0), - myAngleLenSpin (0) + myAngleLenSpin (0), + myAngleRotSpin (0) { SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr(); QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICO_DLG_PROJ_ON_CYL"))); @@ -85,6 +86,8 @@ TransformationGUI_ProjectionOnCylDlg::TransformationGUI_ProjectionOnCylDlg new QLabel(tr("GEOM_PROJ_ON_CYL_START_ANGLE"), aGrpParams); QLabel *anAngleLenLbl = new QLabel(tr("GEOM_PROJ_ON_CYL_LENGTH_ANGLE"), aGrpParams); + QLabel *anAngleRotLbl = + new QLabel(tr("GEOM_PROJ_ON_CYL_ROTATION_ANGLE"), aGrpParams); myObjectName = new QLineEdit(aGrpParams); mySelButton = new QPushButton(aGrpParams); @@ -92,6 +95,7 @@ TransformationGUI_ProjectionOnCylDlg::TransformationGUI_ProjectionOnCylDlg myStartAngleSpin = new SalomeApp_DoubleSpinBox(aGrpParams); myUseAngleLen = new QCheckBox(aGrpParams); myAngleLenSpin = new SalomeApp_DoubleSpinBox(aGrpParams); + myAngleRotSpin = new SalomeApp_DoubleSpinBox(aGrpParams); myObjectName->setReadOnly(true); mySelButton->setIcon(image1); @@ -110,6 +114,8 @@ TransformationGUI_ProjectionOnCylDlg::TransformationGUI_ProjectionOnCylDlg aParamsLayout->addWidget(myUseAngleLen, 3, 0); aParamsLayout->addWidget(anAngleLenLbl, 3, 1); aParamsLayout->addWidget(myAngleLenSpin, 3, 2, 1, 2); + aParamsLayout->addWidget(anAngleRotLbl, 4, 1); + aParamsLayout->addWidget(myAngleRotSpin, 4, 2, 1, 2); QVBoxLayout* layout = new QVBoxLayout( centralWidget() ); layout->setMargin( 0 ); layout->setSpacing( 6 ); @@ -145,14 +151,17 @@ void TransformationGUI_ProjectionOnCylDlg::Init() double aRadius = 100.0; double aStartAngle = 0.; double anAngleLen = 360.; + double aRotAngle = 0.; initSpinBox(myRadiusSpin, 0.00001, COORD_MAX, aStep, "length_precision"); initSpinBox(myStartAngleSpin, -180., 180., aSpecificStep, "angle_precision"); initSpinBox(myAngleLenSpin, 0.00001, COORD_MAX, aSpecificStep, "angle_precision"); + initSpinBox(myAngleRotSpin, -180., 180., aSpecificStep, "angle_precision"); myRadiusSpin->setValue(aRadius); myStartAngleSpin->setValue(aStartAngle); myAngleLenSpin->setValue(anAngleLen); + myAngleRotSpin->setValue(aRotAngle); myObjectName->setText(""); myUseAngleLen->setChecked(true); @@ -165,6 +174,7 @@ void TransformationGUI_ProjectionOnCylDlg::Init() connect(myRadiusSpin, SIGNAL(valueChanged(double)), this, SLOT(processPreview())); connect(myStartAngleSpin, SIGNAL(valueChanged(double)), this, SLOT(processPreview())); connect(myAngleLenSpin, SIGNAL(valueChanged(double)), this, SLOT(processPreview())); + connect(myAngleRotSpin, SIGNAL(valueChanged(double)), this, SLOT(processPreview())); connect(myUseAngleLen, SIGNAL(clicked()), this, SLOT(SetUseLengthAngle())); connect(myGeomGUI->getApp()->selectionMgr(),SIGNAL(currentSelectionChanged()), @@ -319,7 +329,8 @@ bool TransformationGUI_ProjectionOnCylDlg::isValid (QString &msg) if (!myObj->_is_nil() && myRadiusSpin->isValid(msg, !IsPreview()) && - myStartAngleSpin->isValid(msg, !IsPreview())) { + myStartAngleSpin->isValid(msg, !IsPreview()) && + myAngleRotSpin->isValid(msg, !IsPreview())) { if (myUseAngleLen->isChecked()) { // Check length angle spin. isOk = myAngleLenSpin->isValid(msg, !IsPreview()); @@ -343,6 +354,7 @@ bool TransformationGUI_ProjectionOnCylDlg::execute (ObjectList& objects) double aRadius = myRadiusSpin->value(); double aStartAngle = myStartAngleSpin->value()*M_PI/180.; + double aRotAngle = myAngleRotSpin->value()*M_PI/180.; double aLengthAngle = -1.; if (myUseAngleLen->isChecked()) { @@ -350,7 +362,7 @@ bool TransformationGUI_ProjectionOnCylDlg::execute (ObjectList& objects) } GEOM::GEOM_Object_var anObj = anOper->MakeProjectionOnCylinder - (myObj, aRadius, aStartAngle, aLengthAngle); + (myObj, aRadius, aStartAngle, aLengthAngle, aRotAngle); if (!anObj->_is_nil()) { if (!IsPreview()) { @@ -359,6 +371,7 @@ bool TransformationGUI_ProjectionOnCylDlg::execute (ObjectList& objects) aParameters << myStartAngleSpin->text(); if (myUseAngleLen->isChecked()) aParameters << myAngleLenSpin->text(); + aParameters << myAngleRotSpin->text(); anObj->SetParameters(aParameters.join(":").toUtf8().constData()); } objects.push_back(anObj._retn()); diff --git a/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.h b/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.h index beb16d976..eab7ee34a 100644 --- a/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.h +++ b/src/TransformationGUI/TransformationGUI_ProjectionOnCylDlg.h @@ -72,6 +72,7 @@ private: SalomeApp_DoubleSpinBox *myStartAngleSpin; QCheckBox *myUseAngleLen; SalomeApp_DoubleSpinBox *myAngleLenSpin; + SalomeApp_DoubleSpinBox *myAngleRotSpin; }; From c38fbe7a1cfdd75dfbb01fb6448f1cba189217d8 Mon Sep 17 00:00:00 2001 From: skv Date: Mon, 8 Jun 2015 16:09:09 +0300 Subject: [PATCH 14/54] 0052774: GetInPlace creates result as a group of sub-shapes of different types --- src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 98 ++++++++++++--------- 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index affb64b9c..fcba87df2 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -4223,16 +4223,28 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) const TopoDS_Shape &aShapeResult = aGIP.Result(); TopTools_MapOfShape aMFence; TopTools_IndexedMapOfShape aWhereIndices; + Standard_Integer aShapeType = -1; TopExp::MapShapes(aWhere, aWhereIndices); if (aShapeResult.IsNull() == Standard_False) { - TopoDS_Iterator anIt(aShapeResult); + TopoDS_Iterator anIt(aShapeResult); + Standard_Boolean isFirst = Standard_True; for (; anIt.More(); anIt.Next()) { const TopoDS_Shape &aPart = anIt.Value(); if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) { + const TopAbs_ShapeEnum aType = aPart.ShapeType(); + + if (aShapeType == -1) { + // Initialization. + aShapeType = aType; + } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) { + // Different types. + aShapeType = TopAbs_SHAPE; + } + aLSA.Append(aPart); } } @@ -4246,13 +4258,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent()); TopTools_ListIteratorOfListOfShape anIterModif (aLSA); for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) { - if (aWhereIndices.Contains(anIterModif.Value())) { - aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value())); - } - else { - SetErrorCode("Error: wrong sub-shape returned"); - return NULL; - } + aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value())); } //Add a new object @@ -4262,7 +4268,10 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) return NULL; } - if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) { + const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE); + + if ((aModifiedArray->Length() > 1 && isSameType) || + theShapeWhat->GetType() == GEOM_GROUP) { //Set a GROUP type aResult->SetType(GEOM_GROUP); @@ -4331,10 +4340,20 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld new TColStd_HArray1OfInteger (1, aModifiedList.Extent()); TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList); Standard_Integer imod; + Standard_Integer aShapeType = -1; for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) { const Standard_Integer anIndex = aWhereIndices.FindIndex(anIterModif.Value()); + const TopAbs_ShapeEnum aType = anIterModif.Value().ShapeType(); + + if (aShapeType == -1) { + // Initialization. + aShapeType = aType; + } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) { + // Different types. + aShapeType = TopAbs_SHAPE; + } aModifiedArray->SetValue(imod, anIndex); } @@ -4348,7 +4367,10 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld return NULL; } - if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) { + const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE); + + if ((aModifiedArray->Length() > 1 && isSameType) || + theShapeWhat->GetType() == GEOM_GROUP) { //Set a GROUP type aResult->SetType(GEOM_GROUP); @@ -4406,40 +4428,27 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory return NULL; } - Standard_Integer nbFound = aModifiedList.Extent(); + Handle(TColStd_HArray1OfInteger) aModifiedArray = + new TColStd_HArray1OfInteger (1, aModifiedList.Extent()); TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList); - if ( nbFound > 1 ) - { - // remove sub-shapes inappropriate for group creation - TopAbs_ShapeEnum subType = TopAbs_SHAPE; - while ( anIterModif.More() ) { - TopAbs_ShapeEnum type = anIterModif.Value().ShapeType(); - bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE || - type == TopAbs_FACE || type == TopAbs_SOLID ); - if ( okForGroup ) { - if ( subType == TopAbs_SHAPE ) - subType = type; - else - okForGroup = ( subType == type ); - } - if ( okForGroup ) - anIterModif.Next(); - else - aModifiedList.Remove( anIterModif ); - nbFound -= ( !okForGroup ); - } - if ( nbFound == 0 ) { - SetErrorCode("Error: result found but it's type is inappropriate for group creation."); - return NULL; - } - } + Standard_Integer imod; + Standard_Integer aShapeType = -1; - Handle(TColStd_HArray1OfInteger) aModifiedArray = - new TColStd_HArray1OfInteger( 1, nbFound ); - anIterModif.Initialize(aModifiedList); - for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) - aModifiedArray->SetValue - (imod, aWhereIndices.FindIndex(anIterModif.Value())); + for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) { + const Standard_Integer anIndex = + aWhereIndices.FindIndex(anIterModif.Value()); + const TopAbs_ShapeEnum aType = anIterModif.Value().ShapeType(); + + if (aShapeType == -1) { + // Initialization. + aShapeType = aType; + } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) { + // Different types. + aShapeType = TopAbs_SHAPE; + } + + aModifiedArray->SetValue(imod, anIndex); + } //Add a new object Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray); @@ -4448,7 +4457,10 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory return NULL; } - if (aModifiedArray->Length() > 1) { + const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE); + + if ((aModifiedArray->Length() > 1 && isSameType) || + theShapeWhat->GetType() == GEOM_GROUP) { //Set a GROUP type aResult->SetType(GEOM_GROUP); From faf08d0c5248a634fd96a8a63a5c501c397692c7 Mon Sep 17 00:00:00 2001 From: vsr Date: Wed, 10 Jun 2015 13:37:56 +0300 Subject: [PATCH 15/54] Fix regression in KindOfShape functionality - sphere imported from SolidWorks's STEP file is not recognized as sphere --- src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx | 35 ++++++++++++++++----- 1 file changed, 28 insertions(+), 7 deletions(-) mode change 100644 => 100755 src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx diff --git a/src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx b/src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx old mode 100644 new mode 100755 index f5f509496..7c4a9b2de --- a/src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx +++ b/src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx @@ -85,6 +85,17 @@ void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd) return; } // + //modified by NIZNHY-PKV Tue Jun 09 08:35:23 2015f + if (aNbF==2) { + // case requested by the customer + // specific solid that should be treated as a sphere + bIsStepSphere=TreatStepSphere(aSd); + if (bIsStepSphere) { + return; + } + } + //modified by NIZNHY-PKV Tue Jun 09 08:35:28 2015t + // aKD=GEOMAlgo_KD_SPECIFIED; for (i=1; i<=aNbF && aKD==GEOMAlgo_KD_SPECIFIED; ++i) { const TopoDS_Shape& aF=aMF(i); @@ -120,6 +131,8 @@ void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd) return; } } + //modified by NIZNHY-PKV Tue Jun 09 08:36:08 2015f + /* else if (aNbF==2) { // specific solid that should be treated as a sphere bIsStepSphere=TreatStepSphere(aSd); @@ -127,6 +140,8 @@ void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd) return; } } + */ + //modified by NIZNHY-PKV Tue Jun 09 08:36:12 2015t // aNbCyl=0; aNbCon=0; @@ -780,7 +795,7 @@ Standard_Boolean GEOMAlgo_ShapeInfoFiller::TreatStepSphere { Standard_Boolean bRet, bIsAllowedType, bOnlyClosed, bIsEqual; Standard_Integer j; - Standard_Real aTolAng, aTolLin; + Standard_Real aTolAng, aTol; Standard_Real aVolume, aVolumeS, dV, aArea, aAreaS, dA; gp_Sphere aSphere[2]; GeomAbs_SurfaceType aST; @@ -789,7 +804,7 @@ Standard_Boolean GEOMAlgo_ShapeInfoFiller::TreatStepSphere TopExp_Explorer aExp; // bRet=Standard_False; - aTolLin=Precision::Confusion(); + aTol=Precision::Confusion(); aTolAng=Precision::Angular(); // aExp.Init(aSd, TopAbs_FACE); @@ -810,7 +825,7 @@ Standard_Boolean GEOMAlgo_ShapeInfoFiller::TreatStepSphere aSphere[j]=aGAS.Sphere(); } // - bIsEqual=IsEqual(aSphere[0], aSphere[1], aTolLin); + bIsEqual=IsEqual(aSphere[0], aSphere[1], aTol); if (!bIsEqual) { return bRet; } @@ -822,24 +837,30 @@ Standard_Boolean GEOMAlgo_ShapeInfoFiller::TreatStepSphere // aVolume=aSphere[0].Volume(); // - BRepGProp::VolumeProperties(aSd, aGProps, bOnlyClosed); + //modified by NIZNHY-PKV Tue Jun 09 08:39:47 2015f + BRepGProp::VolumeProperties(aSd, aGProps, aTol, bOnlyClosed); + //BRepGProp::VolumeProperties(aSd, aGProps, bOnlyClosed); + //modified by NIZNHY-PKV Tue Jun 09 08:39:50 2015t aVolumeS=aGProps.Mass(); if (aVolumeS<0.) { aVolumeS=-aVolumeS; } // dV=fabs(aVolumeS-aVolume); - if (dV>aTolLin) { + if (dV>aTol) { return bRet; } //-------------------------------- aArea=aSphere[0].Area(); // - BRepGProp::SurfaceProperties(aSd, aGProps); + //modified by NIZNHY-PKV Tue Jun 09 08:23:54 2015f + BRepGProp::SurfaceProperties(aSd, aGProps, aTol); + //BRepGProp::SurfaceProperties(aSd, aGProps); + //modified by NIZNHY-PKV Tue Jun 09 08:23:56 2015t aAreaS=aGProps.Mass(); // dA=fabs(aAreaS-aArea); - if (dA>aTolLin) { + if (dA>aTol) { return bRet; } // From eba013acfeded966f2f5f97d90747c504b160adf Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 11 Jun 2015 10:20:52 +0300 Subject: [PATCH 16/54] Migration to OCCT > 6.9.0 --- src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index 5e33ac622..ff068838b 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -53,6 +53,7 @@ #include #if OCC_VERSION_LARGE > 0x06090000 #include +#include #endif #include #include @@ -1624,11 +1625,11 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersectionsFast // Launch the checker aTool.Perform(); - const BRepExtrema_OverlapTool::OverlapSubShapes& intersections = aTool.OverlapElements(); + const BRepExtrema_MapOfIntegerPackedMapOfInteger& intersections = aTool.OverlapElements(); std::set processed; - for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator it(intersections); it.More(); it.Next()) { + for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator it(intersections); it.More(); it.Next()) { Standard_Integer idxLeft = it.Key(); if (processed.count(idxLeft) > 0) continue; // already added processed.insert(idxLeft); @@ -1715,7 +1716,7 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1, // 2. Get sets of IDs of overlapped faces #if OCC_VERSION_LARGE > 0x06090000 - for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) + for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) #else for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) #endif @@ -1725,7 +1726,7 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1, } #if OCC_VERSION_LARGE > 0x06090000 - for (BRepExtrema_OverlapTool::OverlapSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) + for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) #else for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) #endif From 1839b501d4b7e21938af8af18c060fdf042302e0 Mon Sep 17 00:00:00 2001 From: skv Date: Thu, 11 Jun 2015 11:53:02 +0300 Subject: [PATCH 17/54] 0022782: [CEA 1315] GetFirstVertex does not return the edge's starting point --- doc/salome/gui/GEOM/images/point3.png | Bin 23917 -> 26808 bytes doc/salome/gui/GEOM/input/creating_point.doc | 5 +++-- idl/GEOM_Gen.idl | 5 ++++- src/BasicGUI/BasicGUI_PointDlg.cxx | 16 +++++++++++--- src/BasicGUI/BasicGUI_PointDlg.h | 6 +++--- src/GEOMGUI/GEOM_msg_en.ts | 4 ++++ src/GEOMImpl/GEOMImpl_IBasicOperations.cxx | 21 ++++++++++++------- src/GEOMImpl/GEOMImpl_IBasicOperations.hxx | 20 +++++++++++------- src/GEOMImpl/GEOMImpl_IPoint.hxx | 7 ++++--- src/GEOMImpl/GEOMImpl_PointDriver.cxx | 10 ++++++++- src/GEOM_I/GEOM_IBasicOperations_i.cc | 8 ++++--- src/GEOM_I/GEOM_IBasicOperations_i.hh | 6 ++++-- src/GEOM_I_Superv/GEOM_Superv_i.cc | 2 +- src/GEOM_SWIG/geomBuilder.py | 20 +++++++++++++++--- 14 files changed, 93 insertions(+), 37 deletions(-) mode change 100755 => 100644 doc/salome/gui/GEOM/images/point3.png mode change 100755 => 100644 src/GEOMImpl/GEOMImpl_IPoint.hxx diff --git a/doc/salome/gui/GEOM/images/point3.png b/doc/salome/gui/GEOM/images/point3.png old mode 100755 new mode 100644 index 8b4daecc19890f68633678bf9caa4e68b1ca4266..57cccab0abd4350a8befe9a5306bc0d4df26ad55 GIT binary patch literal 26808 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 literal 23917 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 Z>yLR((Y-}d1u#Y(p{H%Am7`&O?;r61=vn{( diff --git a/doc/salome/gui/GEOM/input/creating_point.doc b/doc/salome/gui/GEOM/input/creating_point.doc index cc8790624..5929a8fd1 100644 --- a/doc/salome/gui/GEOM/input/creating_point.doc +++ b/doc/salome/gui/GEOM/input/creating_point.doc @@ -28,9 +28,10 @@ the position of this point regarding the reference one. \n Thirdly, we can define a point by an \b Edge and a \b Parameter indicating its position on the Edge, ranging from 0.0 to 1.0. For example, 0.5 means that the point is located in the middle of the edge. -\n TUI Command: geompy.MakeVertexOnCurve(Edge,Parameter). +\n TUI Command: geompy.MakeVertexOnCurve(Edge,Parameter,takeOrientationIntoAccount). \n Arguments: Name + 1 edge + 1 Parameter defining the -position of the point on the given edge. +position of the point on the given edge + flag that tells if it is necessary +to take the edge orientation into account. \image html point3.png Alternatively, it is possible to define a point by an \b Edge and a \b Length. diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index c301b79ae..d7c643562 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -732,10 +732,13 @@ module GEOM * 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 takeOrientationIntoAccount flag that tells if it is necessary + * to take the curve's orientation into account. * \return New GEOM_Object, containing the created point. */ GEOM_Object MakePointOnCurve (in GEOM_Object theRefCurve, - in double theParameter); + in double theParameter, + in boolean takeOrientationIntoAccount); /*! * \brief Create a point, corresponding to the given length on the given curve. diff --git a/src/BasicGUI/BasicGUI_PointDlg.cxx b/src/BasicGUI/BasicGUI_PointDlg.cxx index 983666d28..0a374c4d7 100644 --- a/src/BasicGUI/BasicGUI_PointDlg.cxx +++ b/src/BasicGUI/BasicGUI_PointDlg.cxx @@ -125,13 +125,17 @@ BasicGUI_PointDlg::BasicGUI_PointDlg(GeometryGUI* theGeometryGUI, QWidget* paren GroupXYZ->TextLabel2->setText(tr("GEOM_Y")); GroupXYZ->TextLabel3->setText(tr("GEOM_Z")); - GroupOnCurve = new DlgRef_2Sel1Spin(centralWidget()); + GroupOnCurve = new DlgRef_2Sel1Spin2Check(centralWidget()); GroupOnCurve->GroupBox1->setTitle(tr("GEOM_POINT_ON_EDGE")); GroupOnCurve->TextLabel1->setText(tr("GEOM_EDGE")); GroupOnCurve->TextLabel2->setText(tr("GEOM_START_POINT")); GroupOnCurve->TextLabel3->setText(tr("GEOM_PARAMETER")); GroupOnCurve->PushButton1->setIcon(image2); GroupOnCurve->PushButton2->setIcon(image2); + GroupOnCurve->TextLabel3->setText(tr("GEOM_PARAMETER")); + GroupOnCurve->CheckButton1->setText(tr("GEOM_TAKE_ORIENTATION_INTO_ACCOUNT")); + GroupOnCurve->CheckButton2->setAttribute( Qt::WA_DeleteOnClose ); + GroupOnCurve->CheckButton2->close(); GroupOnSurface = new DlgRef_1Sel2Spin(centralWidget()); GroupOnSurface->GroupBox1->setTitle(tr("GEOM_POINT_ON_FACE")); @@ -258,6 +262,7 @@ void BasicGUI_PointDlg::Init() initSpinBox(GroupOnCurve->SpinBox_DX, 0., 1., step, "parametric_precision"); GroupOnCurve->SpinBox_DX->setValue(0.5); + GroupOnCurve->CheckButton1->setChecked(true); initSpinBox(GroupOnSurface->SpinBox_DX, 0., 1., step, "parametric_precision"); GroupOnSurface->SpinBox_DX->setValue(0.5); @@ -275,6 +280,8 @@ void BasicGUI_PointDlg::Init() connect(myParamCoord, SIGNAL(buttonClicked(int)), this, SLOT(ClickParamCoord(int))); + connect(GroupOnCurve->CheckButton1, SIGNAL(toggled(bool)), this, SLOT(CheckBoxClicked())); + connect(GroupOnCurve->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); connect(GroupOnCurve->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); connect(GroupOnSurface->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); @@ -669,7 +676,7 @@ void BasicGUI_PointDlg::ValueChangedInSpinBox(double newValue) // function : CheckBoxClicked() // purpose : Check Boxes Management //================================================================================= -void BasicGUI_PointDlg::CheckBoxClicked(int State) +void BasicGUI_PointDlg::CheckBoxClicked() { displayPreview(true); } @@ -821,7 +828,9 @@ bool BasicGUI_PointDlg::execute(ObjectList& objects) case GEOM_POINT_EDGE : { if (myParamCoord->checkedId() == PARAM_VALUE) { - anObj = anOper->MakePointOnCurve(myEdge.get(), getParameter()); + bool isUseOrientation = GroupOnCurve->CheckButton1->isChecked(); + + anObj = anOper->MakePointOnCurve(myEdge.get(), getParameter(), isUseOrientation); aParameters<SpinBox_DX->text(); } else if (myParamCoord->checkedId() == LENGTH_VALUE) { @@ -973,6 +982,7 @@ void BasicGUI_PointDlg::updateParamCoord(bool theIsUpdate) GroupOnCurve->LineEdit2->setVisible(isLength); GroupOnCurve->TextLabel3->setVisible(isParam || isLength); GroupOnCurve->SpinBox_DX->setVisible(isParam || isLength); + GroupOnCurve->CheckButton1->setVisible(isParam); if (isParam){ initSpinBox(GroupOnCurve->SpinBox_DX, 0., 1., 0.1, "parametric_precision"); GroupOnCurve->SpinBox_DX->setValue(0.5); diff --git a/src/BasicGUI/BasicGUI_PointDlg.h b/src/BasicGUI/BasicGUI_PointDlg.h index 7002333db..ffc01a165 100644 --- a/src/BasicGUI/BasicGUI_PointDlg.h +++ b/src/BasicGUI/BasicGUI_PointDlg.h @@ -31,7 +31,7 @@ #include "GEOM_GenericObjPtr.h" #include -class DlgRef_2Sel1Spin; +class DlgRef_2Sel1Spin2Check; class DlgRef_3Spin; class DlgRef_2Sel; class DlgRef_1Sel3Spin; @@ -88,7 +88,7 @@ private: DlgRef_3Spin* GroupXYZ; DlgRef_1Sel3Spin* GroupRefPoint; - DlgRef_2Sel1Spin* GroupOnCurve; + DlgRef_2Sel1Spin2Check* GroupOnCurve; DlgRef_2Sel* GroupLineIntersection; DlgRef_1Sel2Spin* GroupOnSurface; @@ -115,7 +115,7 @@ private slots: void ValueChangedInSpinBox( double ); void SetDoubleSpinBoxStep( double ); void ClickParamCoord( int ); - void CheckBoxClicked( int ); + void CheckBoxClicked(); void updateSize(); }; diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 9bed663c4..d9ce747c7 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -1352,6 +1352,10 @@ Please, select face, shell or solid and try again GEOM_LENGTH_VALUE By length + + GEOM_TAKE_ORIENTATION_INTO_ACCOUNT + Take edge orientation into account + GEOM_PARTITION Partition diff --git a/src/GEOMImpl/GEOMImpl_IBasicOperations.cxx b/src/GEOMImpl/GEOMImpl_IBasicOperations.cxx index 576ba74af..8f282f2ae 100644 --- a/src/GEOMImpl/GEOMImpl_IBasicOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IBasicOperations.cxx @@ -186,10 +186,11 @@ Handle(GEOM_Object) GEOMImpl_IBasicOperations::MakePointWithReference //============================================================================= Handle(GEOM_Object) GEOMImpl_IBasicOperations::makePointOnGeom (Handle(GEOM_Object) theGeomObj, - double theParam1, - double theParam2, - double theParam3, + double theParam1, + double theParam2, + double theParam3, const PointLocation theLocation, + const bool takeOrientationIntoAccount, Handle(GEOM_Object) theRefPoint) { SetErrorCode(KO); @@ -226,6 +227,7 @@ Handle(GEOM_Object) GEOMImpl_IBasicOperations::makePointOnGeom case PointOn_CurveByParam: aPI.SetCurve(aRefFunction); aPI.SetParameter(theParam1); + aPI.SetTakeOrientationIntoAccount(takeOrientationIntoAccount); break; case PointOn_CurveByLength: aPI.SetCurve(aRefFunction); @@ -277,7 +279,8 @@ Handle(GEOM_Object) GEOMImpl_IBasicOperations::makePointOnGeom { case PointOn_CurveByParam: GEOM::TPythonDump(aFunction) << aPoint << " = geompy.MakeVertexOnCurve(" - << theGeomObj << ", " << theParam1 << ")"; + << theGeomObj << ", " << theParam1 << ", " + << takeOrientationIntoAccount << ")"; break; case PointOn_CurveByLength: GEOM::TPythonDump(aFunction) << aPoint << " = geompy.MakeVertexOnCurveByLength(" @@ -315,9 +318,12 @@ Handle(GEOM_Object) GEOMImpl_IBasicOperations::makePointOnGeom */ //============================================================================= Handle(GEOM_Object) GEOMImpl_IBasicOperations::MakePointOnCurve - (Handle(GEOM_Object) theCurve, double theParameter) + (Handle(GEOM_Object) theCurve, + double theParameter, + bool takeOrientationIntoAccount) { - return makePointOnGeom(theCurve, theParameter, 0.0, 0.0, PointOn_CurveByParam); + return makePointOnGeom(theCurve, theParameter, 0.0, 0.0, PointOn_CurveByParam, + takeOrientationIntoAccount); } //============================================================================= @@ -344,7 +350,8 @@ Handle(GEOM_Object) GEOMImpl_IBasicOperations::MakePointOnCurveByLength double theLength, Handle(GEOM_Object) theStartPoint) { - return makePointOnGeom(theCurve, theLength, 0.0, 0.0, PointOn_CurveByLength, theStartPoint); + return makePointOnGeom(theCurve, theLength, 0.0, 0.0, PointOn_CurveByLength, + false, theStartPoint); } //============================================================================= diff --git a/src/GEOMImpl/GEOMImpl_IBasicOperations.hxx b/src/GEOMImpl/GEOMImpl_IBasicOperations.hxx index e3960f2f5..df8051ab6 100644 --- a/src/GEOMImpl/GEOMImpl_IBasicOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IBasicOperations.hxx @@ -40,8 +40,10 @@ class GEOMImpl_IBasicOperations : public GEOM_IOperations { Standard_EXPORT Handle(GEOM_Object) MakePointWithReference (Handle(GEOM_Object) theReference, double theX, double theY, double theZ); - Standard_EXPORT Handle(GEOM_Object) MakePointOnCurve (Handle(GEOM_Object) theCurve, - double theParameter); + Standard_EXPORT Handle(GEOM_Object) MakePointOnCurve + (Handle(GEOM_Object) theCurve, + double theParameter, + bool takeOrientationIntoAccount); Standard_EXPORT Handle(GEOM_Object) MakePointOnCurveByLength (Handle(GEOM_Object) theCurve, double theLength, @@ -134,12 +136,14 @@ class GEOMImpl_IBasicOperations : public GEOM_IOperations { PointOn_Face }; - Handle(GEOM_Object) makePointOnGeom (Handle(GEOM_Object) theGeomObj, - double theParam1, - double theParam2, - double theParam3, - const PointLocation theLocation, - Handle(GEOM_Object) theRefPoint = 0); + Handle(GEOM_Object) makePointOnGeom + (Handle(GEOM_Object) theGeomObj, + double theParam1, + double theParam2, + double theParam3, + const PointLocation theLocation, + const bool takeOrientationIntoAccount = false, + Handle(GEOM_Object) theRefPoint = 0); }; #endif diff --git a/src/GEOMImpl/GEOMImpl_IPoint.hxx b/src/GEOMImpl/GEOMImpl_IPoint.hxx old mode 100755 new mode 100644 index 650330272..07f81f000 --- a/src/GEOMImpl/GEOMImpl_IPoint.hxx +++ b/src/GEOMImpl/GEOMImpl_IPoint.hxx @@ -40,7 +40,7 @@ #define ARG_LENGTH 11 -//#define ARG_FLAG 12 +#define ARG_USE_ORIENTATION 12 class GEOMImpl_IPoint { @@ -73,12 +73,13 @@ class GEOMImpl_IPoint void SetParameter(double theParam) { _func->SetReal(ARG_PARAM, theParam); } void SetParameter2(double theParam) { _func->SetReal(ARG_PARAM2, theParam); } void SetLength(double theLength) { _func->SetReal(ARG_LENGTH, theLength); } - //void SetReversed(bool theReversed) { _func->SetInteger(ARG_FLAG, theReversed); } + void SetTakeOrientationIntoAccount(bool takeOrientationIntoAccount) + { _func->SetInteger(ARG_USE_ORIENTATION, takeOrientationIntoAccount); } double GetParameter() { return _func->GetReal(ARG_PARAM); } double GetParameter2() { return _func->GetReal(ARG_PARAM2); } double GetLength() { return _func->GetReal(ARG_LENGTH); } - //bool GetReversed() { return _func->GetInteger(ARG_FLAG); } + bool GetTakeOrientationIntoAccount() { return _func->GetInteger(ARG_USE_ORIENTATION); } private: diff --git a/src/GEOMImpl/GEOMImpl_PointDriver.cxx b/src/GEOMImpl/GEOMImpl_PointDriver.cxx index 03edfc4c1..f80ba42b9 100644 --- a/src/GEOMImpl/GEOMImpl_PointDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PointDriver.cxx @@ -145,7 +145,14 @@ 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); if ( !aCurve.IsNull() ) { - aP = aFP + (aLP - aFP) * aPI.GetParameter(); + if (aPI.GetTakeOrientationIntoAccount() && + aRefShape.Orientation() == TopAbs_REVERSED) { + aP = 1. - aPI.GetParameter(); + } else { + aP = aPI.GetParameter(); + } + + aP = aFP + (aLP - aFP) * aP; aPnt = aCurve->Value(aP); } else { @@ -393,6 +400,7 @@ GetCreationInformation(std::string& theOperationName, case POINT_CURVE_PAR: AddParam( theParams, "Edge", aCI.GetCurve() ); AddParam( theParams, "Parameter", aCI.GetParameter() ); + AddParam( theParams, "Use Orientation", aCI.GetTakeOrientationIntoAccount() ); break; case POINT_CURVE_COORD: AddParam( theParams, "X", aCI.GetX() ); diff --git a/src/GEOM_I/GEOM_IBasicOperations_i.cc b/src/GEOM_I/GEOM_IBasicOperations_i.cc index 1dcf544f9..b48adfff4 100644 --- a/src/GEOM_I/GEOM_IBasicOperations_i.cc +++ b/src/GEOM_I/GEOM_IBasicOperations_i.cc @@ -135,7 +135,9 @@ GEOM::GEOM_Object_ptr GEOM_IBasicOperations_i::MakePointOnLinesIntersection */ //============================================================================= GEOM::GEOM_Object_ptr GEOM_IBasicOperations_i::MakePointOnCurve - (GEOM::GEOM_Object_ptr theCurve, CORBA::Double theParameter) + (GEOM::GEOM_Object_ptr theCurve, + CORBA::Double theParameter, + CORBA::Boolean takeOrientationIntoAccount) { GEOM::GEOM_Object_var aGEOMObject; @@ -147,8 +149,8 @@ GEOM::GEOM_Object_ptr GEOM_IBasicOperations_i::MakePointOnCurve if (aReference.IsNull()) return aGEOMObject._retn(); //Create the point - Handle(GEOM_Object) anObject = - GetOperations()->MakePointOnCurve(aReference, theParameter); + Handle(GEOM_Object) anObject = GetOperations()->MakePointOnCurve + (aReference, theParameter, takeOrientationIntoAccount); if (!GetOperations()->IsDone() || anObject.IsNull()) return aGEOMObject._retn(); diff --git a/src/GEOM_I/GEOM_IBasicOperations_i.hh b/src/GEOM_I/GEOM_IBasicOperations_i.hh index ec55aee27..c3e1fa3ff 100644 --- a/src/GEOM_I/GEOM_IBasicOperations_i.hh +++ b/src/GEOM_I/GEOM_IBasicOperations_i.hh @@ -52,8 +52,10 @@ class GEOM_I_EXPORT GEOM_IBasicOperations_i : CORBA::Double theY, CORBA::Double theZ); - GEOM::GEOM_Object_ptr MakePointOnCurve (GEOM::GEOM_Object_ptr theCurve, - CORBA::Double theParameter); + GEOM::GEOM_Object_ptr MakePointOnCurve + (GEOM::GEOM_Object_ptr theCurve, + CORBA::Double theParameter, + CORBA::Boolean takeOrientationIntoAccount); GEOM::GEOM_Object_ptr MakePointOnCurveByLength (GEOM::GEOM_Object_ptr theCurve, CORBA::Double theLength, diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.cc b/src/GEOM_I_Superv/GEOM_Superv_i.cc index 8501474d8..bfd598ad5 100644 --- a/src/GEOM_I_Superv/GEOM_Superv_i.cc +++ b/src/GEOM_I_Superv/GEOM_Superv_i.cc @@ -722,7 +722,7 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakePointOnCurve (GEOM::GEOM_Object_ptr the beginService( " GEOM_Superv_i::MakePointOnCurve" ); MESSAGE("GEOM_Superv_i::MakePointOnCurve"); getBasicOp(); - GEOM::GEOM_Object_ptr anObj = myBasicOp->MakePointOnCurve(theRefCurve, theParameter); + GEOM::GEOM_Object_ptr anObj = myBasicOp->MakePointOnCurve(theRefCurve, theParameter, false); endService( " GEOM_Superv_i::MakePointOnCurve" ); return anObj; } diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 0a3d2c832..0e8257dec 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -1148,6 +1148,11 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): ## 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 takeOrientationIntoAccount flag that tells if it is necessary + # to take the curve's orientation into account for the + # operation. I.e. if this flag is set, the results for the same + # parameters (except the value 0.5) is different for forward + # and reversed curves. If it is not set the result is the same. # @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. @@ -1156,13 +1161,20 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # # @ref tui_creation_point "Example" @ManageTransactions("BasicOp") - def MakeVertexOnCurve(self, theRefCurve, theParameter, theName=None): + def MakeVertexOnCurve(self, theRefCurve, theParameter, + takeOrientationIntoAccount=False, 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. + takeOrientationIntoAccount flag that tells if it is necessary + to take the curve's orientation into account for the + operation. I.e. if this flag is set, the results for + the same parameters (except the value 0.5) is different + for forward and reversed curves. If it is not set + the result is the same. theName Object name; when specified, this parameter is used for result publication in the study. Otherwise, if automatic publication is switched on, default value is used for result name. @@ -1174,8 +1186,10 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): p_on_arc = geompy.MakeVertexOnCurve(Arc, 0.25) """ # Example: see GEOM_TestAll.py - theParameter, Parameters = ParseParameters(theParameter) - anObj = self.BasicOp.MakePointOnCurve(theRefCurve, theParameter) + theParameter, takeOrientationIntoAccount, Parameters = ParseParameters( + theParameter, takeOrientationIntoAccount) + anObj = self.BasicOp.MakePointOnCurve(theRefCurve, theParameter, + takeOrientationIntoAccount) RaiseIfFailed("MakePointOnCurve", self.BasicOp) anObj.SetParameters(Parameters) self._autoPublish(anObj, theName, "vertex") From 0a9a0010a0cf955ad110c43c2a7e24d145a2cdf4 Mon Sep 17 00:00:00 2001 From: mpa Date: Thu, 11 Jun 2015 16:03:47 +0300 Subject: [PATCH 18/54] CMake improvement: usage of SALOME_GUI_MODE() macro --- CMakeLists.txt | 15 ++++---- doc/salome/gui/GEOM/input/dependency_tree.doc | 2 ++ .../GEOM/input/shape_statistics_operation.doc | 2 ++ src/CMakeLists.txt | 5 ++- src/EntityGUI/EntityGUI_SubShapeDlg.cxx | 14 +++++++- src/EntityGUI/EntityGUI_SubShapeDlg.h | 2 ++ src/GEOMGUI/GeometryGUI.cxx | 34 ++++++++++++++++--- src/GEOMGUI/GeometryGUI_Operations.h | 8 ++++- src/GEOMToolsGUI/CMakeLists.txt | 7 +++- src/GEOMToolsGUI/GEOMToolsGUI.cxx | 4 +++ src/GEOMToolsGUI/GEOMToolsGUI.h | 2 ++ src/GEOMToolsGUI/GEOMToolsGUI_1.cxx | 8 +++++ src/GroupGUI/GroupGUI_GroupDlg.cxx | 12 +++++++ src/GroupGUI/GroupGUI_GroupDlg.h | 2 ++ src/MeasureGUI/CMakeLists.txt | 14 ++++++-- src/MeasureGUI/MeasureGUI.cxx | 6 +++- 16 files changed, 118 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dbf940714..8637d6784 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,7 +108,9 @@ IF(SALOME_BUILD_GUI) IF(EXISTS ${GUI_ROOT_DIR}) LIST(APPEND CMAKE_MODULE_PATH "${GUI_ROOT_DIR}/adm_local/cmake_files") FIND_PACKAGE(SalomeGUI) - FULL_GUI(TRUE) #check whether GUI builded in full mode and with CORBA + SALOME_GUI_WITH_CORBA() #check whether GUI builded with CORBA + SALOME_GUI_MODE(SALOME_USE_OCCVIEWER SALOME_USE_VTKVIEWER SALOME_USE_SALOMEOBJECT + OPTIONAL SALOME_USE_PLOT2DVIEWER SALOME_USE_GRAPHICSVIEW SALOME_USE_PYCONSOLE) ADD_DEFINITIONS(${GUI_DEFINITIONS}) INCLUDE_DIRECTORIES(${GUI_INCLUDE_DIRS}) ELSE(EXISTS ${GUI_ROOT_DIR}) @@ -125,12 +127,6 @@ IF(SALOME_BUILD_GUI) # Qt4 FIND_PACKAGE(SalomeQt4 REQUIRED COMPONENTS QtCore QtGui QtXml) - - # Optional prerequisites for GUI - IF(SALOME_USE_GLVIEWER) - FIND_PACKAGE(SalomeOpenGL) - SALOME_LOG_OPTIONAL_PACKAGE(OpenGL SALOME_USE_GLVIEWER) - ENDIF() ENDIF(SALOME_BUILD_GUI) ## @@ -231,9 +227,12 @@ IF(SALOME_BUILD_GUI) LIST(APPEND _${PROJECT_NAME}_exposed_targets AdvancedGUI BasicGUI BlocksGUI BooleanGUI BuildGUI DisplayGUI DlgRef CurveCreator EntityGUI GEOMBase GEOMFiltersSelection GEOM GEOMToolsGUI GenerationGUI GroupGUI Material MeasureGUI GEOMObject - OperationGUI PrimitiveGUI RepairGUI TransformationGUI DependencyTree + OperationGUI PrimitiveGUI RepairGUI TransformationGUI STLPluginGUI BREPPluginGUI STEPPluginGUI IGESPluginGUI XAOPluginGUI VTKPluginGUI ) + IF(SALOME_USE_GRAPHICSVIEW) + LIST(APPEND _${PROJECT_NAME}_exposed_targets DependencyTree) + ENDIF(SALOME_USE_GRAPHICSVIEW) ENDIF(SALOME_BUILD_GUI) IF(SALOME_GEOM_USE_OPENCV) diff --git a/doc/salome/gui/GEOM/input/dependency_tree.doc b/doc/salome/gui/GEOM/input/dependency_tree.doc index b8346eec7..40e1a2ac4 100644 --- a/doc/salome/gui/GEOM/input/dependency_tree.doc +++ b/doc/salome/gui/GEOM/input/dependency_tree.doc @@ -28,6 +28,8 @@ It is also possible to select an object(s) directly in the "Dependency Tree" vie All necessary parameters of Dependency Tree Viewer can be edited in the \ref pref_dependency_tree "Preferences". +\note This functionality is available only if GUI module is builded with Graphics view (set option SALOME_USE_GRAPHICSVIEW to ON when building GUI module). +
      \anchor dependency_tree_nodes_anchor

      Nodes

      diff --git a/doc/salome/gui/GEOM/input/shape_statistics_operation.doc b/doc/salome/gui/GEOM/input/shape_statistics_operation.doc index 207db3b75..991d103b5 100644 --- a/doc/salome/gui/GEOM/input/shape_statistics_operation.doc +++ b/doc/salome/gui/GEOM/input/shape_statistics_operation.doc @@ -25,4 +25,6 @@ In this dialog: - Close dialog box, by pressing Close button. +\note This functionality is available only if GUI module is builded with Plot 2D Viewer (set option SALOME_USE_PLOT2DVIEWER to ON when building GUI module). + */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6f830743b..bd7e3428d 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,11 +42,14 @@ ENDIF() IF(SALOME_BUILD_GUI) SET(SUBDIRS_GUI OBJECT DlgRef GEOMFiltersSelection Material GEOMGUI - GEOMBase DependencyTree GEOMToolsGUI DisplayGUI BasicGUI PrimitiveGUI GenerationGUI + GEOMBase GEOMToolsGUI DisplayGUI BasicGUI PrimitiveGUI GenerationGUI CurveCreator MeasureGUI EntityGUI BuildGUI BooleanGUI TransformationGUI OperationGUI RepairGUI GroupGUI BlocksGUI AdvancedGUI GEOM_SWIG_WITHIHM ) + IF(SALOME_USE_GRAPHICSVIEW) + LIST(APPEND SUBDIRS_GUI DependencyTree) + ENDIF() ENDIF() SET(SUBDIRS diff --git a/src/EntityGUI/EntityGUI_SubShapeDlg.cxx b/src/EntityGUI/EntityGUI_SubShapeDlg.cxx index 598d05de6..9449cf030 100644 --- a/src/EntityGUI/EntityGUI_SubShapeDlg.cxx +++ b/src/EntityGUI/EntityGUI_SubShapeDlg.cxx @@ -30,7 +30,9 @@ #include #include #include -#include +#ifndef DISABLE_PLOT2DVIEWER + #include +#endif #include #include @@ -166,7 +168,9 @@ EntityGUI_SubShapeDlg::EntityGUI_SubShapeDlg(GeometryGUI* theGeometryGUI, QWidge myLessFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp); myGreaterFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp); myApplyFilterButton = new QPushButton(tr("GEOM_BUT_APPLY"), myFilterGrp); +#ifndef DISABLE_PLOT2DVIEWER myPlotDistributionButton = new QPushButton(tr("GEOM_PLOT_DISTRIBUTION"), myFilterGrp); +#endif QGridLayout* filterLayout = new QGridLayout(myFilterGrp); filterLayout->addWidget(myLessFilterCheck, 0, 0); @@ -176,7 +180,9 @@ EntityGUI_SubShapeDlg::EntityGUI_SubShapeDlg(GeometryGUI* theGeometryGUI, QWidge filterLayout->addWidget(myGreaterFilterCombo, 1, 1); filterLayout->addWidget(myGreaterFilterSpin, 1, 2); filterLayout->addWidget(myApplyFilterButton, 0, 3); +#ifndef DISABLE_PLOT2DVIEWER filterLayout->addWidget(myPlotDistributionButton, 1, 3); +#endif QVBoxLayout* layout = new QVBoxLayout(centralWidget()); layout->setMargin(0); layout->setSpacing(6); @@ -253,7 +259,9 @@ void EntityGUI_SubShapeDlg::Init() connect(GroupPoints->PushButton4, SIGNAL(clicked()), this, SLOT(showOnlySelected())); connect(myApplyFilterButton, SIGNAL(clicked()), this, SLOT(ClickOnOkFilter())); +#ifndef DISABLE_PLOT2DVIEWER connect(myPlotDistributionButton, SIGNAL(clicked()), this, SLOT(ClickOnPlot())); +#endif connect(myLessFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled())); connect(myGreaterFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled())); @@ -495,10 +503,12 @@ void EntityGUI_SubShapeDlg::SubShapeToggled() GroupPoints->CheckButton1->isChecked() && shapeType() < GEOM::VERTEX); +#ifndef DISABLE_PLOT2DVIEWER myPlotDistributionButton->setEnabled( myFilterGrp->isEnabled() && ( shapeType() == TopAbs_EDGE || shapeType() == TopAbs_FACE || shapeType() == TopAbs_SOLID ) ); +#endif activateSelection(); } @@ -945,6 +955,7 @@ void EntityGUI_SubShapeDlg::ClickOnOkFilter() updateButtonState(); } +#ifndef DISABLE_PLOT2DVIEWER //================================================================================= // function : ClickOnPlot() // purpose : opens "Shape Statistics" dialog box in order to plot sub-shapes distribution. @@ -956,6 +967,7 @@ void EntityGUI_SubShapeDlg::ClickOnPlot() dlg->show(); } } +#endif //================================================================================= // function : MeasureToggled() diff --git a/src/EntityGUI/EntityGUI_SubShapeDlg.h b/src/EntityGUI/EntityGUI_SubShapeDlg.h index c2f14e66e..18c0c9ec8 100644 --- a/src/EntityGUI/EntityGUI_SubShapeDlg.h +++ b/src/EntityGUI/EntityGUI_SubShapeDlg.h @@ -73,7 +73,9 @@ private slots: void showOnlySelected(); void ClickOnOkFilter(); +#ifndef DISABLE_PLOT2DVIEWER void ClickOnPlot(); +#endif void MeasureToggled(); private: diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 8b4f0968a..3bfe0e5b0 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -51,8 +51,6 @@ #include #include -#include - #include #include #include @@ -66,7 +64,9 @@ #include #include +#ifndef DISABLE_GRAPHICSVIEW #include +#endif #include #include @@ -438,7 +438,11 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam ) SUIT_ViewWindow* window = desk->activeWindow(); bool ViewOCC = ( window && window->getViewManager()->getType() == OCCViewer_Viewer::Type() ); bool ViewVTK = ( window && window->getViewManager()->getType() == SVTK_Viewer::Type() ); +#ifndef DISABLE_GRAPHICSVIEW bool ViewDep = ( window && window->getViewManager()->getType() == GraphicsView_Viewer::Type() ); +#else + bool ViewDep = 0; +#endif // if current viewframe is not of OCC and not of VTK type - return immediately // fix for IPAL8958 - allow some commands to execute even when NO viewer is active (rename for example) QList NotViewerDependentCommands; @@ -479,7 +483,9 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam ) case GEOMOp::OpSelectCompound: // POPUP MENU - SELECT ONLY - COMPOUND case GEOMOp::OpSelectAll: // POPUP MENU - SELECT ONLY - SELECT ALL case GEOMOp::OpDelete: // MENU EDIT - DELETE +#ifndef DISABLE_PYCONSOLE case GEOMOp::OpCheckGeom: // MENU TOOLS - CHECK GEOMETRY +#endif case GEOMOp::OpMaterialsLibrary: // MENU TOOLS - MATERIALS LIBRARY case GEOMOp::OpDeflection: // POPUP MENU - DEFLECTION COEFFICIENT case GEOMOp::OpColor: // POPUP MENU - COLOR @@ -506,7 +512,9 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam ) case GEOMOp::OpClsBringToFront: // case GEOMOp::OpCreateFolder: // POPUP MENU - CREATE FOLDER case GEOMOp::OpSortChildren: // POPUP MENU - SORT CHILD ITEMS +#ifndef DISABLE_GRAPHICSVIEW case GEOMOp::OpShowDependencyTree: // POPUP MENU - SHOW DEPENDENCY TREE +#endif case GEOMOp::OpReduceStudy: // POPUP MENU - REDUCE STUDY libName = "GEOMToolsGUI"; break; @@ -653,7 +661,9 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam ) case GEOMOp::OpCheckSelfInters: // MENU MEASURE - CHECK SELF INTERSECTIONS case GEOMOp::OpFastCheckInters: // MENU MEASURE - FAST CHECK INTERSECTIONS case GEOMOp::OpManageDimensions: // MENU MEASURE - MANAGE DIMENSIONS +#ifndef DISABLE_PLOT2DVIEWER case GEOMOp::OpShapeStatistics: // MENU MEASURE - SHAPE STATISTICS +#endif case GEOMOp::OpShowAllDimensions: // POPUP MENU - SHOW ALL DIMENSIONS case GEOMOp::OpHideAllDimensions: // POPUP MENU - HIDE ALL DIMENSIONS libName = "MeasureGUI"; @@ -1035,10 +1045,14 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( GEOMOp::OpGetNonBlocks, "GET_NON_BLOCKS" ); createGeomAction( GEOMOp::OpCheckSelfInters, "CHECK_SELF_INTERSECTIONS" ); createGeomAction( GEOMOp::OpFastCheckInters, "FAST_CHECK_INTERSECTIONS" ); +#ifndef DISABLE_PLOT2DVIEWER createGeomAction( GEOMOp::OpShapeStatistics, "SHAPE_STATISTICS" ); +#endif +#ifndef DISABLE_PYCONSOLE #ifdef _DEBUG_ // PAL16821 createGeomAction( GEOMOp::OpCheckGeom, "CHECK_GEOMETRY" ); +#endif #endif createGeomAction( GEOMOp::OpMaterialsLibrary, "MATERIALS_LIBRARY" ); @@ -1093,7 +1107,9 @@ void GeometryGUI::initialize( CAM_Application* app ) createGeomAction( GEOMOp::OpPredefMaterCustom, "POP_PREDEF_MATER_CUSTOM" ); createGeomAction( GEOMOp::OpCreateFolder, "POP_CREATE_FOLDER" ); createGeomAction( GEOMOp::OpSortChildren, "POP_SORT_CHILD_ITEMS" ); +#ifndef DISABLE_GRAPHICSVIEW createGeomAction( GEOMOp::OpShowDependencyTree, "POP_SHOW_DEPENDENCY_TREE" ); +#endif createGeomAction( GEOMOp::OpReduceStudy, "POP_REDUCE_STUDY" ); createGeomAction( GEOMOp::OpShowAllDimensions, "POP_SHOW_ALL_DIMENSIONS" ); createGeomAction( GEOMOp::OpHideAllDimensions, "POP_HIDE_ALL_DIMENSIONS" ); @@ -1299,12 +1315,16 @@ void GeometryGUI::initialize( CAM_Application* app ) createMenu( GEOMOp::OpCheckSelfInters, measurId, -1 ); createMenu( GEOMOp::OpFastCheckInters, measurId, -1 ); createMenu( GEOMOp::OpInspectObj, measurId, -1 ); +#ifndef DISABLE_PLOT2DVIEWER createMenu( GEOMOp::OpShapeStatistics, measurId, -1 ); +#endif int toolsId = createMenu( tr( "MEN_TOOLS" ), -1, -1, 50 ); +#ifndef DISABLE_PYCONSOLE #if defined(_DEBUG_) || defined(_DEBUG) // PAL16821 createMenu( separator(), toolsId, -1 ); createMenu( GEOMOp::OpCheckGeom, toolsId, -1 ); +#endif #endif createMenu( separator(), toolsId, -1 ); @@ -1633,9 +1653,11 @@ void GeometryGUI::initialize( CAM_Application* app ) mgr->insert( action( GEOMOp::OpSortChildren ), -1, -1 ); // Sort child items mgr->setRule( action( GEOMOp::OpSortChildren ), QString("client='ObjectBrowser' and $component={'GEOM'} and nbChildren>1"), QtxPopupMgr::VisibleRule ); +#ifndef DISABLE_GRAPHICSVIEW mgr->insert( separator(), -1, -1 ); // ----------- mgr->insert( action( GEOMOp::OpShowDependencyTree ), -1, -1 ); // Show dependency tree mgr->setRule( action( GEOMOp::OpShowDependencyTree ), clientOCCorVTKorOB + " and selcount>0 and ($component={'GEOM'}) and type='Shape'", QtxPopupMgr::VisibleRule ); +#endif mgr->insert( separator(), -1, -1 ); // ----------- mgr->insert( action( GEOMOp::OpReduceStudy ), -1, -1 ); // Reduce Study @@ -1756,17 +1778,18 @@ bool GeometryGUI::activateModule( SUIT_Study* study ) // import Python module that manages GEOM plugins (need to be here because SalomePyQt API uses active module) PyGILState_STATE gstate = PyGILState_Ensure(); - PyObjWrapper pluginsmanager = PyImport_ImportModuleNoBlock((char*)"salome_pluginsmanager"); + PyObject* pluginsmanager = PyImport_ImportModuleNoBlock((char*)"salome_pluginsmanager"); if ( !pluginsmanager ) { PyErr_Print(); } else { - PyObjWrapper result = + PyObject* result = PyObject_CallMethod(pluginsmanager, (char*)"initialize", (char*)"isss", 1, "geom", tr("MEN_NEW_ENTITY").toUtf8().data(), tr("GEOM_PLUGINS_OTHER").toUtf8().data()); if ( !result ) PyErr_Print(); + Py_XDECREF(result); } PyGILState_Release(gstate); // end of GEOM plugins loading @@ -1835,6 +1858,7 @@ bool GeometryGUI::activateModule( SUIT_Study* study ) } } + Py_XDECREF(pluginsmanager); return true; } @@ -1921,7 +1945,9 @@ void GeometryGUI::windows( QMap& mappa ) const { mappa.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea ); mappa.insert( SalomeApp_Application::WT_NoteBook, Qt::LeftDockWidgetArea ); +#ifndef DISABLE_PYCONSOLE mappa.insert( SalomeApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea ); +#endif if ( myCreationInfoWdg ) mappa.insert( myCreationInfoWdg->getWinID(), Qt::LeftDockWidgetArea ); if ( myTextTreeWdg ) diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h index 865ac91d9..480b7d2fd 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -26,7 +26,9 @@ namespace GEOMOp { enum { // ToolsGUI --------------------//-------------------------------- OpDelete = 1020, // MENU EDIT - DELETE +#ifndef DISABLE_PYCONSOLE OpCheckGeom = 1030, // MENU TOOLS - CHECK GEOMETRY +#endif OpMaterialsLibrary = 1040, // MENU TOOLS - MATERIALS LIBRARY OpSelectVertex = 1100, // POPUP MENU - SELECT ONLY - VERTEX OpSelectEdge = 1101, // POPUP MENU - SELECT ONLY - EDGE @@ -59,7 +61,9 @@ namespace GEOMOp { OpIsosWidth = 1261, // POPUP MENU - LINE WIDTH - ISOS WIDTH OpCreateFolder = 1262, // POPUP MENU - CREATE FOLDER OpSortChildren = 1263, // POPUP MENU - SORT CHILD ITEMS +#ifndef DISABLE_GRAPHICSVIEW OpShowDependencyTree = 1264, // POPUP MENU - SHOW DEPENDENCY TREE +#endif OpReduceStudy = 1265, // POPUP MENU - REDUCE STUDY // DisplayGUI ------------------//-------------------------------- OpSwitchVectors = 2001, // MENU VIEW - DISPLAY MODE - SHOW/HIDE EDGE DIRECTION @@ -199,8 +203,10 @@ namespace GEOMOp { OpShowAllDimensions = 5015, // POPUP MENU - SHOW ALL DIMENSIONS OpHideAllDimensions = 5016, // POPUP MENU - HIDE ALL DIMENSIONS OpFastCheckInters = 5017, // MENU MEASURES - FAST CHECK INTERSECTIONS - OpInspectObj = 5018, // MENU MEASURES - INSPECT OBJECT + OpInspectObj = 5018, // MENU MEASURES - INSPECT OBJECT +#ifndef DISABLE_PLOT2DVIEWER OpShapeStatistics = 5019, // MENU MEASURES - SHAPE STATISTICS +#endif // GroupGUI --------------------//-------------------------------- OpGroupCreate = 6000, // MENU GROUP - CREATE OpGroupEdit = 6001, // MENU GROUP - EDIT diff --git a/src/GEOMToolsGUI/CMakeLists.txt b/src/GEOMToolsGUI/CMakeLists.txt index ea18e8b90..cb3e004cb 100755 --- a/src/GEOMToolsGUI/CMakeLists.txt +++ b/src/GEOMToolsGUI/CMakeLists.txt @@ -58,8 +58,13 @@ SET(_link_LIBRARIES GEOM GEOMBase Material - DependencyTree ) + +IF(SALOME_USE_GRAPHICSVIEW) + LIST(APPEND _link_LIBRARIES + DependencyTree + ) +ENDIF() # --- headers --- diff --git a/src/GEOMToolsGUI/GEOMToolsGUI.cxx b/src/GEOMToolsGUI/GEOMToolsGUI.cxx index 5fe45f595..7a437d272 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI.cxx @@ -206,9 +206,11 @@ bool GEOMToolsGUI::OnGUIEvent(int theCommandID, SUIT_Desktop* parent) case GEOMOp::OpDelete: // EDIT - DELETE OnEditDelete(); break; +#ifndef DISABLE_PYCONSOLE case GEOMOp::OpCheckGeom: // TOOLS - CHECK GEOMETRY OnCheckGeometry(); break; +#endif case GEOMOp::OpSelectVertex: // POPUP - SELECT ONLY - VERTEX OnSelectOnly( GEOM_POINT ); break; @@ -306,9 +308,11 @@ bool GEOMToolsGUI::OnGUIEvent(int theCommandID, SUIT_Desktop* parent) case GEOMOp::OpSortChildren: OnSortChildren(); break; +#ifndef DISABLE_GRAPHICSVIEW case GEOMOp::OpShowDependencyTree: OnShowDependencyTree(); break; +#endif case GEOMOp::OpReduceStudy: OnReduceStudy(); break; diff --git a/src/GEOMToolsGUI/GEOMToolsGUI.h b/src/GEOMToolsGUI/GEOMToolsGUI.h index 581d10f7b..6916bdfa8 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI.h +++ b/src/GEOMToolsGUI/GEOMToolsGUI.h @@ -87,7 +87,9 @@ private: void OnClsBringToFront(); void OnCreateFolder(); void OnSortChildren(); +#ifndef DISABLE_GRAPHICSVIEW void OnShowDependencyTree(); +#endif void OnReduceStudy(); // Shortcut commands diff --git a/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx b/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx index d00c98d24..b83b3e77e 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI_1.cxx @@ -24,7 +24,9 @@ // File : GEOMToolsGUI_1.cxx // Author : Sergey ANIKIN, Open CASCADE S.A.S. (sergey.anikin@opencascade.com) +#ifndef DISABLE_PYCONSOLE #include +#endif #include "GEOMToolsGUI.h" #include "GEOMToolsGUI_TransparencyDlg.h" @@ -47,9 +49,11 @@ #include #include +#ifndef DISABLE_GRAPHICSVIEW #include #include #include +#endif #include @@ -126,6 +130,7 @@ // on Show Dependencies operation #define LAYOUT_DEPVIEW +#ifndef DISABLE_PYCONSOLE void GEOMToolsGUI::OnCheckGeometry() { SalomeApp_Application* app = @@ -135,6 +140,7 @@ void GEOMToolsGUI::OnCheckGeometry() if (pyConsole) pyConsole->exec("from GEOM_usinggeom import *"); } +#endif void GEOMToolsGUI::OnAutoColor() { @@ -882,6 +888,7 @@ void GEOMToolsGUI::OnSortChildren() app->updateObjectBrowser( true ); } +#ifndef DISABLE_GRAPHICSVIEW void GEOMToolsGUI::OnShowDependencyTree() { SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); @@ -932,6 +939,7 @@ void GEOMToolsGUI::OnShowDependencyTree() #endif depVw->setFocus(); } +#endif void GEOMToolsGUI::OnReduceStudy() { diff --git a/src/GroupGUI/GroupGUI_GroupDlg.cxx b/src/GroupGUI/GroupGUI_GroupDlg.cxx index a13236cd2..984bc28c2 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.cxx +++ b/src/GroupGUI/GroupGUI_GroupDlg.cxx @@ -31,7 +31,9 @@ #include #include #include +#ifndef DISABLE_PLOT2DVIEWER #include +#endif #include #include @@ -201,7 +203,9 @@ GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QW myLessFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp); myGreaterFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp); myApplyFilterButton = new QPushButton(tr("GEOM_BUT_APPLY"), myFilterGrp); +#ifndef DISABLE_PLOT2DVIEWER myPlotDistributionButton = new QPushButton(tr("GEOM_PLOT_DISTRIBUTION"), myFilterGrp); +#endif QGridLayout* filterLayout = new QGridLayout(myFilterGrp); filterLayout->addWidget(myLessFilterCheck, 0, 0); @@ -211,7 +215,9 @@ GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QW filterLayout->addWidget(myGreaterFilterCombo, 1, 1); filterLayout->addWidget(myGreaterFilterSpin, 1, 2); filterLayout->addWidget(myApplyFilterButton, 0, 3); +#ifndef DISABLE_PLOT2DVIEWER filterLayout->addWidget(myPlotDistributionButton, 1, 3); +#endif QVBoxLayout* layout = new QVBoxLayout(centralWidget()); layout->setMargin(0); layout->setSpacing(6); @@ -329,7 +335,9 @@ void GroupGUI_GroupDlg::Init() connect(myIdList, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged())); connect(myApplyFilterButton, SIGNAL(clicked()), this, SLOT(ClickOnOkFilter())); +#ifndef DISABLE_PLOT2DVIEWER connect(myPlotDistributionButton, SIGNAL(clicked()), this, SLOT(ClickOnPlot())); +#endif connect(myLessFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled())); connect(myGreaterFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled())); @@ -1157,12 +1165,14 @@ void GroupGUI_GroupDlg::updateState (bool isAdd) GEOM::GEOM_IShapesOperations_var aShOp = getGeomEngine()->GetIShapesOperations( getStudyId() ); GEOM::ListOfLong_var aSubShapes = aShOp->SubShapeAllIDs( myMainObj, getShapeType(), false ); bool hasCurrentEntities = aSubShapes->length() > 0; +#ifndef DISABLE_PLOT2DVIEWER myPlotDistributionButton->setEnabled( myFilterGrp->isEnabled() && myIsShapeType && ( getShapeType() == TopAbs_EDGE || getShapeType() == TopAbs_FACE || getShapeType() == TopAbs_SOLID ) && hasCurrentEntities ); +#endif if (subSelectionWay() == ALL_SUBSHAPES) setInPlaceObj(GEOM::GEOM_Object::_nil()); } @@ -1451,6 +1461,7 @@ void GroupGUI_GroupDlg::ClickOnOkFilter() updateState(true); } +#ifndef DISABLE_PLOT2DVIEWER //================================================================================= // function : ClickOnPlot() // purpose : opens "Shape Statistics" dialog box in order to plot sub-shapes distribution. @@ -1463,6 +1474,7 @@ void GroupGUI_GroupDlg::ClickOnPlot() dlg->show(); } } +#endif void GroupGUI_GroupDlg::MeasureToggled() { diff --git a/src/GroupGUI/GroupGUI_GroupDlg.h b/src/GroupGUI/GroupGUI_GroupDlg.h index 231ea033a..06ecae4cf 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.h +++ b/src/GroupGUI/GroupGUI_GroupDlg.h @@ -83,7 +83,9 @@ private slots: void showOnlySelected(); void selectionChanged(); void ClickOnOkFilter(); +#ifndef DISABLE_PLOT2DVIEWER void ClickOnPlot(); +#endif void MeasureToggled(); private: diff --git a/src/MeasureGUI/CMakeLists.txt b/src/MeasureGUI/CMakeLists.txt index 31e2375ac..0f3761522 100755 --- a/src/MeasureGUI/CMakeLists.txt +++ b/src/MeasureGUI/CMakeLists.txt @@ -129,8 +129,13 @@ SET(_moc_HEADERS MeasureGUI_ManageDimensionsDlg.h MeasureGUI_CreateDimensionDlg.h MeasureGUI_DimensionInteractor.h - MeasureGUI_ShapeStatisticsDlg.h ) + +IF(SALOME_USE_PLOT2DVIEWER) + LIST(APPEND _moc_HEADERS + MeasureGUI_ShapeStatisticsDlg.h + ) +ENDIF() # header files / uic wrappings QT4_WRAP_UI(_uic_HEADERS ${_uic_files}) @@ -164,11 +169,16 @@ SET(MeasureGUI_SOURCES MeasureGUI_DimensionCreateTool.cxx MeasureGUI_DimensionInteractor.cxx MeasureGUI_DimensionFilter.cxx - MeasureGUI_ShapeStatisticsDlg.cxx ${_moc_SOURCES} ${_uic_files} ) +IF(SALOME_USE_PLOT2DVIEWER) + LIST(APPEND MeasureGUI_SOURCES + MeasureGUI_ShapeStatisticsDlg.cxx + ) +ENDIF() + # --- rules --- ADD_LIBRARY(MeasureGUI ${MeasureGUI_SOURCES}) diff --git a/src/MeasureGUI/MeasureGUI.cxx b/src/MeasureGUI/MeasureGUI.cxx index 1ab692d32..d76f132ff 100644 --- a/src/MeasureGUI/MeasureGUI.cxx +++ b/src/MeasureGUI/MeasureGUI.cxx @@ -53,7 +53,9 @@ #include "MeasureGUI_FastCheckIntersectionsDlg.h" // Method FAST CHECK INTERSCTIONS #include "MeasureGUI_PointDlg.h" // Method POINTCOORDINATES #include "MeasureGUI_ManageDimensionsDlg.h" // Method MANAGEDIMENSIONS +#ifndef DISABLE_PLOT2DVIEWER #include "MeasureGUI_ShapeStatisticsDlg.h" // Method SHAPE STATISTICS +#endif #include @@ -130,9 +132,11 @@ bool MeasureGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent ) case GEOMOp::OpFastCheckInters: dlg = new MeasureGUI_FastCheckIntersectionsDlg( getGeometryGUI(), parent ); break; // FAST CHECK INTERSCTIONS +#ifndef DISABLE_PLOT2DVIEWER case GEOMOp::OpShapeStatistics: dlg = new MeasureGUI_ShapeStatisticsDlg( parent ); - break; // FAST CHECK INTERSCTIONS + break; // SHAPE STATISTICS +#endif case GEOMOp::OpPointCoordinates: dlg = new MeasureGUI_PointDlg( getGeometryGUI(), parent ); break; // POINT COORDINATES From 9282e3d0d612f89cf50ea8d8dccfb920e0c0d941 Mon Sep 17 00:00:00 2001 From: ana Date: Wed, 17 Jun 2015 13:53:43 +0300 Subject: [PATCH 19/54] Windows compatibility --- src/MeasureGUI/CMakeLists.txt | 1 + .../MeasureGUI_ShapeStatisticsDlg.h | 3 +- src/MeasureGUI/MeasureGUI_definitions.h | 33 +++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/MeasureGUI/MeasureGUI_definitions.h diff --git a/src/MeasureGUI/CMakeLists.txt b/src/MeasureGUI/CMakeLists.txt index 0f3761522..eaae08f27 100755 --- a/src/MeasureGUI/CMakeLists.txt +++ b/src/MeasureGUI/CMakeLists.txt @@ -104,6 +104,7 @@ SET(MeasureGUI_HEADERS MeasureGUI_DimensionCreateTool.h MeasureGUI_DimensionInteractor.h MeasureGUI_DimensionFilter.h + MeasureGUI_definitions.h ) # header files / to be processed by moc diff --git a/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h index 80131321b..8b604a261 100644 --- a/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h +++ b/src/MeasureGUI/MeasureGUI_ShapeStatisticsDlg.h @@ -27,6 +27,7 @@ // GEOM includes #include #include "GEOM_GenericObjPtr.h" +#include "MeasureGUI_definitions.h" // Qt includes #include @@ -45,7 +46,7 @@ class Plot2d_Histogram; // purpose : //========================================================================== -class MeasureGUI_ShapeStatisticsDlg : public QDialog, public GEOMBase_Helper +class MEASUREGUI_EXPORT MeasureGUI_ShapeStatisticsDlg : public QDialog, public GEOMBase_Helper { Q_OBJECT diff --git a/src/MeasureGUI/MeasureGUI_definitions.h b/src/MeasureGUI/MeasureGUI_definitions.h new file mode 100644 index 000000000..f61720001 --- /dev/null +++ b/src/MeasureGUI/MeasureGUI_definitions.h @@ -0,0 +1,33 @@ +// Copyright (C) 2015 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, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef MEASUREGUI_DEF_HXX +#define MEASUREGUI_DEF_HXX + +#ifdef WIN32 +# if defined MEASUREGUI_EXPORTS || defined MeasureGUI_EXPORTS +# define MEASUREGUI_EXPORT __declspec( dllexport ) +# else +# define MEASUREGUI_EXPORT __declspec( dllimport ) +# endif +#else +# define MEASUREGUI_EXPORT +#endif + +#endif \ No newline at end of file From 1f1f0404456a71488cbcbc49574aeb65edd26c6b Mon Sep 17 00:00:00 2001 From: vsr Date: Wed, 17 Jun 2015 18:13:07 +0300 Subject: [PATCH 20/54] 0023115: [CEA 1545] Regression on KindOfShape method --- src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx | 51 ++++++++++---------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index ff068838b..e60150562 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -528,35 +528,34 @@ GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape theDoubles->Append(aD.X()); theDoubles->Append(aD.Y()); theDoubles->Append(aD.Z()); + + if (anInfo.KindOfBounds() != GEOMAlgo_KB_INFINITE) + { + // (+) geompy.kind.PLANAR xo yo zo dx dy dz nb_edges nb_vertices + + aKind = SK_PLANAR; + + gp_Pnt aC = anInfo.Location(); + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); + } } break; default: - if (anInfo.KindOfShape() == GEOMAlgo_KS_PLANE) { - // (+) geompy.kind.PLANAR xo yo zo dx dy dz nb_edges nb_vertices - - aKind = SK_PLANAR; - - gp_Pnt aC = anInfo.Location(); - theDoubles->Append(aC.X()); - theDoubles->Append(aC.Y()); - theDoubles->Append(aC.Z()); - - gp_Ax3 anAx3 = anInfo.Position(); - gp_Dir aD = anAx3.Direction(); - theDoubles->Append(aD.X()); - theDoubles->Append(aD.Y()); - theDoubles->Append(aD.Z()); - - theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE)); - theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); - } - else { - // ??? geompy.kind.FACE nb_edges nb_vertices _surface_type_id_ - // (+) geompy.kind.FACE nb_edges nb_vertices - - theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE)); - theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); - } + // ??? geompy.kind.FACE nb_edges nb_vertices _surface_type_id_ + // (+) geompy.kind.FACE nb_edges nb_vertices + theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); } } break; From 29ae7886c0ea9073341d0cd28c492ffe47835099 Mon Sep 17 00:00:00 2001 From: skv Date: Fri, 19 Jun 2015 10:51:17 +0300 Subject: [PATCH 21/54] 0022776: [CEA 1269] Project a wire or a face on a cylinder: rm instability in RemoveExtraEdges --- src/BlockFix/BlockFix_UnionFaces.cxx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/BlockFix/BlockFix_UnionFaces.cxx b/src/BlockFix/BlockFix_UnionFaces.cxx index c1b56f260..c1788bbb1 100644 --- a/src/BlockFix/BlockFix_UnionFaces.cxx +++ b/src/BlockFix/BlockFix_UnionFaces.cxx @@ -138,8 +138,9 @@ static Standard_Boolean AddOrdinaryEdges(TopTools_SequenceOfShape& edges, { //map of edges TopTools_MapOfShape aNewEdges; + TopExp_Explorer exp(aShape,TopAbs_EDGE); //add edges without seams - for(TopExp_Explorer exp(aShape,TopAbs_EDGE); exp.More(); exp.Next()) { + for(; exp.More(); exp.Next()) { TopoDS_Shape edge = exp.Current(); if(aNewEdges.Contains(edge)) aNewEdges.Remove(edge); @@ -164,9 +165,14 @@ static Standard_Boolean AddOrdinaryEdges(TopTools_SequenceOfShape& edges, } } - //add edges to the sequemce - for(TopTools_MapIteratorOfMapOfShape anIter(aNewEdges); anIter.More(); anIter.Next()) - edges.Append(anIter.Key()); + //add edges to the sequence + for(exp.ReInit(); exp.More(); exp.Next()) { + const TopoDS_Shape &anEdge = exp.Current(); + + if (aNewEdges.Contains(anEdge)) { + edges.Append(anEdge); + } + } return isDropped; } From 73a01143914fb0dad78b3cbc3c468da3c9410267 Mon Sep 17 00:00:00 2001 From: skv Date: Thu, 16 Jul 2015 10:51:04 +0300 Subject: [PATCH 22/54] 0023122: EDF 11178 GEOM: Fuse between a cylinder and a part with a hole fails --- src/BlockFix/BlockFix_UnionEdges.cxx | 35 ++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/BlockFix/BlockFix_UnionEdges.cxx b/src/BlockFix/BlockFix_UnionEdges.cxx index 4647d9e55..62a0307c5 100644 --- a/src/BlockFix/BlockFix_UnionEdges.cxx +++ b/src/BlockFix/BlockFix_UnionEdges.cxx @@ -88,6 +88,37 @@ #include "utilities.h" +//======================================================================= +//function : IsToMerge +//purpose : This method return Standard_True if two edges have common +// vertex. This vertex is returned by output parameter. The +// difference with the method TopExp::CommonVertex is only in +// the case if there are two common vertices. In this case +// this method returns the last vertex of theEdge1, not the first +// one that TopExp::CommonVertex does. +//======================================================================= +static Standard_Boolean GetCommonVertex(const TopoDS_Edge &theEdge1, + const TopoDS_Edge &theEdge2, + TopoDS_Vertex &theCommon) +{ + Standard_Boolean isFound = Standard_True; + ShapeAnalysis_Edge aSae; + TopoDS_Vertex aVF1 = aSae.FirstVertex(theEdge1); + TopoDS_Vertex aVL1 = aSae.LastVertex(theEdge1); + TopoDS_Vertex aVF2 = aSae.FirstVertex(theEdge2); + TopoDS_Vertex aVL2 = aSae.LastVertex(theEdge2); + + if (aVL1.IsSame(aVF2) || aVL1.IsSame(aVL2)) { + theCommon = aVL1; + } else if (aVF1.IsSame(aVL2) || aVF1.IsSame(aVF2)) { + theCommon = aVF1; + } else { + theCommon.Nullify(); + isFound = Standard_False; + } + + return isFound; +} //======================================================================= //function : IsToMerge @@ -148,7 +179,7 @@ static Standard_Boolean IsToMerge // that are connected to the common vertex. TopoDS_Vertex aVCommon; - if (TopExp::CommonVertex(theEdge1, theEdge2, aVCommon)) { + if (GetCommonVertex(theEdge1, theEdge2, aVCommon)) { TopTools_IndexedDataMapOfShapeListOfShape aMapVE; TopExp::MapShapesAndAncestors @@ -328,7 +359,7 @@ static TopoDS_Edge GlueEdgesWithPCurves(const TopTools_SequenceOfShape& aChain, if (i > 1) { - TopExp::CommonVertex(PrevEdge, anEdge, CV); + GetCommonVertex(PrevEdge, anEdge, CV); Standard_Real Tol = BRep_Tool::Tolerance(CV); tabtolvertex(i-2) = Tol; } From 28c8e9fe42aecec565a46fe489967cad4f705a26 Mon Sep 17 00:00:00 2001 From: eap Date: Thu, 16 Jul 2015 20:45:48 +0300 Subject: [PATCH 23/54] IPAL52828: No Creation Info available for a GEOM object imported from XAO file --- resources/CMakeLists.txt | 1 + resources/import.png | Bin 0 -> 1125 bytes src/GEOMGUI/GEOMGUI_CreationInfoWdg.cxx | 5 ++++- src/GEOMGUI/GEOM_images.ts | 4 ++++ src/XAOPlugin/XAOPlugin_Driver.cxx | 21 +++++++++++++++++++-- src/XAOPlugin/XAOPlugin_Driver.hxx | 14 +++++++++----- src/XAOPlugin/XAOPlugin_IOperations.cxx | 2 ++ 7 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 resources/import.png diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 44d86e7bc..3d47d93ed 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -114,6 +114,7 @@ SET( _res_files fuse_collinear_edges.png geometry.png import_picture.png + import.png limit_tolerance.png line.png line2points.png diff --git a/resources/import.png b/resources/import.png new file mode 100644 index 0000000000000000000000000000000000000000..71690c91278061869208d982bdf33e554c83000d GIT binary patch literal 1125 zcmV-r1e*JaP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2j2$} z5i2ro#_D?j00ZSoL_t(I%Z-#xh?Z3thOg(mKl7_K<_KX7qsa6_1=%7^h8EGHMPRxp zgxVBV7)(Ua!bQt+BeWRkXHlR*EsTh=G;on=Xr+dxmZgG@GdeThH#6_|e(%rud0Kqa zP!QI=JUrazy6?kz1mNB6tG3_!$hMvRx2{Sx1Vsdq2$1N~`QvBze6(-Jz7zZb)PQmm z#Q-A@ZQkP*uf#qG+c@+@E81k9R z;qb9DSN9%uB@kkO{*`M@wQvosTM(s)iNVBJTBQ9k+g^C%srl*4PfC=ihyVg&5EGlK zTyS|Y{>kQIKUBjYfks zO?Yw3!@E{4J9lFy3uj^gj37}8>JgJLHQQo*{}qNG8^e0A&f~liR0#@Y?aAxFuit;k z>95AwwCUxMynH_gqIjvzC`AbTboMF-e(PfOhNo%GH?W#gEgGsSAt+Ud_~FyHaosEF zUporGYg>o!uB(NgJBDH~Q5T1fo#TT~4$wQemJ6r8Bg-fyahOsYCh~Wz8(XZD5AEGZ0-i-fMT7{vXEP-)L=u5qM#6I1PHz^@U}vO z2cWEN_nGq-wPR=!S_=&pY&WU_?;V7I!4pd$iaT@&n8?%Hosf#fNJVcd04y}8nV6bc zy-1kSYF=k*w#D*w23uKbuUNV|g@_=s_;|kN+YfiJtm^`)afGcK(dk3$fpcTqHg!5w zRTP-K(PWtl)&`sl|N6CdZ8*s-3BfH)82`6(AA*Od6S>IeNKFsT`HY^}^3s}v+}_<> z8dlXMQgvO}+DcipLsjJj>xhyx_z=8_(~ee*(BKgxcyCb+1ZVMCqcbl8A>g&5 z3|=Q@>w2;cr_@mZ}hh0KTfVElTc#ejNj} z=O%|}HgT;92%(cvg#VI=*np|BcDUwg+!VZlWN@xPUb0a%&ND zWqDt8Wc>4sg#c#bI`huPdsaN_G>L--L_lw{mt!Lu8POz`Ac9WJ+B?5EJ~P#5>3sr3 rz-_Ff_RT#jgcd#r00000NkvXXu0mjf?`R5i literal 0 HcmV?d00001 diff --git a/src/GEOMGUI/GEOMGUI_CreationInfoWdg.cxx b/src/GEOMGUI/GEOMGUI_CreationInfoWdg.cxx index 5c3681e28..35a59ccfb 100644 --- a/src/GEOMGUI/GEOMGUI_CreationInfoWdg.cxx +++ b/src/GEOMGUI/GEOMGUI_CreationInfoWdg.cxx @@ -124,7 +124,10 @@ void GEOMGUI_CreationInfoWdg::setInfo( GEOM::CreationInformationSeq& info ) } // get icon QString prefix = plugin_name.isEmpty() ? "GEOM" : plugin_name; - icon = resMgr->loadPixmap( prefix, tr( ("ICO_"+name).toLatin1().constData() ), false ); + if ( name.startsWith( "Import")) + icon = resMgr->loadPixmap( "GEOM", tr("ICO_IMPORT_SHAPE"), true ); + else + icon = resMgr->loadPixmap( prefix, tr( ("ICO_"+name).toLatin1().constData() ), false ); // translate operation name operationName = tr( ("MEN_"+name).toLatin1().constData() ); diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index 1e906fe81..cfcccd313 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -1387,6 +1387,10 @@ ICO_TRANSFER_DATA transfer_data.png
      + + ICO_IMPORT_SHAPE + import.png + ICON_DLG_POINT_FACE pointonface.png diff --git a/src/XAOPlugin/XAOPlugin_Driver.cxx b/src/XAOPlugin/XAOPlugin_Driver.cxx index 01803c136..607c7b3df 100644 --- a/src/XAOPlugin/XAOPlugin_Driver.cxx +++ b/src/XAOPlugin/XAOPlugin_Driver.cxx @@ -100,6 +100,23 @@ Standard_Integer XAOPlugin_Driver::Execute(TFunction_Logbook& log) const return 1; } -IMPLEMENT_STANDARD_HANDLE (XAOPlugin_Driver, TFunction_Driver); -IMPLEMENT_STANDARD_RTTIEXT(XAOPlugin_Driver, TFunction_Driver); +//======================================================================= +//function : GetCreationInformation +//purpose : Returns a name of creation operation and names and values of +// creation parameters +//======================================================================= + +bool XAOPlugin_Driver::GetCreationInformation(std::string& theOperationName, + std::vector& theParams) +{ + if (Label().IsNull()) return false; + Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label()); + + theOperationName = "ImportXAO"; + AddParam( theParams, "File name", function->GetString( GetFileNameTag() )); + return true; +} + +IMPLEMENT_STANDARD_HANDLE (XAOPlugin_Driver, GEOM_BaseDriver); +IMPLEMENT_STANDARD_RTTIEXT(XAOPlugin_Driver, GEOM_BaseDriver); diff --git a/src/XAOPlugin/XAOPlugin_Driver.hxx b/src/XAOPlugin/XAOPlugin_Driver.hxx index 1d36b839b..9a8885e96 100644 --- a/src/XAOPlugin/XAOPlugin_Driver.hxx +++ b/src/XAOPlugin/XAOPlugin_Driver.hxx @@ -23,12 +23,11 @@ #ifndef _XAOPlugin_Driver_HXX #define _XAOPlugin_Driver_HXX -// OCCT includes -#include +#include "GEOM_BaseDriver.hxx" -DEFINE_STANDARD_HANDLE(XAOPlugin_Driver, TFunction_Driver); +DEFINE_STANDARD_HANDLE(XAOPlugin_Driver, GEOM_BaseDriver); -class XAOPlugin_Driver: public TFunction_Driver +class XAOPlugin_Driver: public GEOM_BaseDriver { public: XAOPlugin_Driver(); @@ -39,7 +38,12 @@ public: Standard_Boolean MustExecute(const TFunction_Logbook&) const; virtual void Validate(TFunction_Logbook&) const {} -DEFINE_STANDARD_RTTI(XAOPlugin_Driver) + virtual bool GetCreationInformation(std::string& theOperationName, + std::vector& theParams); + + static int GetFileNameTag() { return 1; } // where to store file name in GEOM_Function + + DEFINE_STANDARD_RTTI(XAOPlugin_Driver) }; #endif // _XAOPlugin_Driver_HXX diff --git a/src/XAOPlugin/XAOPlugin_IOperations.cxx b/src/XAOPlugin/XAOPlugin_IOperations.cxx index d491cad2b..d8c886274 100644 --- a/src/XAOPlugin/XAOPlugin_IOperations.cxx +++ b/src/XAOPlugin/XAOPlugin_IOperations.cxx @@ -470,6 +470,8 @@ bool XAOPlugin_IOperations::ImportXAO( const char* fileName, if (function.IsNull()) return false; if (function->GetDriverGUID() != XAOPlugin_Driver::GetID()) return false; + function->SetString( XAOPlugin_Driver::GetFileNameTag(), fileName ); + // set the geometry if (xaoGeometry->getFormat() == XAO::BREP) { From 8851ec8d8f69aedca05141791a6f81239cb192b0 Mon Sep 17 00:00:00 2001 From: skv Date: Tue, 21 Jul 2015 18:29:07 +0300 Subject: [PATCH 24/54] 0022664: [CEA 1253] MakePipeWithDifferentSections fails on a elbow pipe --- doc/salome/examples/complex_objs_ex05.py | 16 +- doc/salome/gui/GEOM/images/pipe3.png | Bin 29124 -> 30885 bytes .../input/creating_extrusion_alongpath.doc | 17 +- idl/GEOM_Gen.idl | 9 +- src/GEOMGUI/GEOM_msg_en.ts | 4 + src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx | 22 +- src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx | 1 + src/GEOMImpl/GEOMImpl_IPipe.hxx | 1 + src/GEOMImpl/GEOMImpl_IPipeDiffSect.hxx | 6 + src/GEOMImpl/GEOMImpl_PipeDriver.cxx | 215 ++++++++++++++---- src/GEOMImpl/GEOMImpl_PipeDriver.hxx | 1 + src/GEOMImpl/GEOMImpl_PrismDriver.cxx | 3 +- src/GEOM_I/GEOM_I3DPrimOperations_i.cc | 3 +- src/GEOM_I/GEOM_I3DPrimOperations_i.hh | 1 + src/GEOM_I_Superv/GEOM_Superv_i.cc | 2 +- src/GEOM_PY/structelem/parts.py | 3 +- src/GEOM_SWIG/geomBuilder.py | 39 +++- src/GenerationGUI/GenerationGUI_PipeDlg.cxx | 59 +++-- src/GenerationGUI/GenerationGUI_PipeDlg.h | 2 + 19 files changed, 325 insertions(+), 79 deletions(-) diff --git a/doc/salome/examples/complex_objs_ex05.py b/doc/salome/examples/complex_objs_ex05.py index f38f0816b..f6681b587 100644 --- a/doc/salome/examples/complex_objs_ex05.py +++ b/doc/salome/examples/complex_objs_ex05.py @@ -18,18 +18,22 @@ 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) +# create pipes +Pipe1 = geompy.MakePipeWithDifferentSections(circles, vertices, Wire_1, 0, 0) +Pipe2 = geompy.MakePipeWithDifferentSectionsBySteps(circles, vertices, Wire_1) # 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") +id_wire = geompy.addToStudy(Wire_1, "Path") +id_pipe1 = geompy.addToStudy(Pipe1, "Pipe1") +id_pipe2 = geompy.addToStudy(Pipe2, "Pipe2") # display the wire(path) and the pipe gg.createAndDisplayGO(id_wire) -gg.createAndDisplayGO(id_pipe) -gg.setDisplayMode(id_pipe,1) +gg.createAndDisplayGO(id_pipe1) +gg.createAndDisplayGO(id_pipe2) +gg.setDisplayMode(id_pipe1,1) +gg.setDisplayMode(id_pipe2,1) diff --git a/doc/salome/gui/GEOM/images/pipe3.png b/doc/salome/gui/GEOM/images/pipe3.png index d1b7f403112e899f565dd7a357a33e951efaa125..c5c3149152a256cb0e62efc775af7a4aaebc1902 100644 GIT binary patch delta 13521 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 JizJQx{tG%MohtwU delta 11767 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 diff --git a/doc/salome/gui/GEOM/input/creating_extrusion_alongpath.doc b/doc/salome/gui/GEOM/input/creating_extrusion_alongpath.doc index 078089362..84260fe68 100644 --- a/doc/salome/gui/GEOM/input/creating_extrusion_alongpath.doc +++ b/doc/salome/gui/GEOM/input/creating_extrusion_alongpath.doc @@ -72,18 +72,33 @@ Additional controls: - If With contact is checked, the section is translated in contact with the spine. - If With correction is checked, the section is rotated to be orthogonal to the spine tangent in the corresponding point. +- If Step-by-step generation is checked, the result is created +step-by-step, i.e. it creates pipes between each pair of neighbor sections and +fuses them into a single shape. + +\note If Step-by-step generation is checked, With contact and +With correction controls are disabled as corrections of bases are +not allowed in step-by-step mode. Generate groups checkbox - if checked allows to create groups of sub-shapes. For more details on groups creation please refer to \ref create_groups_page "this description". \n The \b Result of the operation will be a shell or a solid. -\n TUI Command: geompy.MakePipeWithDifferentSections(baseShape, locations, pathShape, withContact, withCorrection, +\n TUI Commands: +- geompy.MakePipeWithDifferentSections(baseShape, locations, pathShape, withContact, withCorrection, IsGenerateGroups=False) \n Arguments: Name + list of shapes (edges, planar wires, faces or shells) serving as base object + list of locations (vertices) on the path corresponding specified list of the shapes + 1 shape (edge or wire) for definition of the path + 3 Boolean parameters (withContact, withCorrection, IsGenerateGroups). +- geompy.MakePipeWithDifferentSectionsBySteps(baseShape, locations, pathShape, + IsGenerateGroups=False) +\n Arguments: Name + list of shapes (edges, planar wires, faces or shells) serving as base object + +list of locations (vertices) on the path corresponding specified list of the shapes + +1 shape (edge or wire) for definition of the path + +Boolean parameter. + \n Advanced options \ref preview_anchor "Preview" \image html pipe3.png diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index d7c643562..4b56df001 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -1808,9 +1808,13 @@ module GEOM * should be equal to number of bases or list of locations can be empty. * \param thePath - Path shape to extrude the base shape along it. * \param theWithContact - the mode defining that the section is translated to be in - * contact with the spine. + * contact with the spine. Ignored if IsBySteps is set. * \param theWithCorrection - defining that the section is rotated to be - * orthogonal to the spine tangent in the correspondent point + * orthogonal to the spine tangent in + * the correspondent point. Ignored if IsBySteps is set. + * \param IsBySteps - flag that tells if the result should be created + * step by step or as a whole. If IsBySteps is set no correction + * of bases is allowed. * \param IsGenerateGroups flag that tells if it is necessary to * return groups (true) or not (false). * \return The list of objects. The first one is a result pipe, @@ -1823,6 +1827,7 @@ module GEOM in GEOM_Object thePath, in boolean theWithContact , in boolean theWithCorrection, + in boolean IsBySteps, in boolean IsGenerateGroups); /*! diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index d9ce747c7..606714b1e 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -1428,6 +1428,10 @@ Please, select face, shell or solid and try again GEOM_GROUP_NAME_PREFIX Group Names Prefix + + GEOM_STEP_BY_STEP + Step-by-step generation + GEOM_PLANE Plane diff --git a/src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx b/src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx index 017447071..4f46c1bbd 100644 --- a/src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_I3DPrimOperations.cxx @@ -1828,6 +1828,7 @@ Handle(TColStd_HSequenceOfTransient) const Handle(GEOM_Object) &thePath, const bool theWithContact, const bool theWithCorrections, + const bool IsBySteps, const bool IsGenerateGroups) { SetErrorCode(KO); @@ -1897,8 +1898,13 @@ Handle(TColStd_HSequenceOfTransient) aCI.SetBases(aSeqBases); aCI.SetLocations(aSeqLocs); aCI.SetPath(aRefPath); - aCI.SetWithContactMode(theWithContact); - aCI.SetWithCorrectionMode(theWithCorrections); + + if (!IsBySteps) { + aCI.SetWithContactMode(theWithContact); + aCI.SetWithCorrectionMode(theWithCorrections); + } + + aCI.SetIsBySteps(IsBySteps); aCI.SetGenerateGroups(IsGenerateGroups); //Compute the Pipe value @@ -1930,7 +1936,11 @@ Handle(TColStd_HSequenceOfTransient) pyDump << aPipeDS; } - pyDump << " = geompy.MakePipeWithDifferentSections(["; + if (IsBySteps) { + pyDump << " = geompy.MakePipeWithDifferentSectionsBySteps(["; + } else { + pyDump << " = geompy.MakePipeWithDifferentSections(["; + } for(i =1 ; i <= nbBases; i++) { @@ -1962,7 +1972,11 @@ Handle(TColStd_HSequenceOfTransient) } } - pyDump<< "], "<GetInteger(PIPEDS_ARG_WITHCORRECT); } + void SetIsBySteps (int IsBySteps) + { _func->SetInteger(PIPEDS_ARG_BY_STEPS, IsBySteps); } + + int GetIsBySteps() + { return _func->GetInteger(PIPEDS_ARG_BY_STEPS); } + }; #endif diff --git a/src/GEOMImpl/GEOMImpl_PipeDriver.cxx b/src/GEOMImpl/GEOMImpl_PipeDriver.cxx index 31f53f873..cf660675f 100644 --- a/src/GEOMImpl/GEOMImpl_PipeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PipeDriver.cxx @@ -43,8 +43,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -686,6 +688,42 @@ static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2, FS2 = Fs(numface); } +//======================================================================= +//function : RemoveFaces +//purpose : This function returns theShapeFrom without faces of the shape +// theFacesToRm. It returns a shell if theShapeFrom is a solid or +// a compound otherwise. Auxilary for CreatePipeWithDifferentSections +// method. +//======================================================================= +static TopoDS_Shape RemoveFaces(const TopoDS_Shape &theShapeFrom, + const TopoDS_Shape &theFacesToRm) +{ + TopTools_IndexedMapOfShape aMapFaces; + TopExp_Explorer anExp(theShapeFrom, TopAbs_FACE); + BRep_Builder aBuilder; + TopoDS_Shape aResult; + + if (theShapeFrom.ShapeType() == TopAbs_SOLID) { + // Create shell + aBuilder.MakeShell(TopoDS::Shell(aResult)); + } else { + // Create compound + aBuilder.MakeCompound(TopoDS::Compound(aResult)); + } + + TopExp::MapShapes(theFacesToRm, TopAbs_FACE, aMapFaces); + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aFace = anExp.Current(); + + if (!aMapFaces.Contains(aFace)) { + aBuilder.Add(aResult, aFace); + } + } + + return aResult; +} + //======================================================================= //function : CreatePipeWithDifferentSections //purpose : @@ -696,6 +734,7 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections const Handle(TopTools_HSequenceOfShape) theHSeqLocs, const Standard_Boolean theWithContact, const Standard_Boolean theWithCorrect, + const Standard_Boolean IsBySteps, Handle(TColStd_HArray1OfInteger) *theGroups) { TopoDS_Shape aShape; @@ -883,49 +922,82 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections } } - // check curvature of wire for condition that - // max summary angle between directions along - // wire path must be < 4*PI. If not - split wire - // and seguences of shapes, perform pipe for each - // and make sewing after that - double fp,lp; - gp_Pnt P1,P2; - gp_Vec Vec1,Vec2; - double SumAng = 0; - if ( Edges.Length() > 0 ) { - Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp); - C->D1(fp,P1,Vec1); - C->D1(lp,P2,Vec2); - SumAng = fabs(Vec1.Angle(Vec2)); - Vec1 = Vec2; - P1 = P2; - } TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums; - int LastLoc = 1; - //cout<<"Edges.Length()="<D1(lp,P2,Vec2); - double ang = fabs(Vec1.Angle(Vec2)); - SumAng += ang; - if (SumAng>4*M_PI) { - SumAng = ang; - SplitEdgeNums.Append(i-1); - int j; - for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) { - TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j)); - gp_Pnt P = BRep_Tool::Pnt(aVert); - if (P1.Distance(P) < tol) { - SplitLocNums.Append(j); - LastLoc = j; - break; - } + + if (IsBySteps) { + // Fill SplitEdgeNums and SplitLocNums with intermediate location indices + // and corresponding edge indices. + Standard_Integer i = 1; + Standard_Integer j; + TopoDS_Vertex aVert; + gp_Pnt aP; + + for (j = 2; j < aSeqLocs.Length(); j++) { + SplitLocNums.Append(j); + aVert = TopoDS::Vertex(aSeqLocs.Value(j)); + aP = BRep_Tool::Pnt(aVert); + + while (i < Edges.Length()) { + Standard_Real aFp; + Standard_Real aLp; + TopoDS_Edge anEdge = TopoDS::Edge(Edges.Value(i)); + Standard_Real aTol = BRep_Tool::Tolerance(anEdge); + Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aFp, aLp); + gp_Pnt aPLast; + + aC->D0(aLp, aPLast); + i++; + + if (aP.Distance(aPLast) < aTol) { + SplitEdgeNums.Append(i - 1); + break; } } + } + } else { + // check curvature of wire for condition that + // max summary angle between directions along + // wire path must be < 4*PI. If not - split wire + // and seguences of shapes, perform pipe for each + // and make sewing after that + double fp,lp; + gp_Pnt P1,P2; + gp_Vec Vec1,Vec2; + double SumAng = 0; + if ( Edges.Length() > 0 ) { + Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp); + C->D1(fp,P1,Vec1); + C->D1(lp,P2,Vec2); + SumAng = fabs(Vec1.Angle(Vec2)); Vec1 = Vec2; P1 = P2; + } + int LastLoc = 1; + //cout<<"Edges.Length()="<D1(lp,P2,Vec2); + double ang = fabs(Vec1.Angle(Vec2)); + SumAng += ang; + if (SumAng>4*M_PI) { + SumAng = ang; + SplitEdgeNums.Append(i-1); + int j; + for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) { + TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j)); + gp_Pnt P = BRep_Tool::Pnt(aVert); + if (P1.Distance(P) < tol) { + SplitLocNums.Append(j); + LastLoc = j; + break; + } + } + } + Vec1 = Vec2; + P1 = P2; + } } bool isCreateGroups = (theGroups != NULL); @@ -966,9 +1038,24 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid"); } - BuildPipeShell(aBuilder); + Standard_Boolean isDone = BuildPipeShell(aBuilder); + + if (isDone && NeedCreateSolid && nn == 1) { + // Make solid for the first step. + isDone = aBuilder.MakeSolid(); + } + + if (!isDone) { + Standard_ConstructionError::Raise("Pipe construction failure"); + } TopoDS_Shape resShape = aBuilder.Shape(); + + if (NeedCreateSolid && nn == 1) { + // Remove top lid from the result. + resShape = RemoveFaces(resShape, aBuilder.LastShape()); + } + aSeqRes.Append(resShape); // Create groups. @@ -1014,9 +1101,23 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid"); } - BuildPipeShell(aBuilder); + Standard_Boolean isDone = BuildPipeShell(aBuilder); + + if (isDone && NeedCreateSolid) { + isDone = aBuilder.MakeSolid(); + } + + if (!isDone) { + Standard_ConstructionError::Raise("Pipe construction failure"); + } TopoDS_Shape resShape = aBuilder.Shape(); + + if (NeedCreateSolid) { + // Remove bottom lid from the result. + resShape = RemoveFaces(resShape, aBuilder.FirstShape()); + } + aSeqRes.Append(resShape); // Create groups. @@ -1046,6 +1147,28 @@ TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections aSewing->Perform(); aShape = aSewing->SewedShape(); + if (NeedCreateSolid && aShape.ShapeType() == TopAbs_SHELL) { + // Build a solid. + BRepBuilderAPI_MakeSolid aMkSolid; + + aMkSolid.Add(TopoDS::Shell(aShape)); + + if (!aMkSolid.IsDone()) { + Standard_ConstructionError::Raise("Can't create solid pipe"); + } + + TopoDS_Solid aSolid = aMkSolid.Solid(); + BRepClass3d_SolidClassifier aSC(aSolid); + + aSC.PerformInfinitePoint(Precision::Confusion()); + + if (aSC.State() == TopAbs_IN) { + aShape = aSolid.Reversed(); + } else { + aShape = aSolid; + } + } + if (isCreateGroups) { // Replase Group shapes by modified ones. TopTools_SequenceOfShape aSeqGroups[5]; @@ -3032,6 +3155,7 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations (); Standard_Boolean aWithContact = (aCIDS->GetWithContactMode()); Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode()); + Standard_Boolean isBySteps = aCIDS->GetIsBySteps(); if (aCI) { delete aCI; @@ -3079,7 +3203,7 @@ Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const aShape = CreatePipeWithDifferentSections (aWirePath, aHSeqBases, aHSeqLocs, - aWithContact, aWithCorrect, pGroups); + aWithContact, aWithCorrect, isBySteps, pGroups); if (isGenerateGroups) { // Store created groups. @@ -3265,8 +3389,13 @@ GetCreationInformation(std::string& theOperationName, AddParam( theParams, "Bases", aCI.GetBases() ); AddParam( theParams, "Locations", aCI.GetLocations() ); AddParam( theParams, "Path", aCI.GetPath() ); - AddParam( theParams, "With contact", aCI.GetWithContactMode() ); - AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() ); + + if (!aCI.GetIsBySteps()) { + AddParam( theParams, "With contact", aCI.GetWithContactMode() ); + AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() ); + } + + AddParam( theParams, "Step by step", aCI.GetIsBySteps() ); break; } case PIPE_SHELL_SECTIONS: diff --git a/src/GEOMImpl/GEOMImpl_PipeDriver.hxx b/src/GEOMImpl/GEOMImpl_PipeDriver.hxx index 3a4deca6f..767536946 100644 --- a/src/GEOMImpl/GEOMImpl_PipeDriver.hxx +++ b/src/GEOMImpl/GEOMImpl_PipeDriver.hxx @@ -88,6 +88,7 @@ public: const Handle(TopTools_HSequenceOfShape) theLocs, const Standard_Boolean theWithContact, const Standard_Boolean theWithCorrect, + const Standard_Boolean IsBySteps, Handle(TColStd_HArray1OfInteger) *theGroups = NULL); Standard_EXPORT virtual diff --git a/src/GEOMImpl/GEOMImpl_PrismDriver.cxx b/src/GEOMImpl/GEOMImpl_PrismDriver.cxx index 52f6d2109..48e5353ea 100644 --- a/src/GEOMImpl/GEOMImpl_PrismDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PrismDriver.cxx @@ -351,7 +351,8 @@ TopoDS_Shape GEOMImpl_PrismDriver::MakeScaledPrism (const TopoDS_Shape& theShape aLocs->Append(aShapeCDG_1); aLocs->Append(aShapeCDG_2); - aShape = GEOMImpl_PipeDriver::CreatePipeWithDifferentSections(aWirePath, aBases, aLocs, false, false); + aShape = GEOMImpl_PipeDriver::CreatePipeWithDifferentSections + (aWirePath, aBases, aLocs, false, false, false); // 7. Make a solid, if possible if (theShapeBase.ShapeType() == TopAbs_FACE) { diff --git a/src/GEOM_I/GEOM_I3DPrimOperations_i.cc b/src/GEOM_I/GEOM_I3DPrimOperations_i.cc index 3d5969f71..41b415ded 100644 --- a/src/GEOM_I/GEOM_I3DPrimOperations_i.cc +++ b/src/GEOM_I/GEOM_I3DPrimOperations_i.cc @@ -987,6 +987,7 @@ GEOM::ListOfGO *GEOM_I3DPrimOperations_i::MakePipeWithDifferentSections GEOM::GEOM_Object_ptr thePath, CORBA::Boolean theWithContact, CORBA::Boolean theWithCorrections, + CORBA::Boolean IsBySteps, CORBA::Boolean IsGenerateGroups) { GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO; @@ -1029,7 +1030,7 @@ GEOM::ListOfGO *GEOM_I3DPrimOperations_i::MakePipeWithDifferentSections GetOperations()->MakePipeWithDifferentSections (aSeqBases, aSeqLocations, aPath, theWithContact, - theWithCorrections, IsGenerateGroups); + theWithCorrections, IsBySteps, IsGenerateGroups); if (!GetOperations()->IsDone() || aHSeq.IsNull()) return aSeq._retn(); diff --git a/src/GEOM_I/GEOM_I3DPrimOperations_i.hh b/src/GEOM_I/GEOM_I3DPrimOperations_i.hh index d5d8ea847..3fe2951eb 100644 --- a/src/GEOM_I/GEOM_I3DPrimOperations_i.hh +++ b/src/GEOM_I/GEOM_I3DPrimOperations_i.hh @@ -186,6 +186,7 @@ class GEOM_I_EXPORT GEOM_I3DPrimOperations_i : GEOM::GEOM_Object_ptr thePath, CORBA::Boolean theWithContact, CORBA::Boolean theWithCorrections, + CORBA::Boolean IsBySteps, CORBA::Boolean IsGenerateGroups); GEOM::ListOfGO* MakePipeWithShellSections diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.cc b/src/GEOM_I_Superv/GEOM_Superv_i.cc index bfd598ad5..449a3c6b8 100644 --- a/src/GEOM_I_Superv/GEOM_Superv_i.cc +++ b/src/GEOM_I_Superv/GEOM_Superv_i.cc @@ -1512,7 +1512,7 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakePipeWithDifferentSections beginService( " GEOM_Superv_i::MakePipeWithDifferentSections" ); MESSAGE("GEOM_Superv_i::MakePipeWithDifferentSections"); get3DPrimOp(); - GEOM::ListOfGO_var aList = my3DPrimOp->MakePipeWithDifferentSections(theBases,theLocations, thePath,theWithContact,theWithCorrections, false); + GEOM::ListOfGO_var aList = my3DPrimOp->MakePipeWithDifferentSections(theBases,theLocations, thePath,theWithContact,theWithCorrections, false, false); endService( " GEOM_Superv_i::MakePipeWithDifferentSections" ); return aList[0]; } diff --git a/src/GEOM_PY/structelem/parts.py b/src/GEOM_PY/structelem/parts.py index 5ab2f2474..ae1e59d0f 100644 --- a/src/GEOM_PY/structelem/parts.py +++ b/src/GEOM_PY/structelem/parts.py @@ -361,7 +361,8 @@ class Beam(StructuralElementPart): face2 = self.geom.MakeFace(wire2, True) shell = self.geom.MakePipeWithDifferentSections([wire1, wire2], [point1, point2], - path, False, False) + path, False, False, + False) closedShell = self.geom.MakeShell([face1, face2, shell]) solid = self.geom.MakeSolid([closedShell]) return solid diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 0e8257dec..d0eba918c 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -4037,7 +4037,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): aList = self.PrimOp.MakePipeWithDifferentSections(theSeqBases, theLocations, thePath, theWithContact, theWithCorrection, - IsGenerateGroups) + False, IsGenerateGroups) RaiseIfFailed("MakePipeWithDifferentSections", self.PrimOp) if IsGenerateGroups: @@ -4047,6 +4047,43 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): self._autoPublish(aList[0], theName, "pipe") return aList[0] + ## Create a shape by extrusion of the profile shape along + # the path shape. This function is a version of + # MakePipeWithShellSections() with the same parameters, except + # eliminated theWithContact and theWithCorrection. So it is + # possible to find the description of all parameters is in this + # method. The difference is that this method performs the operation + # step by step, i.e. it creates pipes between each pair of neighbor + # sections and fuses them into a single shape. + # + # @ref tui_creation_pipe_with_diff_sec "Example" + @ManageTransactions("PrimOp") + def MakePipeWithDifferentSectionsBySteps(self, theSeqBases, + theLocations, thePath, + IsGenerateGroups=False, theName=None): + """ + Create a shape by extrusion of the profile shape along + the path shape. This function is a version of + MakePipeWithShellSections() with the same parameters, except + eliminated theWithContact and theWithCorrection. So it is + possible to find the description of all parameters is in this + method. The difference is that this method performs the operation + step by step, i.e. it creates pipes between each pair of neighbor + sections and fuses them into a single shape. + """ + aList = self.PrimOp.MakePipeWithDifferentSections(theSeqBases, + theLocations, thePath, + False, False, + True, IsGenerateGroups) + RaiseIfFailed("MakePipeWithDifferentSectionsBySteps", self.PrimOp) + + if IsGenerateGroups: + self._autoPublish(aList, theName, "pipe") + return aList + + self._autoPublish(aList[0], theName, "pipe") + return aList[0] + ## Create a shape by extrusion of the profile shape along # the path shape. The path shape can be a wire or an edge. # the several profiles can be specified in the several locations of path. diff --git a/src/GenerationGUI/GenerationGUI_PipeDlg.cxx b/src/GenerationGUI/GenerationGUI_PipeDlg.cxx index 33b43b09f..703fe5ede 100644 --- a/src/GenerationGUI/GenerationGUI_PipeDlg.cxx +++ b/src/GenerationGUI/GenerationGUI_PipeDlg.cxx @@ -50,13 +50,14 @@ //================================================================================= GenerationGUI_PipeDlg::GenerationGUI_PipeDlg (GeometryGUI* theGeometryGUI, QWidget* parent, bool modal, Qt::WindowFlags fl) - : GEOMBase_Skeleton (theGeometryGUI, parent, modal, fl), - myGenGroupCheckGP (0), - myPrefixLblGP (0), - myPrefixEditGP (0), - myGenGroupCheckGMP (0), - myPrefixLblGMP (0), - myPrefixEditGMP (0) + : GEOMBase_Skeleton (theGeometryGUI, parent, modal, fl), + myGenGroupCheckGP (0), + myPrefixLblGP (0), + myPrefixEditGP (0), + myStepByStepCheckGMP (0), + myGenGroupCheckGMP (0), + myPrefixLblGMP (0), + myPrefixEditGMP (0) { QPixmap image0 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_PIPE"))); QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT"))); @@ -124,15 +125,18 @@ GenerationGUI_PipeDlg::GenerationGUI_PipeDlg (GeometryGUI* theGeometryGUI, QWidg // Add widgets for group generation QGridLayout *aLayoutGMP = (QGridLayout *)GroupMakePoints->GroupBox1->layout(); - myGenGroupCheckGMP = + myStepByStepCheckGMP = + new QCheckBox(tr("GEOM_STEP_BY_STEP"), GroupMakePoints->GroupBox1); + myGenGroupCheckGMP = new QCheckBox(tr("GEOM_GENERATE_GROUPS"), GroupMakePoints->GroupBox1); - myPrefixLblGMP = + myPrefixLblGMP = new QLabel (tr("GEOM_GROUP_NAME_PREFIX"), GroupMakePoints->GroupBox1); - myPrefixEditGMP = new QLineEdit(GroupMakePoints->GroupBox1); + myPrefixEditGMP = new QLineEdit(GroupMakePoints->GroupBox1); - aLayoutGMP->addWidget(myGenGroupCheckGMP, 8, 0, 1, 3); - aLayoutGMP->addWidget(myPrefixLblGMP, 9, 0, 1, 2); - aLayoutGMP->addWidget(myPrefixEditGMP, 9, 2); + aLayoutGMP->addWidget(myStepByStepCheckGMP, 8, 0, 1, 3); + aLayoutGMP->addWidget(myGenGroupCheckGMP, 9, 0, 1, 3); + aLayoutGMP->addWidget(myPrefixLblGMP, 10, 0, 1, 2); + aLayoutGMP->addWidget(myPrefixEditGMP, 10, 2); QVBoxLayout* layout = new QVBoxLayout(centralWidget()); layout->setMargin(0); layout->setSpacing(6); @@ -201,8 +205,10 @@ void GenerationGUI_PipeDlg::Init() connect(GroupMakePoints->PushButton3, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); connect(GroupMakePoints->CheckBox1, SIGNAL(clicked()), this, SLOT(processPreview())); connect(GroupMakePoints->CheckBox2, SIGNAL(clicked()), this, SLOT(processPreview())); - connect(myGenGroupCheckGP, SIGNAL(toggled(bool)), this, SLOT(GenGroupClicked(bool))); - connect(myGenGroupCheckGMP, SIGNAL(toggled(bool)), this, SLOT(GenGroupClicked(bool))); + connect(myStepByStepCheckGMP, SIGNAL(clicked()), this, SLOT(processPreview())); + connect(myGenGroupCheckGP, SIGNAL(toggled(bool)), this, SLOT(GenGroupClicked(bool))); + connect(myGenGroupCheckGMP, SIGNAL(toggled(bool)), this, SLOT(GenGroupClicked(bool))); + connect(myStepByStepCheckGMP, SIGNAL(toggled(bool)), this, SLOT(StepByStepClicked(bool))); initName(tr("GEOM_PIPE")); resize(100,100); @@ -250,6 +256,7 @@ void GenerationGUI_PipeDlg::ConstructorsClicked( int constructorId ) GroupPoints->hide(); GroupMakePoints->show(); GroupMakePoints->PushButton1->click(); + myStepByStepCheckGMP->setChecked(false); myGenGroupCheckGMP->setChecked(false); resetGenGroup(myGenGroupCheckGMP, false, true); break; @@ -583,10 +590,16 @@ bool GenerationGUI_PipeDlg::execute (ObjectList& objects) myGenGroupCheckGMP->isChecked(); } + bool isWithContact = GroupMakePoints->CheckBox1->isEnabled() && + GroupMakePoints->CheckBox1->isChecked(); + bool isWithCorrection = GroupMakePoints->CheckBox2->isEnabled() && + GroupMakePoints->CheckBox2->isChecked(); + aList = anOper->MakePipeWithDifferentSections - (myBaseGO.in(), myLocationsGO.in(), myPath.get(), - GroupMakePoints->CheckBox1->isChecked(), - GroupMakePoints->CheckBox2->isChecked(), doGroups); + (myBaseGO.in(), myLocationsGO.in(), myPath.get(), + isWithContact, isWithCorrection, + myStepByStepCheckGMP->isChecked(), + doGroups); if (aList->length() > 0) { if (doGroups) { @@ -706,6 +719,16 @@ void GenerationGUI_PipeDlg::GenGroupClicked(bool isChecked) resetGenGroup((QCheckBox *)sender(), isChecked, false); } +//================================================================================= +// function : StepByStepClicked +// purpose : Slot to treat checking "Step-by-step generation" check box. +//================================================================================= +void GenerationGUI_PipeDlg::StepByStepClicked(bool isChecked) +{ + GroupMakePoints->CheckBox1->setEnabled(!isChecked); + GroupMakePoints->CheckBox2->setEnabled(!isChecked); +} + //================================================================================= // function : updateGenGroup // purpose : Update "Generate groups" widgets depending on the path. diff --git a/src/GenerationGUI/GenerationGUI_PipeDlg.h b/src/GenerationGUI/GenerationGUI_PipeDlg.h index 4b2d88efd..341fb18f4 100644 --- a/src/GenerationGUI/GenerationGUI_PipeDlg.h +++ b/src/GenerationGUI/GenerationGUI_PipeDlg.h @@ -81,6 +81,7 @@ private: QCheckBox *myGenGroupCheckGP; QLabel *myPrefixLblGP; QLineEdit *myPrefixEditGP; + QCheckBox *myStepByStepCheckGMP; QCheckBox *myGenGroupCheckGMP; QLabel *myPrefixLblGMP; QLineEdit *myPrefixEditGMP; @@ -95,6 +96,7 @@ private slots: void ConstructorsClicked( int ); void SelectionTypeButtonClicked(); void GenGroupClicked(bool); + void StepByStepClicked(bool); }; #endif // GENERATIONGUI_PIPEDLG_H From 6440cc096cc6377fdc40531ddaad10febcdb862d Mon Sep 17 00:00:00 2001 From: skv Date: Tue, 21 Jul 2015 18:39:48 +0300 Subject: [PATCH 25/54] 0022664: [CEA 1253] MakePipeWithDifferentSections fails on a elbow pipe: Fix comment --- src/GEOM_SWIG/geomBuilder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index d0eba918c..ccf06b705 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -4049,7 +4049,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): ## Create a shape by extrusion of the profile shape along # the path shape. This function is a version of - # MakePipeWithShellSections() with the same parameters, except + # MakePipeWithDifferentSections() with the same parameters, except # eliminated theWithContact and theWithCorrection. So it is # possible to find the description of all parameters is in this # method. The difference is that this method performs the operation @@ -4064,7 +4064,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): """ Create a shape by extrusion of the profile shape along the path shape. This function is a version of - MakePipeWithShellSections() with the same parameters, except + MakePipeWithDifferentSections() with the same parameters, except eliminated theWithContact and theWithCorrection. So it is possible to find the description of all parameters is in this method. The difference is that this method performs the operation From a207750f4a6445385f86f142c5a12f4efd24b6a9 Mon Sep 17 00:00:00 2001 From: skv Date: Wed, 22 Jul 2015 12:40:08 +0300 Subject: [PATCH 26/54] 0052829: Failed GetSubShapeID() breaks the next IsSubShapeBelongsTo() --- src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index fcba87df2..e5cdc97ea 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -690,8 +690,12 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWithConstraints if ( aFace->GetValue().ShapeType() != TopAbs_FACE ) // constraint face can be omitted - it is a valid case continue; + // Keep the old error code as IsSubShapeBelongsTo changes it. + TCollection_AsciiString anOldCode = GetErrorCode(); + if ( IsSubShapeBelongsTo( anObject, 0, aFace, 0 ) ) { // valid constraint + SetErrorCode(anOldCode); aRefSh = aFace->GetLastFunction(); aConstraints->Append(aRefSh); it++; @@ -2019,6 +2023,8 @@ Standard_Boolean GEOMImpl_IShapesOperations::IsSubShapeBelongsTo( Handle(GEOM_Ob Handle(GEOM_Object) theObject, const Standard_Integer theObjectIndex) { + SetErrorCode(KO); + if ( theObject.IsNull() || theSubObject.IsNull() ) return false; @@ -2039,7 +2045,12 @@ Standard_Boolean GEOMImpl_IShapesOperations::IsSubShapeBelongsTo( Handle(GEOM_Ob } TopExp::MapShapes( shape, anIndices ); - return anIndices.Contains( subShape ); + + const Standard_Boolean isBelongTo = anIndices.Contains(subShape); + + SetErrorCode(OK); + + return isBelongTo; } //============================================================================= From d7f33d79e41ce83f5126af2d8a44c7c3078b81bd Mon Sep 17 00:00:00 2001 From: skv Date: Tue, 28 Jul 2015 15:38:27 +0300 Subject: [PATCH 27/54] 0023128: [CEA 1555] FuseCollinearEdgesWithinWire fails on the outline of a square face partitioned --- src/GEOMImpl/GEOMImpl_HealingDriver.cxx | 72 ++++++++++++++++++++----- src/GEOMImpl/GEOMImpl_ShapeDriver.cxx | 6 ++- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_HealingDriver.cxx b/src/GEOMImpl/GEOMImpl_HealingDriver.cxx index 3c519465c..fab57241a 100644 --- a/src/GEOMImpl/GEOMImpl_HealingDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_HealingDriver.cxx @@ -804,25 +804,73 @@ void GEOMImpl_HealingDriver::FuseCollinearEdges (const TopoDS_Shape& theOriginal theWire = TopoDS::Wire(Fixer->Shape()); */ - TopoDS_Edge prevEdge; - TopTools_ListOfShape finalList, currChain; + // Get the ordered list of edges. + TopTools_ListOfShape anEdges; + TopTools_ListOfShape aCurVertices; + BRepTools_WireExplorer aWExp (theWire); - BRepTools_WireExplorer wexp (theWire); - if (wexp.More()) { - prevEdge = wexp.Current(); - currChain.Append(prevEdge); - wexp.Next(); + for (; aWExp.More(); aWExp.Next()) { + anEdges.Append(aWExp.Current()); + aCurVertices.Append(aWExp.CurrentVertex()); } - else { + + if (anEdges.IsEmpty()) { Standard_NullObject::Raise("Empty wire given"); } - for (; wexp.More(); wexp.Next()) { - TopoDS_Edge anEdge = wexp.Current(); - TopoDS_Vertex CurVertex = wexp.CurrentVertex(); + // Treat the case if the wire is closed and first and last edges are C1. + Standard_Boolean isShift = Standard_False; + + if (BRep_Tool::IsClosed(theWire)) { + // Wire is closed. Check if there are more than 2 edges in the wire. + if (!anEdges.First().IsSame(anEdges.Last())) { + isShift = Standard_True; + } + } + + if (isShift) { + // Put first edge to the end of the list while the chain break is reached. + TopoDS_Shape aFirstEdge = anEdges.First(); + + while (isShift) { + isShift = Standard_False; + + // Check if the first vertex should be kept + if (aMapToRemove.Contains(aCurVertices.First()) || removeAll) { + // Check if first and last edges are C1. + TopoDS_Edge anEdge1 = TopoDS::Edge(anEdges.Last()); + TopoDS_Edge anEdge2 = TopoDS::Edge(anEdges.First()); + + if (AreEdgesC1(anEdge1, anEdge2)) { + // Make the first edge last. + anEdges.Append(anEdge2); + anEdges.RemoveFirst(); + aCurVertices.Append(aCurVertices.First()); + aCurVertices.RemoveFirst(); + + // Check if we reached the first edge again. + // Break the loop in this case. + isShift = !aFirstEdge.IsSame(anEdges.First()); + } + } + } + } + + TopTools_ListOfShape finalList, currChain; + TopTools_ListIteratorOfListOfShape anEIter(anEdges); + TopTools_ListIteratorOfListOfShape aVIter(aCurVertices); + TopoDS_Edge prevEdge = TopoDS::Edge(anEIter.Value()); + + currChain.Append(prevEdge); + anEIter.Next(); + aVIter.Next(); + + for (; anEIter.More(); anEIter.Next(), aVIter.Next()) { + TopoDS_Edge anEdge = TopoDS::Edge(anEIter.Value()); + const TopoDS_Shape &aCurVertex = aVIter.Value(); bool continueChain = false; - if (aMapToRemove.Contains(CurVertex) || removeAll) { + if (aMapToRemove.Contains(aCurVertex) || removeAll) { // if C1 -> continue chain if (AreEdgesC1(prevEdge, anEdge)) { continueChain = true; diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index 933ad9eea..5462bbdf4 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -861,11 +861,13 @@ TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, { Standard_Boolean Done = Standard_False; Standard_Real NewFpar, NewLpar; - GeomAdaptor_Curve GAprevcurve(CurveSeq.Last()); + Handle(Geom_Geometry) aTrsfGeom = CurveSeq.Last()->Transformed + (LocSeq.Last().Location().Transformation()); + GeomAdaptor_Curve GAprevcurve(Handle(Geom_Curve)::DownCast(aTrsfGeom)); TopoDS_Vertex CurVertex = wexp.CurrentVertex(); TopoDS_Vertex CurFirstVer = TopExp::FirstVertex(anEdge); TopAbs_Orientation ConnectByOrigin = (CurVertex.IsSame(CurFirstVer))? TopAbs_FORWARD : TopAbs_REVERSED; - if (aCurve == CurveSeq.Last()) + if (aCurve == CurveSeq.Last() && aLoc.IsEqual(LocSeq.Last().Location())) { NewFpar = fpar; NewLpar = lpar; From f8174cfe4291eeef6fca842d3c3e1c785c37a44a Mon Sep 17 00:00:00 2001 From: skv Date: Tue, 28 Jul 2015 17:57:43 +0300 Subject: [PATCH 28/54] 0023129: [CEA 1551] GetShapesOnQuadrangle does not work with a points compound --- src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index e5cdc97ea..96c8e49b1 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -2626,7 +2626,7 @@ Handle(TColStd_HSequenceOfInteger) TopoDS_Shape aShape = theShape->GetValue(); // Check presence of triangulation, build if need - if (!GEOMUtils::CheckTriangulation(aShape)) { + if (theShapeType != TopAbs_VERTEX && !GEOMUtils::CheckTriangulation(aShape)) { SetErrorCode("Cannot build triangulation on the shape"); return aSeqOfIDs; } @@ -2793,7 +2793,7 @@ Handle(TColStd_HSequenceOfInteger) TopTools_ListOfShape res; // Check presence of triangulation, build if need - if (!GEOMUtils::CheckTriangulation(aShape)) { + if (theShapeType != TopAbs_VERTEX && !GEOMUtils::CheckTriangulation(aShape)) { SetErrorCode("Cannot build triangulation on the shape"); return aSeqOfIDs; } @@ -3082,7 +3082,8 @@ Handle(TColStd_HSequenceOfInteger) Handle(TColStd_HSequenceOfInteger) aSeqOfIDs; // Check presence of triangulation, build if need - if (!GEOMUtils::CheckTriangulation(theShape)) { + if (theShapeType != TopAbs_VERTEX && + !GEOMUtils::CheckTriangulation(theShape)) { SetErrorCode("Cannot build triangulation on the shape"); return aSeqOfIDs; } @@ -4008,7 +4009,7 @@ Handle(TColStd_HSequenceOfInteger) Handle(TColStd_HSequenceOfInteger) aSeqOfIDs; // Check presence of triangulation, build if need - if (!GEOMUtils::CheckTriangulation(aShape)) { + if (theShapeType != TopAbs_VERTEX && !GEOMUtils::CheckTriangulation(aShape)) { SetErrorCode("Cannot build triangulation on the shape"); return aSeqOfIDs; } From ab0d7e24cdeab0fa290e0549193fdc9941a80b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Aguerre?= Date: Tue, 28 Jul 2015 16:40:24 +0200 Subject: [PATCH 29/54] SIMAN removal --- src/GEOM_I/GEOM_Gen_i.cc | 258 +++++++++------------------------------ src/GEOM_I/GEOM_Gen_i.hh | 63 +++++----- 2 files changed, 85 insertions(+), 236 deletions(-) diff --git a/src/GEOM_I/GEOM_Gen_i.cc b/src/GEOM_I/GEOM_Gen_i.cc index 7a824de35..7f60f803e 100755 --- a/src/GEOM_I/GEOM_Gen_i.cc +++ b/src/GEOM_I/GEOM_Gen_i.cc @@ -66,7 +66,6 @@ #include #include -#include #include #include @@ -326,8 +325,8 @@ SALOMEDS::SObject_ptr GEOM_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy, std::string plgId; for ( size_t j = 0; j < infoSeq->length(); ++j ) for ( size_t i = 0; i < infoSeq[j].params.length(); ++i ) { - std::string param_name = infoSeq[j].params[i].name.in(); - std::string param_value = infoSeq[j].params[i].value.in(); + std::string param_name = infoSeq[j].params[i].name.in(); + std::string param_value = infoSeq[j].params[i].value.in(); if( param_name == PLUGIN_NAME) { plgId = param_value; break; @@ -684,8 +683,8 @@ CORBA::Boolean GEOM_Gen_i::Load(SALOMEDS::SComponent_ptr theComponent, useCaseBuilder->SetRootCurrent(); useCaseBuilder->Append( theComponent ); // component object is added as the top level item } - - SALOMEDS::ChildIterator_wrap it = study->NewChildIterator( theComponent ); + + SALOMEDS::ChildIterator_wrap it = study->NewChildIterator( theComponent ); for ( it->InitEx(true); it->More(); it->Next() ) { if ( !useCaseBuilder->IsUseCaseNode( it->Value() ) ) { useCaseBuilder->AppendTo( it->Value()->GetFather(), it->Value() ); @@ -2459,7 +2458,7 @@ GEOM::GEOM_IOperations_ptr GEOM_Gen_i::GetPluginOperations(CORBA::Long theStudyI aServant = myOpCreatorMap[aLibName]->Create(_poa, theStudyID, engine, _impl); // activate the CORBA servant if (aServant) - operations = aServant->_this(); + operations = aServant->_this(); } } catch (SALOME_Exception& S_ex) { @@ -2484,7 +2483,7 @@ void GEOM_Gen_i::LoadPlugin(const std::string& theLibName) aPlatformLibName += theLibName; aPlatformLibName += ".so"; #endif - + // check, if corresponding operations are already created if (myOpCreatorMap.find(theLibName) == myOpCreatorMap.end()) { // load plugin library @@ -2497,7 +2496,7 @@ void GEOM_Gen_i::LoadPlugin(const std::string& theLibName) throw(SALOME_Exception(LOCALIZED( "Can't load server geometry plugin library" ))); #endif } - + // get method, returning operations creator typedef GEOM_GenericOperationsCreator* (*GetOperationsCreator)(); GetOperationsCreator procHandle = @@ -2506,7 +2505,7 @@ void GEOM_Gen_i::LoadPlugin(const std::string& theLibName) UnLoadLib(libHandle); throw(SALOME_Exception(LOCALIZED("bad geometry plugin library"))); } - + // get operations creator GEOM_GenericOperationsCreator* aCreator = procHandle(); if (aCreator) { @@ -2808,8 +2807,8 @@ char* GEOM_Gen_i::getVersion() // function : CreateFolder() // purpose : Creates and returns a new folder object //================================================================================= -SALOMEDS::SObject_ptr GEOM_Gen_i::CreateFolder(const char* theName, - SALOMEDS::SObject_ptr theFather) +SALOMEDS::SObject_ptr GEOM_Gen_i::CreateFolder(const char* theName, + SALOMEDS::SObject_ptr theFather) { SALOMEDS::SObject_var aFolderSO; @@ -2861,8 +2860,8 @@ SALOMEDS::SObject_ptr GEOM_Gen_i::CreateFolder(const char* theName, // function : MoveToFolder() // purpose : Moves GEOM object to the specified folder //================================================================================= -void GEOM_Gen_i::MoveToFolder(GEOM::GEOM_Object_ptr theObject, - SALOMEDS::SObject_ptr theFolder) { +void GEOM_Gen_i::MoveToFolder(GEOM::GEOM_Object_ptr theObject, + SALOMEDS::SObject_ptr theFolder) { GEOM::object_list_var objects = new GEOM::object_list(); objects->length( 1 ); SALOMEDS::SObject_var aSO = theFolder->GetStudy()->FindObjectID( theObject->GetStudyEntry() ); @@ -2874,8 +2873,8 @@ void GEOM_Gen_i::MoveToFolder(GEOM::GEOM_Object_ptr theObject, // function : MoveListToFolder() // purpose : Moves list of GEOM objects to the specified folder //================================================================================= -void GEOM_Gen_i::MoveListToFolder (const GEOM::ListOfGO& theListOfGO, - SALOMEDS::SObject_ptr theFolder) { +void GEOM_Gen_i::MoveListToFolder (const GEOM::ListOfGO& theListOfGO, + SALOMEDS::SObject_ptr theFolder) { int aLen = theListOfGO.length(); GEOM::object_list_var objects = new GEOM::object_list(); objects->length( aLen ); @@ -2892,12 +2891,12 @@ void GEOM_Gen_i::MoveListToFolder (const GEOM::ListOfGO& theListOfGO, //================================================================================= // function : Move() -// purpose : Moves objects to the specified position. +// purpose : Moves objects to the specified position. // Is used in the drag-n-drop functionality. //================================================================================= void GEOM_Gen_i::Move( const GEOM::object_list& what, - SALOMEDS::SObject_ptr where, - CORBA::Long row ) + SALOMEDS::SObject_ptr where, + CORBA::Long row ) { if ( CORBA::is_nil( where ) ) return; @@ -2907,7 +2906,7 @@ void GEOM_Gen_i::Move( const GEOM::object_list& what, SALOMEDS::SComponent_var father = where->GetFatherComponent(); std::string dataType = father->ComponentDataType(); if ( dataType != "GEOM" ) return; // not a GEOM component - + SALOMEDS::SObject_var objAfter; if ( row >= 0 && useCaseBuilder->HasChildren( where ) ) { // insert at given row -> find insertion position @@ -2918,7 +2917,7 @@ void GEOM_Gen_i::Move( const GEOM::object_list& what, objAfter = useCaseIt->Value(); } } - + for ( int i = 0; i < what.length(); i++ ) { SALOMEDS::SObject_var sobj = what[i]; if ( CORBA::is_nil( sobj ) ) continue; // skip bad object @@ -2930,155 +2929,12 @@ void GEOM_Gen_i::Move( const GEOM::object_list& what, } } -//================================================================================= -// function : importData -// purpose : imports geometrical data file into the GEOM internal data structure -//================================================================================= -Engines::ListOfIdentifiers* GEOM_Gen_i::importData( - CORBA::Long studyId, Engines::DataContainer_ptr data, const Engines::ListOfOptions& options) -{ - CORBA::Object_var aSMObject = name_service->Resolve( "/myStudyManager" ); - SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow( aSMObject ); - SALOMEDS::Study_var aStudy = aStudyManager->GetStudyByID( studyId ); - - Engines::ListOfIdentifiers_var aResult = new Engines::ListOfIdentifiers; - GEOM::GEOM_IInsertOperations_var aInsOp = GetIInsertOperations(aStudy->StudyId()); - if (aInsOp->_is_nil()) { - MESSAGE("No insert operations!"); - return aResult._retn(); - } - - // Get a temporary directory to store a file - std::string aTmpDir = SALOMEDS_Tool::GetTmpDir(); - std::string aFileName("file"); - if (aFileName.rfind("/") != std::string::npos) { // remove folders from the name - aFileName = aFileName.substr(aFileName.rfind("/") + 1); - } - - std::string anExtension(data->extension()); - aFileName += "." + anExtension; - // convert extension to upper case - std::transform(anExtension.begin(), anExtension.end(), anExtension.begin(), ::toupper); - std::string aFullPath = aTmpDir + aFileName; - - Engines::TMPFile* aFileStream = data->get(); - const char *aBuffer = (const char*)aFileStream->NP_data(); -#ifdef WIN32 - std::ofstream aFile(aFullPath.c_str(), std::ios::binary); -#else - std::ofstream aFile(aFullPath.c_str()); -#endif - aFile.write(aBuffer, aFileStream->length()); - aFile.close(); - - GEOM::ListOfGBO_var aObjects = aInsOp->ImportFile(aFullPath.c_str(), "XAO"); - - if ( aObjects->length() > 0 && aInsOp->IsDone() ) { - aResult->length(aObjects->length()); - // publish main object (first in the list of returned geom objects) - CORBA::String_var aName = aObjects[0]->GetName(); - SALOMEDS::SObject_var aSO = PublishInStudy(aStudy.in(), SALOMEDS::SObject::_nil(), aObjects[0].in(), aName.in()); - aResult[0] = aSO->GetID(); - // publish groups && fields - for (int i = 1; i < aObjects->length(); i++ ) { - aName = aObjects[i]->GetName(); - aSO = AddInStudy(aStudy.in(), aObjects[0].in(), aName.in(), aObjects[0].in()); - aResult[i] = aSO->GetID(); - } - } - else { - if (aObjects->length() == 0) - MESSAGE("ImportXAO operation is failed for file "<IsDone()) - MESSAGE("Import operation is not done for file "<DocumentModified(studyId, false); - return aResult._retn(); -} - -//================================================================================= -// function : getModifiedData -// purpose : exports all geometry of this GEOM module into one BRep file -//================================================================================= -Engines::ListOfData* GEOM_Gen_i::getModifiedData(CORBA::Long studyId) -{ - Engines::ListOfData_var aResult = new Engines::ListOfData; - - if (!_impl->DocumentModified(studyId)) { - MESSAGE("Document is not modified") - return aResult._retn(); - } - - CORBA::Object_var aSMObject = name_service->Resolve("/myStudyManager"); - SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow( aSMObject ); - if (CORBA::is_nil(aStudyManager)) - return aResult._retn(); - SALOMEDS::Study_var aStudy = aStudyManager->GetStudyByID( studyId ); - if (CORBA::is_nil(aStudy)) - return aResult._retn(); - SALOMEDS::SComponent_var aComponent = aStudy->FindComponent("GEOM"); - if (CORBA::is_nil(aComponent)) - return aResult._retn(); - SALOMEDS::ChildIterator_var anIter = aStudy->NewChildIterator(aComponent); // check only published shapes - - GEOM::GEOM_IInsertOperations_var aInsOp = GetIInsertOperations(aStudy->StudyId()); - if (aInsOp->_is_nil()) { - MESSAGE("No insert operations!"); - return aResult._retn(); - } - - GEOM::GEOM_Object_var shapeObj; - - for(; anIter->More(); anIter->Next()) { - SALOMEDS::SObject_var aSO = anIter->Value(); - SALOMEDS::SObject_var aRefSO; - // export only not referenced objects, or referenced outside of GEOM - if (!aSO->ReferencedObject(aRefSO) || aRefSO->GetFatherComponent()->GetID() != aComponent->GetID()) { - CORBA::Object_var anObj = aSO->GetObject(); - if (!CORBA::is_nil(anObj)) { - GEOM::GEOM_Object_var aCORBAMainShape = GEOM::GEOM_Object::_narrow(anObj); - if(!aCORBAMainShape->_is_nil()) { - CORBA::String_var entry = aCORBAMainShape->GetEntry(); - Handle(GEOM_Object) aMainShape = Handle(GEOM_Object)::DownCast(_impl->GetObject(studyId, entry)); - - GEOM::shape_type aCORBAShapeType = aCORBAMainShape->GetShapeType(); - if (!aMainShape.IsNull() && !(aCORBAShapeType == GEOM::VERTEX) && !(aCORBAShapeType == GEOM::EDGE)) { - shapeObj = aCORBAMainShape; - break; - } - } - } - } - } - - if (!CORBA::is_nil(shapeObj)) { // Shape is correct, write it to the temporary file - std::string aPath = Kernel_Utils::GetTmpFileName() + ".xao"; - aInsOp->Export(shapeObj.in(), aPath.c_str(), "XAO"); - aResult->length(1); - Engines::DataContainer_var aData = (new Engines_DataContainer_i( - aPath.c_str(), "", "", true))->_this(); - aResult[0] = aData; - } else { - MESSAGE("No shapes to export"); - } - - return aResult._retn(); -} - //======================================================================= // function : GetDependencyTree // purpose : Collects dependencies of the given objects from other ones //======================================================================= SALOMEDS::TMPFile* GEOM_Gen_i::GetDependencyTree( SALOMEDS::Study_ptr theStudy, - const GEOM::string_array& theObjectEntries ) { + const GEOM::string_array& theObjectEntries ) { // fill in the tree structure GEOMUtils::TreeModel tree; @@ -3102,7 +2958,7 @@ SALOMEDS::TMPFile* GEOM_Gen_i::GetDependencyTree( SALOMEDS::Study_ptr theStudy, // translation the tree into string std::string treeStr; GEOMUtils::ConvertTreeToString( tree, treeStr ); - + // put string into stream char* aBuffer = (char*)CORBA::string_dup(treeStr.c_str()); int aBufferSize = strlen((char*)aBuffer); @@ -3118,10 +2974,10 @@ SALOMEDS::TMPFile* GEOM_Gen_i::GetDependencyTree( SALOMEDS::Study_ptr theStudy, // function : getUpwardDependency // purpose : Collects the entries of objects on that the given one depends //======================================================================= -void GEOM_Gen_i::getUpwardDependency( GEOM::GEOM_BaseObject_ptr gbo, - GEOMUtils::LevelsList &upLevelList, - std::map< std::string, std::set > &passedEntries, - int level ) { +void GEOM_Gen_i::getUpwardDependency( GEOM::GEOM_BaseObject_ptr gbo, + GEOMUtils::LevelsList &upLevelList, + std::map< std::string, std::set > &passedEntries, + int level ) { std::string aGboEntry = gbo->GetEntry(); GEOMUtils::NodeLinks anEntries; GEOMUtils::LevelInfo aLevelMap; @@ -3133,7 +2989,7 @@ void GEOM_Gen_i::getUpwardDependency( GEOM::GEOM_BaseObject_ptr gbo, // get the existent map aLevelMap = upLevelList.at(level-1); if ( aLevelMap.count( aGboEntry ) > 0 ) { - anEntries = aLevelMap[ aGboEntry ]; + anEntries = aLevelMap[ aGboEntry ]; } } } @@ -3144,7 +3000,7 @@ void GEOM_Gen_i::getUpwardDependency( GEOM::GEOM_BaseObject_ptr gbo, if ( depList[j]->_is_nil() ) continue; aDepEntry = depList[j]->GetEntry(); - if ( passedEntries.count( aGboEntry ) > 0 && + if ( passedEntries.count( aGboEntry ) > 0 && passedEntries[aGboEntry].count( aDepEntry ) > 0 ) { //avoid checking the passed objects continue; @@ -3166,10 +3022,10 @@ void GEOM_Gen_i::getUpwardDependency( GEOM::GEOM_BaseObject_ptr gbo, // function : getDownwardDependency // purpose : Collects the entries of objects that depends on the given one //======================================================================= -void GEOM_Gen_i::getDownwardDependency( GEOM::GEOM_BaseObject_ptr gbo, - GEOMUtils::LevelsList &downLevelList, - std::map< std::string, std::set > &passedEntries, - int level ) { +void GEOM_Gen_i::getDownwardDependency( GEOM::GEOM_BaseObject_ptr gbo, + GEOMUtils::LevelsList &downLevelList, + std::map< std::string, std::set > &passedEntries, + int level ) { std::string aGboEntry = gbo->GetEntry(); Handle(TDocStd_Document) aDoc = GEOM_Engine::GetEngine()->GetDocument(gbo->GetStudyID()); Handle(TDataStd_TreeNode) aNode, aRoot; @@ -3201,7 +3057,7 @@ void GEOM_Gen_i::getDownwardDependency( GEOM::GEOM_BaseObject_ptr gbo, continue; if ( depList[i]->_is_equivalent( gbo ) ) { // yes, the current object depends on the given object - if ( passedEntries.count( aGoEntry ) > 0 && + if ( passedEntries.count( aGoEntry ) > 0 && passedEntries[aGoEntry].count( aGboEntry ) > 0 ) { //avoid checking the passed objects continue; @@ -3234,10 +3090,10 @@ void GEOM_Gen_i::getDownwardDependency( GEOM::GEOM_BaseObject_ptr gbo, // purpose : Fills 3 lists that is used to clean study of redundant objects //============================================================================== void GEOM_Gen_i::GetEntriesToReduceStudy(SALOMEDS::Study_ptr theStudy, - GEOM::string_array& theSelectedEntries, - GEOM::string_array& theParentEntries, - GEOM::string_array& theSubEntries, - GEOM::string_array& theOtherEntries) + GEOM::string_array& theSelectedEntries, + GEOM::string_array& theParentEntries, + GEOM::string_array& theSubEntries, + GEOM::string_array& theOtherEntries) { std::set aSelected, aParents, aChildren, anOthers; for ( int i = 0; i < theSelectedEntries.length(); i++ ) { @@ -3271,7 +3127,7 @@ void GEOM_Gen_i::GetEntriesToReduceStudy(SALOMEDS::Study_ptr theStudy, if ( aSelected.count( anEntry ) > 0 && aParents.count( anEntry ) == 0 ) { includeParentDependencies( geomObj, aSelected, aParents, aChildren, anOthers ); - } else if ( aParents.count( anEntry ) == 0 && + } else if ( aParents.count( anEntry ) == 0 && aChildren.count( anEntry ) == 0 ) { anOthers.insert( geomObj->GetEntry() ); } @@ -3288,7 +3144,7 @@ void GEOM_Gen_i::GetEntriesToReduceStudy(SALOMEDS::Study_ptr theStudy, } // if some selected object is not a main shape, - // we move it's main shapes into 'selected' list, + // we move it's main shapes into 'selected' list, // because they could not be modified anyhow. std::set aToBeInSelected; for ( it = aSelected.begin(); it != aSelected.end(); ++it ) { @@ -3341,13 +3197,13 @@ void GEOM_Gen_i::GetEntriesToReduceStudy(SALOMEDS::Study_ptr theStudy, //============================================================================== // function : includeParentDependencies -// purpose : +// purpose : //============================================================================== void GEOM_Gen_i::includeParentDependencies(GEOM::GEOM_BaseObject_ptr geomObj, - std::set& aSelected, - std::set& aParents, - std::set& aChildren, - std::set& anOthers) + std::set& aSelected, + std::set& aParents, + std::set& aChildren, + std::set& anOthers) { std::string anEntry = geomObj->GetEntry(); if ( aSelected.count( anEntry ) == 0 ) { @@ -3369,10 +3225,10 @@ void GEOM_Gen_i::includeParentDependencies(GEOM::GEOM_BaseObject_ptr geomObj, for( int i = 0; i < depList->length(); i++ ) { aDepEntry = depList[i]->GetEntry(); if ( depList[i]->_is_nil() || - aDepEntry == anEntry || // skip self-depending - aSelected.count( aDepEntry ) > 0 || // skip selected objects - aParents.count( aDepEntry ) > 0 // skip already processed objects - ) + aDepEntry == anEntry || // skip self-depending + aSelected.count( aDepEntry ) > 0 || // skip selected objects + aParents.count( aDepEntry ) > 0 // skip already processed objects + ) continue; includeParentDependencies( depList[i], aSelected, aParents, aChildren, anOthers ); } @@ -3380,14 +3236,14 @@ void GEOM_Gen_i::includeParentDependencies(GEOM::GEOM_BaseObject_ptr geomObj, //============================================================================== // function : includeSubObjects -// purpose : +// purpose : //============================================================================== void GEOM_Gen_i::includeSubObjects(SALOMEDS::Study_ptr theStudy, - const std::string& aSelectedEntry, - std::set& aSelected, - std::set& aParents, - std::set& aChildren, - std::set& anOthers) + const std::string& aSelectedEntry, + std::set& aSelected, + std::set& aParents, + std::set& aChildren, + std::set& anOthers) { std::set::iterator foundIt; Handle(GEOM_BaseObject) handle_object = _impl->GetObject( theStudy->StudyId(), aSelectedEntry.c_str(), false); @@ -3412,10 +3268,10 @@ void GEOM_Gen_i::includeSubObjects(SALOMEDS::Study_ptr theStudy, if ( foundIt == aParents.end() ) { // add to sub-objects if it is not in parents list foundIt = aSelected.find( aSubEntryStr ); if ( foundIt == aSelected.end() ) { // add to sub-objects if it is not in selected list - aChildren.insert( aSubEntryStr ); - foundIt = anOthers.find( aSubEntryStr ); - if ( foundIt != anOthers.end() ) - anOthers.erase( foundIt ); + aChildren.insert( aSubEntryStr ); + foundIt = anOthers.find( aSubEntryStr ); + if ( foundIt != anOthers.end() ) + anOthers.erase( foundIt ); } } includeSubObjects( theStudy, aSubEntryStr, aSelected, aParents, aChildren, anOthers ); diff --git a/src/GEOM_I/GEOM_Gen_i.hh b/src/GEOM_I/GEOM_Gen_i.hh index f56712fb0..25963bffd 100644 --- a/src/GEOM_I/GEOM_Gen_i.hh +++ b/src/GEOM_I/GEOM_Gen_i.hh @@ -201,7 +201,7 @@ class GEOM_I_EXPORT GEOM_Gen_i: virtual public POA_GEOM::GEOM_Gen, virtual publi //Collects dependencies of the given objects from other ones SALOMEDS::TMPFile* GetDependencyTree(SALOMEDS::Study_ptr theStudy, - const GEOM::string_array& theObjectEntries); + const GEOM::string_array& theObjectEntries); //-----------------------------------------------------------------------// // Transaction methods // @@ -301,37 +301,30 @@ class GEOM_I_EXPORT GEOM_Gen_i: virtual public POA_GEOM::GEOM_Gen, virtual publi virtual char* getVersion(); // Create a new folder object - SALOMEDS::SObject_ptr CreateFolder(const char* theName, - SALOMEDS::SObject_ptr theFather); + SALOMEDS::SObject_ptr CreateFolder(const char* theName, + SALOMEDS::SObject_ptr theFather); // Move GEOM object to the specified folder - void MoveToFolder(GEOM::GEOM_Object_ptr theObject, - SALOMEDS::SObject_ptr theFolder); + void MoveToFolder(GEOM::GEOM_Object_ptr theObject, + SALOMEDS::SObject_ptr theFolder); // Move list of GEOM objects to the specified folder - void MoveListToFolder (const GEOM::ListOfGO& theListOfGO, - SALOMEDS::SObject_ptr theFolder); + void MoveListToFolder (const GEOM::ListOfGO& theListOfGO, + SALOMEDS::SObject_ptr theFolder); // Move objects to the specified position void Move( const GEOM::object_list& what, - SALOMEDS::SObject_ptr where, - CORBA::Long row ); - - // SIMAN-related functions (check out/check in) : import data to study - virtual Engines::ListOfIdentifiers* importData(CORBA::Long studyId, - Engines::DataContainer_ptr data, - const Engines::ListOfOptions& options); - // SIMAN-related functions (check out/check in) : get modified data - virtual Engines::ListOfData* getModifiedData(CORBA::Long studyId); + SALOMEDS::SObject_ptr where, + CORBA::Long row ); /*! \brief Fills 3 lists that is used to clean study of redundant objects. * To be used from GUI. */ void GetEntriesToReduceStudy(SALOMEDS::Study_ptr theStudy, - GEOM::string_array& theSelectedEntries, - GEOM::string_array& theParentEntries, - GEOM::string_array& theSubEntries, - GEOM::string_array& theOtherEntries); + GEOM::string_array& theSelectedEntries, + GEOM::string_array& theParentEntries, + GEOM::string_array& theSubEntries, + GEOM::string_array& theOtherEntries); //-----------------------------------------------------------------------// // Internal methods // @@ -381,28 +374,28 @@ class GEOM_I_EXPORT GEOM_Gen_i: virtual public POA_GEOM::GEOM_Gen, virtual publi const Standard_CString& GrName, GEOM::ListOfGO_var aResList); - void getUpwardDependency( GEOM::GEOM_BaseObject_ptr gbo, - GEOMUtils::LevelsList &upLevelList, - std::map< std::string, std::set > &passedEntries, + void getUpwardDependency( GEOM::GEOM_BaseObject_ptr gbo, + GEOMUtils::LevelsList &upLevelList, + std::map< std::string, std::set > &passedEntries, int level = 0 ); - void getDownwardDependency( GEOM::GEOM_BaseObject_ptr gbo, - GEOMUtils::LevelsList &downLevelList, - std::map< std::string, std::set > &passedEntries, + void getDownwardDependency( GEOM::GEOM_BaseObject_ptr gbo, + GEOMUtils::LevelsList &downLevelList, + std::map< std::string, std::set > &passedEntries, int level = 0 ); void includeParentDependencies(GEOM::GEOM_BaseObject_ptr gbo, - std::set& aSelected, - std::set& aParents, - std::set& aChildren, - std::set& anOthers); + std::set& aSelected, + std::set& aParents, + std::set& aChildren, + std::set& anOthers); void includeSubObjects(SALOMEDS::Study_ptr theStudy, - const std::string& aSelectedEntry, - std::set& aSelected, - std::set& aParents, - std::set& aChildren, - std::set& anOthers); + const std::string& aSelectedEntry, + std::set& aSelected, + std::set& aParents, + std::set& aChildren, + std::set& anOthers); void LoadPlugin(const std::string& theLibName); From 914938a458b9d78a1b7719a3c9f6b74d3c5f20a7 Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 18 Aug 2015 14:18:20 +0300 Subject: [PATCH 30/54] 0023115: [CEA 1545] Regression on KindOfShape method Additional correction, to avoid duplicated information in result of operation --- src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index e60150562..17a54671f 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -532,20 +532,8 @@ GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape if (anInfo.KindOfBounds() != GEOMAlgo_KB_INFINITE) { // (+) geompy.kind.PLANAR xo yo zo dx dy dz nb_edges nb_vertices - aKind = SK_PLANAR; - gp_Pnt aC = anInfo.Location(); - theDoubles->Append(aC.X()); - theDoubles->Append(aC.Y()); - theDoubles->Append(aC.Z()); - - gp_Ax3 anAx3 = anInfo.Position(); - gp_Dir aD = anAx3.Direction(); - theDoubles->Append(aD.X()); - theDoubles->Append(aD.Y()); - theDoubles->Append(aD.Z()); - theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE)); theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); } From 2146f8da308639fee66a8872470be8bbf50b8310 Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 18 Aug 2015 16:54:08 +0300 Subject: [PATCH 31/54] 0023137: [CEA 1570] WhatIs on a Local Coordinates System returns POLYGON Kind Of Shape functionality has been adopted for Local Coordinate system objects. --- idl/GEOM_Gen.idl | 1 + src/GEOMGUI/GEOM_msg_en.ts | 20 + src/GEOMGUI/GEOM_msg_fr.ts | 20 + src/GEOMGUI/GEOM_msg_ja.ts | 20 + src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx | 33 ++ src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx | 4 +- src/GEOM_SWIG/geomBuilder.py | 2 + src/MeasureGUI/MeasureGUI_WhatisDlg.cxx | 485 ++++++++++--------- 8 files changed, 351 insertions(+), 234 deletions(-) diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 4b56df001..98af123bd 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -4216,6 +4216,7 @@ module GEOM // VERTEX VERTEX, // ADVANCED shapes + LCS, /*! all advanced shapes (temporary implementation) */ ADVANCED }; diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 606714b1e..5bec27d7c 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -5144,6 +5144,10 @@ Please, select face, shell or solid and try again GEOM_Z_I Z%1 : + + GEOM_A_I + A%1 : + GEOM_SHAPES_ON_SHAPE_TITLE Get shapes on shape @@ -5416,6 +5420,22 @@ shells and solids on the other hand. GEOM_PLOT_DISTRIBUTION Plot + + GEOM_X_AXIS + X Axis + + + GEOM_Y_AXIS + Y Axis + + + GEOM_Z_AXIS + Z Axis + + + GEOM_DIM_AXES + Dimensions along local axes + GeometryGUI diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 06169dafb..8ff9bde85 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -5136,6 +5136,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau GEOM_Z_I Z%1 : + + GEOM_A_I + A%1 : + GEOM_SHAPES_ON_SHAPE_TITLE Trouver les éléments d'un objet @@ -5408,6 +5412,22 @@ le paramètre '%1' aux préférences du module Géométrie.GEOM_PLOT_DISTRIBUTION Plot + + GEOM_X_AXIS + Axe X + + + GEOM_Y_AXIS + Axe Y + + + GEOM_Z_AXIS + Axe Z + + + GEOM_DIM_AXES + Dimensions along local axes + GeometryGUI diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts index a92a3e60b..4a7d00101 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -5147,6 +5147,10 @@ GEOM_Z_I Z%1 : + + GEOM_A_I + A%1 : + GEOM_SHAPES_ON_SHAPE_TITLE オブジェクトの要素を見つける @@ -5415,6 +5419,22 @@ GEOM_PLOT_DISTRIBUTION Plot + + GEOM_X_AXIS + Axe X + + + GEOM_Y_AXIS + Axe Y + + + GEOM_Z_AXIS + Axe Z + + + GEOM_DIM_AXES + Dimensions along local axes + GeometryGUI diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index 17a54671f..e1b9e08cd 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include @@ -147,6 +148,38 @@ GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape } const GEOMAlgo_ShapeInfo& anInfo = aSF.Info(); + // specific processing for some "advandced" objects + switch ( geom_type ) { + case GEOM_MARKER: + // local coordinate systen + // (+) geompy.kind.LCS xc yc zc xx xy xz yx yy yz zx zy zz + + TopoDS_Face aFace = TopoDS::Face( aShape ); + Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast( BRep_Tool::Surface( aFace ) ); + gp_Pnt aC = aPlane->Pln().Location(); + gp_Ax3 anAx3 = aPlane->Pln().Position(); + + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + gp_Dir aD = anAx3.XDirection(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + aD = anAx3.YDirection(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + SetErrorCode(OK); + return SK_LCS; + } + // Interprete results TopAbs_ShapeEnum aType = anInfo.Type(); switch (aType) diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx index e81e5db1f..72329c18d 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx @@ -80,8 +80,10 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations { SK_SEGMENT, // segment SK_EDGE, // other edge // VERTEX - SK_VERTEX, + SK_VERTEX, // vertex // ADVANCED shapes + SK_LCS, // local coordinate system + // (other advanced shapes) SK_ADVANCED, // all advanced shapes (temporary implementation) }; diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index ccf06b705..be3cffc07 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -600,6 +600,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # - EDGE: [nb_vertices] # # - VERTEX: [x y z] + # + # - LCS: [x y z xx xy xz yx yy yz zx zy zz] # @ingroup l1_geomBuilder_auxiliary kind = GEOM.GEOM_IKindOfShape diff --git a/src/MeasureGUI/MeasureGUI_WhatisDlg.cxx b/src/MeasureGUI/MeasureGUI_WhatisDlg.cxx index 3bf5a2bf7..cd4d660da 100644 --- a/src/MeasureGUI/MeasureGUI_WhatisDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_WhatisDlg.cxx @@ -193,10 +193,8 @@ void MeasureGUI_WhatisDlg::processObject() //================================================================================= void MeasureGUI_WhatisDlg::activateSelection() { - MeasureGUI_Skeleton::activateSelection(); - std::list needTypes; - needTypes.push_back( TopAbs_VERTEX ), needTypes.push_back( TopAbs_EDGE ), needTypes.push_back( TopAbs_WIRE ), needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ), needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPOUND ); - localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + globalSelection(); // all types of objects + localSelection(GEOM::GEOM_Object::_nil(), TopAbs_SHAPE); // all types of sub-shapes } //================================================================================= @@ -264,7 +262,9 @@ QString MeasureGUI_WhatisDlg::getKindOfShape( QString& theParameters ) if ( !anOper->IsDone() ) return aKindStr; -#define PRINT_DOUBLE(val, tol) DlgRef::PrintDoubleValue( val, tol ) +#define PRINT_DOUBLE(val, tol) QString(" %1").arg( DlgRef::PrintDoubleValue( val, tol ) ) +#define TITLE(val) QString("%1").arg(tr(val)) +#define TITLE_I(val, i) QString("%1").arg(tr(val).arg(i)) switch ( aKind ) { case GEOM::GEOM_IKindOfShape::COMPOUND: @@ -294,85 +294,85 @@ QString MeasureGUI_WhatisDlg::getKindOfShape( QString& theParameters ) // SOLIDs case GEOM::GEOM_IKindOfShape::SPHERE: aKindStr = tr( "GEOM_SPHERE" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::CYLINDER: aKindStr = tr( "GEOM_CYLINDER" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_AXIS" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + - "\n" + tr( "GEOM_HEIGHT" ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_AXIS" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + + "
      " + tr( "GEOM_HEIGHT" ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::BOX: aKindStr = tr( "GEOM_BOX" ); - theParameters = tr( "GEOM_CENTER") + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + "Ax :" + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + "Ay :" + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + "Az :" + PRINT_DOUBLE( aDbls[5], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + "Ax :" + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + "Ay :" + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + "Az :" + PRINT_DOUBLE( aDbls[5], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::ROTATED_BOX: aKindStr = tr( "GEOM_BOX" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\nZ Axis:" + - "\n" + "Zx :" + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + "Zy :" + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + "Zz :" + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + - "\nX Axis:" + - "\n" + tr( "GEOM_X_I" ).arg( "x" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + - "\n" + tr( "GEOM_X_I" ).arg( "y" ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ) + - "\n" + tr( "GEOM_X_I" ).arg( "z" ) + PRINT_DOUBLE( aDbls[8], aLenPrecision ) + - "\nDimensions along local axes:" + - "\n" + "Ax :" + PRINT_DOUBLE( aDbls[9], aLenPrecision ) + - "\n" + "Ay :" + PRINT_DOUBLE( aDbls[10], aLenPrecision ) + - "\n" + "Az :" + PRINT_DOUBLE( aDbls[11], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_Z_AXIS") + + "
      " + tr( "GEOM_Z_I" ).arg( "x" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( "y" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( "z" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_X_AXIS") + + "
      " + tr( "GEOM_X_I" ).arg( "x" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + + "
      " + tr( "GEOM_X_I" ).arg( "y" ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ) + + "
      " + tr( "GEOM_X_I" ).arg( "z" ) + PRINT_DOUBLE( aDbls[8], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIM_AXES") + + "
      " + tr( "GEOM_A_I" ).arg( "x" ) + PRINT_DOUBLE( aDbls[9], aLenPrecision ) + + "
      " + tr( "GEOM_A_I" ).arg( "y" ) + PRINT_DOUBLE( aDbls[10], aLenPrecision ) + + "
      " + tr( "GEOM_A_I" ).arg( "z" ) + PRINT_DOUBLE( aDbls[11], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::TORUS: aKindStr = tr( "GEOM_TORUS" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_AXIS" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + - "\n" + tr( "GEOM_RADIUS_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_AXIS" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + + "
      " + tr( "GEOM_RADIUS_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::CONE: aKindStr = tr( "GEOM_CONE" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_AXIS" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + - "\n" + tr( "GEOM_RADIUS_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ) + - "\n" + tr( "GEOM_HEIGHT" ) + PRINT_DOUBLE( aDbls[8], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_AXIS" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + + "
      " + tr( "GEOM_RADIUS_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ) + + "
      " + tr( "GEOM_HEIGHT" ) + PRINT_DOUBLE( aDbls[8], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::POLYHEDRON: aKindStr = tr( "GEOM_POLYHEDRON" ); @@ -383,115 +383,115 @@ QString MeasureGUI_WhatisDlg::getKindOfShape( QString& theParameters ) // FACEs case GEOM::GEOM_IKindOfShape::SPHERE2D: aKindStr = tr( "GEOM_SURFSPHERE" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::CYLINDER2D: aKindStr = tr( "GEOM_SURFCYLINDER" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_AXIS" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + - "\n" + tr( "GEOM_HEIGHT" ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_AXIS" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + + "
      " + tr( "GEOM_HEIGHT" ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::TORUS2D: aKindStr = tr( "GEOM_SURFTORUS" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_AXIS" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + - "\n" + tr( "GEOM_RADIUS_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_AXIS" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + + "
      " + tr( "GEOM_RADIUS_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::CONE2D: aKindStr = tr( "GEOM_SURFCONE" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_AXIS" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + - "\n" + tr( "GEOM_RADIUS_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ) + - "\n" + tr( "GEOM_HEIGHT" ) + PRINT_DOUBLE( aDbls[8], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_AXIS" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + + "
      " + tr( "GEOM_RADIUS_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ) + + "
      " + tr( "GEOM_HEIGHT" ) + PRINT_DOUBLE( aDbls[8], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::DISK_CIRCLE: aKindStr = tr( "GEOM_DISK_CIRCLE" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_NORMAL" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_NORMAL" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::DISK_ELLIPSE: aKindStr = tr( "GEOM_DISK_ELLIPSE" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_NORMAL" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS_MAJOR" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + - "\n" + tr( "GEOM_RADIUS_MINOR" ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_NORMAL" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS_MAJOR" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + + "
      " + tr( "GEOM_RADIUS_MINOR" ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::POLYGON: aKindStr = tr( "GEOM_POLYGON" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_NORMAL" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_NORMAL" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::PLANE: aKindStr = tr( "GEOM_PLANE" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_NORMAL" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_NORMAL" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::PLANAR: aKindStr = tr( "GEOM_PLANAR_FACE" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_NORMAL" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_NORMAL" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::FACE: aKindStr = tr( "GEOM_FACE" ); @@ -499,105 +499,124 @@ QString MeasureGUI_WhatisDlg::getKindOfShape( QString& theParameters ) // EDGEs case GEOM::GEOM_IKindOfShape::CIRCLE: aKindStr = tr( "GEOM_CIRCLE" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_NORMAL" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_NORMAL" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::ARC_CIRCLE: aKindStr = tr( "GEOM_ARC" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_NORMAL" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + - "\n" + tr( "GEOM_POINT_I" ).arg( 1 ) + - "\n" + tr( "GEOM_X_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[8], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[9], aLenPrecision ) + - "\n" + tr( "GEOM_POINT_I" ).arg( 2 ) + - "\n" + tr( "GEOM_X_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[10], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[11], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[12], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_NORMAL" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + + "
      " + TITLE_I( "GEOM_POINT_I", 1 ) + + "
      " + tr( "GEOM_X_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[8], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[9], aLenPrecision ) + + "
      " + TITLE_I( "GEOM_POINT_I", 2 ) + + "
      " + tr( "GEOM_X_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[10], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[11], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[12], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::ELLIPSE: aKindStr = tr( "GEOM_ELLIPSE" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_NORMAL" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS_MAJOR" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + - "\n" + tr( "GEOM_RADIUS_MINOR" ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_NORMAL" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS_MAJOR" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + + "
      " + tr( "GEOM_RADIUS_MINOR" ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::ARC_ELLIPSE: aKindStr = tr( "GEOM_ARC_ELLIPSE" ); - theParameters = tr( "GEOM_CENTER" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_NORMAL" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + - "\n" + tr( "GEOM_DIMENSIONS" ) + - "\n" + tr( "GEOM_RADIUS_MAJOR" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + - "\n" + tr( "GEOM_RADIUS_MINOR" ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ) + - "\n" + tr( "GEOM_POINT_I" ).arg( 1 ) + - "\n" + tr( "GEOM_X_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[8], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[9], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[10], aLenPrecision ) + - "\n" + tr( "GEOM_POINT_I" ).arg( 2 ) + - "\n" + tr( "GEOM_X_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[11], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[12], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[13], aLenPrecision ); + theParameters = TITLE( "GEOM_CENTER" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_NORMAL" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIMENSIONS" ) + + "
      " + tr( "GEOM_RADIUS_MAJOR" ) + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + + "
      " + tr( "GEOM_RADIUS_MINOR" ) + PRINT_DOUBLE( aDbls[7], aLenPrecision ) + + "
      " + TITLE_I( "GEOM_POINT_I", 1 ) + + "
      " + tr( "GEOM_X_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[8], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[9], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[10], aLenPrecision ) + + "
      " + TITLE_I( "GEOM_POINT_I", 2 ) + + "
      " + tr( "GEOM_X_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[11], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[12], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[13], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::LINE: aKindStr = tr( "GEOM_LINE" ); - theParameters = tr( "GEOM_POSITION" ) + - "\n" + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_DIRECTION" ) + - "\n" + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ); + theParameters = TITLE( "GEOM_POSITION" ) + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_DIRECTION" ) + + "
      " + tr( "GEOM_DX" ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_DY" ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_DZ" ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::SEGMENT: aKindStr = tr( "GEOM_SEGMENT" ); - theParameters = tr( "GEOM_POINT_I" ).arg( 1 ) + - "\n" + tr( "GEOM_X_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + - "\n" + tr( "GEOM_POINT_I" ).arg( 2 ) + - "\n" + tr( "GEOM_X_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + - "\n" + tr( "GEOM_Y_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + - "\n" + tr( "GEOM_Z_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ); + theParameters = TITLE_I( "GEOM_POINT_I", 1 ) + + "
      " + tr( "GEOM_X_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 1 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE_I( "GEOM_POINT_I", 2 ) + + "
      " + tr( "GEOM_X_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 2 ) + PRINT_DOUBLE( aDbls[5], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::EDGE: aKindStr = tr( "GEOM_EDGE" ); break; case GEOM::GEOM_IKindOfShape::VERTEX: aKindStr = tr( "GEOM_VERTEX" ); - theParameters = tr( "GEOM_COORDINATES" ) + - "\n" + tr( "GEOM_X" ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + - "\n" + tr( "GEOM_Y" ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + - "\n" + tr( "GEOM_Z" ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ); + theParameters = TITLE( "GEOM_COORDINATES" ) + + "
      " + tr( "GEOM_X" ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y" ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z" ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ); + break; + case GEOM::GEOM_IKindOfShape::LCS: + aKindStr = tr( "GEOM_LCS" ); + theParameters = TITLE("GEOM_POSITION") + + "
      " + tr( "GEOM_X_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[0], aLenPrecision ) + + "
      " + tr( "GEOM_Y_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[1], aLenPrecision ) + + "
      " + tr( "GEOM_Z_I" ).arg( 0 ) + PRINT_DOUBLE( aDbls[2], aLenPrecision ) + + "
      " + TITLE( "GEOM_X_AXIS") + + "
      " + "Xx :" + PRINT_DOUBLE( aDbls[3], aLenPrecision ) + + "
      " + "Xy :" + PRINT_DOUBLE( aDbls[4], aLenPrecision ) + + "
      " + "Xz :" + PRINT_DOUBLE( aDbls[5], aLenPrecision ) + + "
      " + TITLE( "GEOM_Y_AXIS") + + "
      " + "Yx :" + PRINT_DOUBLE( aDbls[6], aLenPrecision ) + + "
      " + "Yy :" + PRINT_DOUBLE( aDbls[7], aLenPrecision ) + + "
      " + "Yz :" + PRINT_DOUBLE( aDbls[8], aLenPrecision ) + + "
      " + TITLE( "GEOM_Z_AXIS") + + "
      " + "Zx :" + PRINT_DOUBLE( aDbls[9], aLenPrecision ) + + "
      " + "Zy :" + PRINT_DOUBLE( aDbls[10], aLenPrecision ) + + "
      " + "Zz :" + PRINT_DOUBLE( aDbls[11], aLenPrecision ); break; case GEOM::GEOM_IKindOfShape::ADVANCED: { @@ -629,4 +648,4 @@ void MeasureGUI_WhatisDlg::SelectionIntoArgument() mySelEdit->setText(GEOMBase::GetName(myObj.get())); processObject(); redisplayPreview(); -} \ No newline at end of file +} From 891fb0379d44e6067d51b70b7bd59bc9cfd012f1 Mon Sep 17 00:00:00 2001 From: eap Date: Thu, 20 Aug 2015 16:47:26 +0300 Subject: [PATCH 32/54] IPAL52616: Wrong documentation of Check compound of Blocks --- .../gui/GEOM/input/check_compound_of_blocks.doc | 15 ++++++++++++--- .../gui/GEOM/input/check_self_intersections.doc | 6 +++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/doc/salome/gui/GEOM/input/check_compound_of_blocks.doc b/doc/salome/gui/GEOM/input/check_compound_of_blocks.doc index d903fc1ba..486184871 100644 --- a/doc/salome/gui/GEOM/input/check_compound_of_blocks.doc +++ b/doc/salome/gui/GEOM/input/check_compound_of_blocks.doc @@ -2,7 +2,8 @@ \page check_compound_of_blocks_page Check Compound of Blocks -This operation checks whether a shape is a compound of glued blocks. +This operation checks whether a shape is a compound of glued blocks +and tries to improve the shape to make it include only valid blocks. \image html measures10.png @@ -27,7 +28,15 @@ In this dialog: - Not glued; - Not connected; - Extra or degenerated edge. -- Incriminated Sub-shapes field outputs the list of sub-shapes that cause problem. It is possible to select them in the list and publish in the study for further analysis by clicking \b Apply or Apply and Close button. +- Incriminated Sub-shapes field outputs the list of sub-shapes that cause problem. +- \b Apply and Apply and Close buttons launch an improving process +and publish a result shape which includes valid blocks only. The +improving process tries to + - remove seam edges and degenerated edges of surfaces of revolution; + - re-approximate surfaces to exclude singularities on boundaries; + - unite edges and faces; + - glue faces. + \n TUI Command: @@ -38,4 +47,4 @@ is returned, and encountered errors are printed in the python console. See also a \ref tui_check_compound_of_blocks_page "TUI example". -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/GEOM/input/check_self_intersections.doc b/doc/salome/gui/GEOM/input/check_self_intersections.doc index f806d4dd6..c92695a10 100644 --- a/doc/salome/gui/GEOM/input/check_self_intersections.doc +++ b/doc/salome/gui/GEOM/input/check_self_intersections.doc @@ -8,7 +8,7 @@ There are two ways to check self-intersections. \anchor check_self_intersections_topological -

      Check topological intersections

      +

      Check topological intersections

      This operation checks the topology of the selected shape to detect self-intersections. @@ -38,7 +38,7 @@ where: \n See also a \ref tui_check_self_intersections_page "TUI example". \anchor check_self_intersections_fast -

      Fast intersection

      +

      Fast intersection

      This operations allows to quickly detect self-interferences of the given shape by means of algorithm based on mesh intersections. @@ -61,4 +61,4 @@ where: \n See also a \ref tui_check_self_intersections_fast_page "TUI example". -*/ \ No newline at end of file +*/ From 18906b1406e88bdba426abf6f86a5f6e882862d8 Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 25 Aug 2015 17:40:04 +0300 Subject: [PATCH 33/54] Import STEP: read more units (all currently supported by OCCT) --- src/STEPPlugin/STEPPlugin_ImportDriver.cxx | 502 +++++++++++---------- 1 file changed, 260 insertions(+), 242 deletions(-) diff --git a/src/STEPPlugin/STEPPlugin_ImportDriver.cxx b/src/STEPPlugin/STEPPlugin_ImportDriver.cxx index a00ccdcd8..961dd77be 100644 --- a/src/STEPPlugin/STEPPlugin_ImportDriver.cxx +++ b/src/STEPPlugin/STEPPlugin_ImportDriver.cxx @@ -66,239 +66,242 @@ #include #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC -//============================================================================= -/*! - * GetShape() - */ -//============================================================================= - -TopoDS_Shape GetShape(const Handle(Standard_Transient) &theEnti, - const Handle(Transfer_TransientProcess) &theTP) +namespace { - TopoDS_Shape aResult; - Handle(Transfer_Binder) aBinder = theTP->Find(theEnti); - - if (aBinder.IsNull()) { + //============================================================================= + /*! + * GetShape() + */ + //============================================================================= + + TopoDS_Shape GetShape(const Handle(Standard_Transient) &theEnti, + const Handle(Transfer_TransientProcess) &theTP) + { + TopoDS_Shape aResult; + Handle(Transfer_Binder) aBinder = theTP->Find(theEnti); + + if (aBinder.IsNull()) { + return aResult; + } + + aResult = TransferBRep::ShapeResult(aBinder); + + return aResult; + } + + //============================================================================= + /*! + * GetLabel() + */ + //============================================================================= + + TDF_Label GetLabel(const Handle(Standard_Transient) &theEnti, + const TDF_Label &theShapeLabel, + const TopoDS_Shape &aShape) + { + TDF_Label aResult; + + if (theEnti->IsKind + (STANDARD_TYPE(StepGeom_GeometricRepresentationItem))) { + // check all named shapes using iterator + TDF_ChildIDIterator anIt + (theShapeLabel, TDataStd_Name::GetID(), Standard_True); + + for (; anIt.More(); anIt.Next()) { + Handle(TDataStd_Name) nameAttr = + Handle(TDataStd_Name)::DownCast(anIt.Value()); + + if (nameAttr.IsNull()) { + continue; + } + + TDF_Label aLab = nameAttr->Label(); + Handle(TNaming_NamedShape) shAttr; + + if (aLab.FindAttribute(TNaming_NamedShape::GetID(), shAttr) && + shAttr->Get().IsEqual(aShape)) { + aResult = aLab; + } + } + } + + // create label and set shape + if (aResult.IsNull()) { + TDF_TagSource aTag; + + aResult = aTag.NewChild(theShapeLabel); + + TNaming_Builder tnBuild (aResult); + + tnBuild.Generated(aShape); + } + return aResult; } - aResult = TransferBRep::ShapeResult(aBinder); - - return aResult; -} - -//============================================================================= -/*! - * GetLabel() - */ -//============================================================================= - -TDF_Label GetLabel(const Handle(Standard_Transient) &theEnti, - const TDF_Label &theShapeLabel, - const TopoDS_Shape &aShape) -{ - TDF_Label aResult; - - if (theEnti->IsKind - (STANDARD_TYPE(StepGeom_GeometricRepresentationItem))) { - // check all named shapes using iterator - TDF_ChildIDIterator anIt - (theShapeLabel, TDataStd_Name::GetID(), Standard_True); - - for (; anIt.More(); anIt.Next()) { - Handle(TDataStd_Name) nameAttr = - Handle(TDataStd_Name)::DownCast(anIt.Value()); - - if (nameAttr.IsNull()) { - continue; - } - - TDF_Label aLab = nameAttr->Label(); - Handle(TNaming_NamedShape) shAttr; - - if (aLab.FindAttribute(TNaming_NamedShape::GetID(), shAttr) && - shAttr->Get().IsEqual(aShape)) { - aResult = aLab; - } - } - } - - // create label and set shape - if (aResult.IsNull()) { - TDF_TagSource aTag; - - aResult = aTag.NewChild(theShapeLabel); - - TNaming_Builder tnBuild (aResult); - - tnBuild.Generated(aShape); - } - - return aResult; -} - -//============================================================================= -/*! - * StoreName() - */ -//============================================================================= - -void StoreName( const Handle(Standard_Transient) &theEnti, - const TopTools_IndexedMapOfShape &theIndices, - const Handle(Transfer_TransientProcess) &theTP, - const TDF_Label &theShapeLabel) -{ - Handle(TCollection_HAsciiString) aName; - - if (theEnti->IsKind(STANDARD_TYPE(StepShape_TopologicalRepresentationItem)) || - theEnti->IsKind(STANDARD_TYPE(StepGeom_GeometricRepresentationItem))) { - aName = Handle(StepRepr_RepresentationItem)::DownCast(theEnti)->Name(); - } else { - Handle(StepBasic_ProductDefinition) PD = - Handle(StepBasic_ProductDefinition)::DownCast(theEnti); - - if (PD.IsNull() == Standard_False) { - Handle(StepBasic_Product) Prod = PD->Formation()->OfProduct(); - aName = Prod->Name(); - } - } - - bool isValidName = false; - - if (aName.IsNull() == Standard_False) { - isValidName = true; - - if (aName->UsefullLength() < 1) { - isValidName = false; - } else if (aName->UsefullLength() == 4 && - toupper (aName->Value(1)) == 'N' && - toupper (aName->Value(2)) == 'O' && - toupper (aName->Value(3)) == 'N' && - toupper (aName->Value(4)) == 'E') { - // skip 'N0NE' name - isValidName = false; + //============================================================================= + /*! + * StoreName() + */ + //============================================================================= + + void StoreName( const Handle(Standard_Transient) &theEnti, + const TopTools_IndexedMapOfShape &theIndices, + const Handle(Transfer_TransientProcess) &theTP, + const TDF_Label &theShapeLabel) + { + Handle(TCollection_HAsciiString) aName; + + if (theEnti->IsKind(STANDARD_TYPE(StepShape_TopologicalRepresentationItem)) || + theEnti->IsKind(STANDARD_TYPE(StepGeom_GeometricRepresentationItem))) { + aName = Handle(StepRepr_RepresentationItem)::DownCast(theEnti)->Name(); } else { - // special check to pass names like "Open CASCADE STEP translator 6.3 1" - TCollection_AsciiString aSkipName ("Open CASCADE STEP translator"); + Handle(StepBasic_ProductDefinition) PD = + Handle(StepBasic_ProductDefinition)::DownCast(theEnti); + + if (PD.IsNull() == Standard_False) { + Handle(StepBasic_Product) Prod = PD->Formation()->OfProduct(); + aName = Prod->Name(); + } + } + + bool isValidName = false; - if (aName->Length() >= aSkipName.Length()) { - if (aName->String().SubString - (1, aSkipName.Length()).IsEqual(aSkipName)) { - isValidName = false; + if (aName.IsNull() == Standard_False) { + isValidName = true; + + if (aName->UsefullLength() < 1) { + isValidName = false; + } else if (aName->UsefullLength() == 4 && + toupper (aName->Value(1)) == 'N' && + toupper (aName->Value(2)) == 'O' && + toupper (aName->Value(3)) == 'N' && + toupper (aName->Value(4)) == 'E') { + // skip 'N0NE' name + isValidName = false; + } else { + // special check to pass names like "Open CASCADE STEP translator 6.3 1" + TCollection_AsciiString aSkipName ("Open CASCADE STEP translator"); + + if (aName->Length() >= aSkipName.Length()) { + if (aName->String().SubString + (1, aSkipName.Length()).IsEqual(aSkipName)) { + isValidName = false; + } + } + } + } + + if (isValidName) { + TCollection_ExtendedString aNameExt (aName->ToCString()); + + // find target shape + TopoDS_Shape S = GetShape(theEnti, theTP); + + if (S.IsNull()) { + return; + } + + // as PRODUCT can be included in the main shape + // several times, we look here for all iclusions. + Standard_Integer isub, nbSubs = theIndices.Extent(); + + for (isub = 1; isub <= nbSubs; isub++) { + TopoDS_Shape aSub = theIndices.FindKey(isub); + + if (aSub.IsPartner(S)) { + TDF_Label L = GetLabel(theEnti, theShapeLabel, aSub); + + // set a name + TDataStd_Name::Set(L, aNameExt); } } } } - if (isValidName) { - TCollection_ExtendedString aNameExt (aName->ToCString()); + //============================================================================= + /*! + * StoreMaterial() + */ + //============================================================================= - // find target shape - TopoDS_Shape S = GetShape(theEnti, theTP); - - if (S.IsNull()) { - return; - } - - // as PRODUCT can be included in the main shape - // several times, we look here for all iclusions. - Standard_Integer isub, nbSubs = theIndices.Extent(); - - for (isub = 1; isub <= nbSubs; isub++) { - TopoDS_Shape aSub = theIndices.FindKey(isub); - - if (aSub.IsPartner(S)) { - TDF_Label L = GetLabel(theEnti, theShapeLabel, aSub); - - // set a name - TDataStd_Name::Set(L, aNameExt); - } - } - } -} - -//============================================================================= -/*! - * StoreMaterial() - */ -//============================================================================= - -void StoreMaterial( const Handle(Standard_Transient) &theEnti, - const TopTools_IndexedMapOfShape &theIndices, - const Handle(Transfer_TransientProcess) &theTP, - const TDF_Label &theShapeLabel ) -{ - // Treat Product Definition Shape only. - Handle(StepRepr_ProductDefinitionShape) aPDS = + void StoreMaterial( const Handle(Standard_Transient) &theEnti, + const TopTools_IndexedMapOfShape &theIndices, + const Handle(Transfer_TransientProcess) &theTP, + const TDF_Label &theShapeLabel ) + { + // Treat Product Definition Shape only. + Handle(StepRepr_ProductDefinitionShape) aPDS = Handle(StepRepr_ProductDefinitionShape)::DownCast(theEnti); - Handle(StepBasic_ProductDefinition) aProdDef; + Handle(StepBasic_ProductDefinition) aProdDef; - if(aPDS.IsNull() == Standard_False) { - // Product Definition Shape ==> Product Definition - aProdDef = aPDS->Definition().ProductDefinition(); - } + if(aPDS.IsNull() == Standard_False) { + // Product Definition Shape ==> Product Definition + aProdDef = aPDS->Definition().ProductDefinition(); + } - if (aProdDef.IsNull() == Standard_False) { - // Product Definition ==> Property Definition - const Interface_Graph &aGraph = theTP->Graph(); - Interface_EntityIterator aSubs = aGraph.Sharings(aProdDef); - TopoDS_Shape aShape; + if (aProdDef.IsNull() == Standard_False) { + // Product Definition ==> Property Definition + const Interface_Graph &aGraph = theTP->Graph(); + Interface_EntityIterator aSubs = aGraph.Sharings(aProdDef); + TopoDS_Shape aShape; - for(aSubs.Start(); aSubs.More(); aSubs.Next()) { - Handle(StepRepr_PropertyDefinition) aPropD = - Handle(StepRepr_PropertyDefinition)::DownCast(aSubs.Value()); + for(aSubs.Start(); aSubs.More(); aSubs.Next()) { + Handle(StepRepr_PropertyDefinition) aPropD = + Handle(StepRepr_PropertyDefinition)::DownCast(aSubs.Value()); - if(aPropD.IsNull() == Standard_False) { - // Property Definition ==> Representation. - Interface_EntityIterator aSubs1 = aGraph.Sharings(aPropD); + if(aPropD.IsNull() == Standard_False) { + // Property Definition ==> Representation. + Interface_EntityIterator aSubs1 = aGraph.Sharings(aPropD); - for(aSubs1.Start(); aSubs1.More(); aSubs1.Next()) { - Handle(StepRepr_PropertyDefinitionRepresentation) aPDR = - Handle(StepRepr_PropertyDefinitionRepresentation):: + for(aSubs1.Start(); aSubs1.More(); aSubs1.Next()) { + Handle(StepRepr_PropertyDefinitionRepresentation) aPDR = + Handle(StepRepr_PropertyDefinitionRepresentation):: DownCast(aSubs1.Value()); - if(aPDR.IsNull() == Standard_False) { - // Property Definition ==> Material Name. - Handle(StepRepr_Representation) aRepr = aPDR->UsedRepresentation(); + if(aPDR.IsNull() == Standard_False) { + // Property Definition ==> Material Name. + Handle(StepRepr_Representation) aRepr = aPDR->UsedRepresentation(); - if(aRepr.IsNull() == Standard_False) { - Standard_Integer ir; + if(aRepr.IsNull() == Standard_False) { + Standard_Integer ir; - for(ir = 1; ir <= aRepr->NbItems(); ir++) { - Handle(StepRepr_RepresentationItem) aRI = aRepr->ItemsValue(ir); - Handle(StepRepr_DescriptiveRepresentationItem) aDRI = - Handle(StepRepr_DescriptiveRepresentationItem)::DownCast(aRI); + for(ir = 1; ir <= aRepr->NbItems(); ir++) { + Handle(StepRepr_RepresentationItem) aRI = aRepr->ItemsValue(ir); + Handle(StepRepr_DescriptiveRepresentationItem) aDRI = + Handle(StepRepr_DescriptiveRepresentationItem)::DownCast(aRI); - if(aDRI.IsNull() == Standard_False) { - // Get shape from Product Definition - Handle(TCollection_HAsciiString) aMatName = aDRI->Name(); + if(aDRI.IsNull() == Standard_False) { + // Get shape from Product Definition + Handle(TCollection_HAsciiString) aMatName = aDRI->Name(); - if(aMatName.IsNull() == Standard_False) { - TCollection_ExtendedString - aMatNameExt (aMatName->ToCString()); - - if (aShape.IsNull()) { - // Get the shape. - aShape = GetShape(aProdDef, theTP); + if(aMatName.IsNull() == Standard_False) { + TCollection_ExtendedString + aMatNameExt (aMatName->ToCString()); if (aShape.IsNull()) { - return; + // Get the shape. + aShape = GetShape(aProdDef, theTP); + + if (aShape.IsNull()) { + return; + } } - } - // as PRODUCT can be included in the main shape - // several times, we look here for all iclusions. - Standard_Integer isub, nbSubs = theIndices.Extent(); + // as PRODUCT can be included in the main shape + // several times, we look here for all iclusions. + Standard_Integer isub, nbSubs = theIndices.Extent(); - for (isub = 1; isub <= nbSubs; isub++) { - TopoDS_Shape aSub = theIndices.FindKey(isub); + for (isub = 1; isub <= nbSubs; isub++) { + TopoDS_Shape aSub = theIndices.FindKey(isub); - if (aSub.IsPartner(aShape)) { - TDF_Label aLabel = - GetLabel(aProdDef, theShapeLabel, aSub); + if (aSub.IsPartner(aShape)) { + TDF_Label aLabel = + GetLabel(aProdDef, theShapeLabel, aSub); - // set a name - TDataStd_Comment::Set(aLabel, aMatNameExt); + // set a name + TDataStd_Comment::Set(aLabel, aMatNameExt); + } } } } @@ -310,7 +313,53 @@ void StoreMaterial( const Handle(Standard_Transient) &theEnti, } } } -} + + TCollection_AsciiString ToNamedUnit( const TCollection_AsciiString& unit ) + { + TCollection_AsciiString result = unit; + result.LowerCase(); + if ( result == "mil" ) result = "milliinch"; + return result; + } + + TCollection_AsciiString ToOcctUnit( const TCollection_AsciiString& unit, TCollection_AsciiString& error ) + { + TCollection_AsciiString result = "M", u = ToNamedUnit(unit); + u.LowerCase(); + + if (u == "inch") + result = "INCH"; + else if (u == "milliinch") + result = "MIL"; + else if (u == "microinch") + result = "UIN"; + else if (u == "foot") + result = "FT"; + else if (u == "mile") + result = "MI"; + else if (u == "metre") + result = "M"; + else if (u == "kilometre") + result = "KM"; + else if (u == "millimetre") + result = "MM"; + else if (u == "centimetre") + result = "CM"; + else if (u == "micrometre") + result = "UM"; + else if (u.IsEmpty()) + result = "M"; + else + error = "The file contains not supported units"; + + // TODO (for other units) + // else + // result = "??" + + return result; + } + +} // end of namespace //======================================================================= //function : GetID @@ -377,21 +426,8 @@ Standard_Integer STEPPlugin_ImportDriver::Execute( TFunction_Logbook& log ) cons TColStd_SequenceOfAsciiString anUnitSolidAngleNames; aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames); if (anUnitLengthNames.Length() > 0) { - TCollection_AsciiString aLenUnits = anUnitLengthNames.First(); - if (aLenUnits == "millimetre") - Interface_Static::SetCVal("xstep.cascade.unit", "MM"); - else if (aLenUnits == "centimetre") - Interface_Static::SetCVal("xstep.cascade.unit", "CM"); - else if (aLenUnits == "metre" || aLenUnits.IsEmpty()) - Interface_Static::SetCVal("xstep.cascade.unit", "M"); - else if (aLenUnits == "INCH") - Interface_Static::SetCVal("xstep.cascade.unit", "INCH"); - else { - anError = "The file contains not supported units."; - } - // TODO (for other units than mm, cm, m or inch) - // else if (aLenUnits == "") - // Interface_Static::SetCVal("xstep.cascade.unit", "???"); + TCollection_AsciiString aLenUnits = ToOcctUnit(anUnitLengthNames.First(), anError); + Interface_Static::SetCVal("xstep.cascade.unit", aLenUnits.ToCString()); } } else { @@ -548,10 +584,10 @@ GetCreationInformation( std::string& theOperationName, TCollection_AsciiString STEPPlugin_ImportDriver::GetValue( const TCollection_AsciiString& theFileName, - const TCollection_AsciiString& theParameterName, - TCollection_AsciiString& theError ) + const TCollection_AsciiString& theParameterName, + TCollection_AsciiString& theError ) { - Handle(TCollection_HAsciiString) aValue; + TCollection_AsciiString aValue; if (theParameterName != "LEN_UNITS") { theError = theParameterName + " parameter reading is not supported by STEP plugin"; @@ -575,23 +611,8 @@ STEPPlugin_ImportDriver::GetValue( const TCollection_AsciiString& theFileName, TColStd_SequenceOfAsciiString anUnitAngleNames; TColStd_SequenceOfAsciiString anUnitSolidAngleNames; aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames); - if (anUnitLengthNames.Length() > 0) { - aValue = new TCollection_HAsciiString( anUnitLengthNames.First() ); - /* - TCollection_AsciiString aLenUnits = anUnitLengthNames.First(); - if (aLenUnits == "millimetre") - aValue = new TCollection_HAsciiString ("MM"); - else if (aLenUnits == "centimetre") - aValue = new TCollection_HAsciiString ("CM"); - else if (aLenUnits == "metre") - aValue = new TCollection_HAsciiString ("M"); - else if (aLenUnits == "INCH") - aValue = new TCollection_HAsciiString ("INCH"); - // TODO (for other units than mm, cm, m or inch) - //else if (aLenUnits == "") - // aValue = new TCollection_HAsciiString (""); - */ - } + if (anUnitLengthNames.Length() > 0) + aValue = ToNamedUnit( anUnitLengthNames.First() ); } else { theError = theFileName + " reading failed"; @@ -601,10 +622,7 @@ STEPPlugin_ImportDriver::GetValue( const TCollection_AsciiString& theFileName, Handle(Standard_Failure) aFail = Standard_Failure::Caught(); theError = aFail->GetMessageString(); } - if (!aValue.IsNull()) - return aValue->String(); - else - return TCollection_AsciiString(); + return aValue; } From a8b4700b54cef3af6b0ad34d6f1e885b52f916c7 Mon Sep 17 00:00:00 2001 From: vsr Date: Fri, 28 Aug 2015 10:42:03 +0300 Subject: [PATCH 34/54] 0023149: EDF - Problem with planar face creation --- src/GEOMImpl/GEOMImpl_ShapeDriver.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index 5462bbdf4..35224af79 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -706,7 +706,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const if (aShape.IsNull()) return 0; // Check shape validity - BRepCheck_Analyzer ana (aShape, false); + BRepCheck_Analyzer ana (aShape, true); if (!ana.IsValid()) { //Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result"); // For Mantis issue 0021772: EDF 2336 GEOM: Non valid face created from two circles From c744f39b399f644f8375070460f019d945b657ce Mon Sep 17 00:00:00 2001 From: skv Date: Wed, 2 Sep 2015 13:53:03 +0300 Subject: [PATCH 35/54] 0023134: EDF GEOM: Regression with getinplace --- src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx b/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx index c7abe5e96..878faf172 100644 --- a/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx +++ b/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx @@ -182,7 +182,7 @@ Standard_Integer GEOMAlgo_GetInPlaceAPI::GetInPlaceOld if (fabs(tab_aWhat[3] - tab_aWhere[3]) <= aMassTol && aPnt_aWhat.Distance(aPnt) <= aTolConf) isFound = true; else { - if ((tab_aWhat[3] - tab_aWhere[3]) > aMassTol) { + if (tab_aWhat[3] > tab_aWhere[3]) { aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape(); aVertex = TopoDS::Vertex( aPntShape ); BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() ); From e27516a96fbd6b149b05e7a7d86a6eebea8947ac Mon Sep 17 00:00:00 2001 From: vsr Date: Wed, 2 Sep 2015 17:16:57 +0300 Subject: [PATCH 36/54] 0023152: EDF GEOM: Use a self-intersected wire with MakeFace --- doc/salome/gui/GEOM/input/creating_face.doc | 8 +- .../gui/GEOM/input/creating_isoline.doc | 4 +- src/BuildGUI/BuildGUI_FaceDlg.cxx | 10 +- src/BuildGUI/BuildGUI_ShellDlg.cxx | 5 +- src/GEOMGUI/GEOM_msg_en.ts | 6 +- src/GEOMGUI/GEOM_msg_fr.ts | 6 +- src/GEOMGUI/GEOM_msg_ja.ts | 4 + src/GEOMImpl/GEOMImpl_ShapeDriver.cxx | 141 ++++++++++++++---- src/GEOM_SWIG/geomBuilder.py | 12 +- 9 files changed, 149 insertions(+), 47 deletions(-) diff --git a/doc/salome/gui/GEOM/input/creating_face.doc b/doc/salome/gui/GEOM/input/creating_face.doc index cb626f83d..e75288de7 100644 --- a/doc/salome/gui/GEOM/input/creating_face.doc +++ b/doc/salome/gui/GEOM/input/creating_face.doc @@ -11,7 +11,7 @@ of the operation will be a GEOM_Object (FACE). \n Firstly, to create a \b Face you need to select input shape(s). The list of input shapes can include shapes of any type except vertices; if the shapes are neither wires nor edges, the algorithm extracts all edges from -the input shapes and works on the obtaineed edges. +the input shapes and works on the obtained edges. \n The edges and wires do not necessarily have to be closed, the algorithm automatically builds a wire of maximum length from all given edges and wires. If several closed wires are detected the algorithm tries @@ -26,7 +26,7 @@ exceeds 1e-06, a warning will be shown, but the face will be created and published in the study in a normal way. Using such faces can lead to failures or unpredictable results in most operations. -\n The \b Result will be a \b GEOM_Object (FACE). +\n The \b Result will be a \b GEOM_Object. It can be either a single face or, in specific cases, a compound of faces. \n TUI Command: geompy.MakeFaceWires([list of Shapes], isPlanarWanted) \n Arguments: Name + 1 wire. @@ -35,7 +35,7 @@ or unpredictable results in most operations. \n Secondly, it is possible to create a face based on another face's surface and bounded by a wire. -\n The \b Result will be a \b GEOM_Object (FACE). +\n The \b Result will be a \b GEOM_Object (face). \n TUI Command: geompy.MakeFaceFromSurface(theFace, theWire) \n Arguments: Name + 1 face + 1 wire. @@ -50,7 +50,7 @@ and constraints: \note Please note, that the constraint face must be connected to a reference edge. -\n The \b Result will be a \b GEOM_Object (FACE). +\n The \b Result will be a \b GEOM_Object (face). \n TUI Command: geompy.MakeFaceWithConstraints([List of constraints]) \n Arguments: Name + List of input edges and constraint faces. If a constraint diff --git a/doc/salome/gui/GEOM/input/creating_isoline.doc b/doc/salome/gui/GEOM/input/creating_isoline.doc index c69418547..9736a2982 100644 --- a/doc/salome/gui/GEOM/input/creating_isoline.doc +++ b/doc/salome/gui/GEOM/input/creating_isoline.doc @@ -3,7 +3,9 @@ \page create_isoline_page Isoline \b Isoline is a 3D curve built on a bounded face limited by [Umin, Umax] and [Vmin, Vmax] -values of U and V parameters. For all points of the isoline U or V parameter value is constant. +values of U and V parameters. For all points of the isoline U or V parameter value is constant. + +Result of this operation is either a single edge or a compound of edges. To create an \b Isoline of a face in the Main Menu select New Entity - > Basic - > Isoline. diff --git a/src/BuildGUI/BuildGUI_FaceDlg.cxx b/src/BuildGUI/BuildGUI_FaceDlg.cxx index 1f42c752a..14ac07bb5 100644 --- a/src/BuildGUI/BuildGUI_FaceDlg.cxx +++ b/src/BuildGUI/BuildGUI_FaceDlg.cxx @@ -659,8 +659,6 @@ bool BuildGUI_FaceDlg::execute( ObjectList& objects ) } if (!anObj->_is_nil()) { - objects.push_back(anObj._retn()); - if ( !anOper->IsDone() && QString(anOper->GetErrorCode()) == "MAKE_FACE_TOLERANCE_TOO_BIG") { if ( !IsPreview() ) { SUIT_OverrideCursor wc; @@ -670,6 +668,14 @@ bool BuildGUI_FaceDlg::execute( ObjectList& objects ) } anOper->SetErrorCode("PAL_NO_ERROR"); } + else if ( anObj->GetShapeType() == GEOM::COMPOUND ) { + if ( !IsPreview() ) { + SUIT_MessageBox::warning(this, + QObject::tr("GEOM_WRN_WARNING"), + QObject::tr("GEOM_WRN_FACES_NOT_FACE")); + } + } + objects.push_back(anObj._retn()); } return res; diff --git a/src/BuildGUI/BuildGUI_ShellDlg.cxx b/src/BuildGUI/BuildGUI_ShellDlg.cxx index 36ed6ad7e..6674e9eac 100644 --- a/src/BuildGUI/BuildGUI_ShellDlg.cxx +++ b/src/BuildGUI/BuildGUI_ShellDlg.cxx @@ -262,10 +262,7 @@ bool BuildGUI_ShellDlg::execute( ObjectList& objects ) GEOM::GEOM_Object_var anObj = anOper->MakeShell( objlist.in() ); if ( !anObj->_is_nil() ) { - TopoDS_Shape aShell; - GEOMBase::GetShape(anObj, aShell, TopAbs_SHELL); - - if (aShell.IsNull()) { + if (anObj->GetShapeType() == GEOM::COMPOUND) { SUIT_MessageBox::warning(this, QObject::tr("GEOM_WRN_WARNING"), QObject::tr("GEOM_WRN_FACES_NOT_SHELL")); diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 5bec27d7c..491d964f8 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -2426,7 +2426,11 @@ Please, select face, shell or solid and try again GEOM_WRN_FACES_NOT_SHELL - Unable to create a shell. Result is a compound of faces. + Unable to create single shell. Result is a compound of shells. + + + GEOM_WRN_FACES_NOT_FACE + Unable to create single face. Result is a compound of faces. WRN_SHAPE_UNCLOSED diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 8ff9bde85..ef98f61ec 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -2418,7 +2418,11 @@ Choisissez une face, une coque ou un solide et essayez de nouveau GEOM_WRN_FACES_NOT_SHELL - Impossible de créer une coque. Le résultat est un assemblage de faces. + Impossible de créer une coque. Le résultat est un assemblage de coques. + + + GEOM_WRN_FACES_NOT_FACE + Impossible de créer une face. Le résultat est un assemblage de faces. WRN_SHAPE_UNCLOSED diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts index 4a7d00101..2ed220891 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -2431,6 +2431,10 @@ GEOM_WRN_FACES_NOT_SHELL シェルを作成できません。面の結合です。 + + GEOM_WRN_FACES_NOT_FACE + Impossible de créer une face. Le résultat est un assemblage de faces. + WRN_SHAPE_UNCLOSED 閉じていないオブジェクト %1 からソリッドを作成できません diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index 35224af79..46b7d1d7b 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -107,6 +107,61 @@ #include +namespace +{ + // check that compound includes only shapes of expected type + bool checkCompound( TopoDS_Shape& c, TopAbs_ShapeEnum t ) + { + TopoDS_Iterator it( c, Standard_True, Standard_True ); + + // check that compound is not empty + bool result = it.More(); + + // => if expected type is TopAbs_SHAPE, we allow compound consisting of any shapes, this above check is enough + // => otherwise we have to check compound's content + // => compound sometimes can contain enclosed compound(s), we process them recursively and rebuild initial compound + + if ( t != TopAbs_SHAPE ) { + std::list compounds, shapes; + compounds.push_back( c ); + while ( !compounds.empty() && result ) { + // check that compound contains only shapes of expected type + TopoDS_Shape cc = compounds.front(); + compounds.pop_front(); + it.Initialize( cc, Standard_True, Standard_True ); + for ( ; it.More() && result; it.Next() ) { + TopAbs_ShapeEnum tt = it.Value().ShapeType(); + if ( tt == TopAbs_COMPOUND || tt == TopAbs_COMPSOLID ) { + compounds.push_back( it.Value() ); + continue; + } + shapes.push_back( it.Value() ); + result = tt == t; + } + } + if ( result ) { + if ( shapes.empty() ) { + result = false; + } + else if ( shapes.size() == 1 ) { + c = shapes.front(); + } + else { + BRep_Builder b; + TopoDS_Compound newc; + b.MakeCompound( newc ); + std::list ::const_iterator sit; + for ( sit = shapes.begin(); sit != shapes.end(); ++sit ) + b.Add( newc, *sit ); + c = newc; + } + } + } + + return result; + } +} + //modified by NIZNHY-PKV Wed Dec 28 13:48:20 2011f //static // void KeepEdgesOrder(const Handle(TopTools_HSequenceOfShape)& aEdges, @@ -146,12 +201,17 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const TopoDS_Shape aShape; TCollection_AsciiString aWarning; - std::list anExpectedType; + + // this is an exact type of expected shape, or shape in a compound if compound is allowed as a result (see below) + TopAbs_ShapeEnum anExpectedType = TopAbs_SHAPE; + // this should be true if result can be a compound of shapes of strict type (see above) + bool allowCompound = false; BRep_Builder B; if (aType == WIRE_EDGES) { - anExpectedType.push_back(TopAbs_WIRE); + // result may be only a single wire + anExpectedType = TopAbs_WIRE; Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); @@ -162,7 +222,9 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = MakeWireFromEdges(aShapes, aTolerance); } else if (aType == FACE_WIRE) { - anExpectedType.push_back(TopAbs_FACE); + // result may be a face or a compound of faces + anExpectedType = TopAbs_FACE; + allowCompound = true; Handle(GEOM_Function) aRefBase = aCI.GetBase(); TopoDS_Shape aShapeBase = aRefBase->GetValue(); @@ -197,7 +259,9 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } } else if (aType == FACE_WIRES) { - anExpectedType.push_back(TopAbs_FACE); + // result may be a face or a compound of faces + anExpectedType = TopAbs_FACE; + allowCompound = true; // Try to build a face from a set of wires and edges int ind; @@ -325,7 +389,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } } else if (aType == FACE_FROM_SURFACE) { - anExpectedType.push_back(TopAbs_FACE); + // result may be only a face + anExpectedType = TopAbs_FACE; Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); @@ -361,7 +426,9 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } } else if (aType == SHELL_FACES) { - anExpectedType.push_back(TopAbs_SHELL); + // result may be only a shell or a compound of shells + anExpectedType = TopAbs_SHELL; + allowCompound = true; Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); @@ -420,7 +487,9 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } else if (aType == SOLID_SHELLS) { - anExpectedType.push_back(TopAbs_SOLID); + // result may be only a solid or a compound of solids + anExpectedType = TopAbs_SOLID; + allowCompound = true; Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); @@ -463,7 +532,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = Sol; } else if (aType == COMPOUND_SHAPES) { - anExpectedType.push_back(TopAbs_COMPOUND); + // result may be only a compound of any shapes + allowCompound = true; Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); @@ -484,7 +554,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } else if (aType == EDGE_WIRE) { - anExpectedType.push_back(TopAbs_EDGE); + // result may be only an edge + anExpectedType = TopAbs_EDGE; Handle(GEOM_Function) aRefBase = aCI.GetBase(); TopoDS_Shape aWire = aRefBase->GetValue(); @@ -495,9 +566,9 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = MakeEdgeFromWire(aWire, LinTol, AngTol); } else if (aType == SOLID_FACES) { - anExpectedType.push_back(TopAbs_SOLID); - anExpectedType.push_back(TopAbs_COMPOUND); - anExpectedType.push_back(TopAbs_COMPSOLID); + // result may be only a solid or a compound of solids + anExpectedType = TopAbs_SOLID; + allowCompound = true; Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); @@ -534,7 +605,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = aMV.Shape(); } else if (aType == EDGE_CURVE_LENGTH) { - anExpectedType.push_back(TopAbs_EDGE); + // result may be only an edge + anExpectedType = TopAbs_EDGE; GEOMImpl_IVector aVI (aFunction); @@ -609,7 +681,12 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const BRepBuilderAPI_MakeEdge aME (ReOrientedCurve, UFirst, aParam); if (aME.IsDone()) aShape = aME.Shape(); - } else if (aType == SHAPE_ISOLINE) { + } + else if (aType == SHAPE_ISOLINE) { + // result may be only an edge or compound of edges + anExpectedType = TopAbs_EDGE; + allowCompound = true; + GEOMImpl_IIsoline aII (aFunction); Handle(GEOM_Function) aRefFace = aII.GetFace(); TopoDS_Shape aShapeFace = aRefFace->GetValue(); @@ -635,8 +712,11 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const Standard_NullObject::Raise ("Shape for isoline construction is not a face"); } - } else if (aType == EDGE_UV) { - anExpectedType.push_back(TopAbs_EDGE); + } + else if (aType == EDGE_UV) { + // result may be only an edge + anExpectedType = TopAbs_EDGE; + GEOMImpl_IShapeExtend aSE (aFunction); Handle(GEOM_Function) aRefEdge = aSE.GetShape(); TopoDS_Shape aShapeEdge = aRefEdge->GetValue(); @@ -646,8 +726,10 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = ExtendEdge(anEdge, aSE.GetUMin(), aSE.GetUMax()); } - } else if (aType == FACE_UV) { - anExpectedType.push_back(TopAbs_FACE); + } + else if (aType == FACE_UV) { + // result may be only a face + anExpectedType = TopAbs_FACE; GEOMImpl_IShapeExtend aSE (aFunction); Handle(GEOM_Function) aRefFace = aSE.GetShape(); @@ -660,8 +742,10 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = ExtendFace(aFace, aSE.GetUMin(), aSE.GetUMax(), aSE.GetVMin(), aSE.GetVMax()); } - } else if (aType == SURFACE_FROM_FACE) { - anExpectedType.push_back(TopAbs_FACE); + } + else if (aType == SURFACE_FROM_FACE) { + // result may be only a face + anExpectedType = TopAbs_FACE; GEOMImpl_IShapeExtend aSE (aFunction); Handle(GEOM_Function) aRefFace = aSE.GetShape(); @@ -715,17 +799,18 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = aSfs->Shape(); } - // Check if the result shape type is compatible with the expected. + // Check if the result shape is of expected type. const TopAbs_ShapeEnum aShType = aShape.ShapeType(); - if (!anExpectedType.empty()) { - bool ok = false; - std::list::const_iterator it; - for (it = anExpectedType.begin(); it != anExpectedType.end() && !ok; ++it) - ok = (*it == TopAbs_SHAPE || *it == aShType); - if (!ok) - Standard_ConstructionError::Raise("Result type check failed"); + bool ok = false; + if ( aShType == TopAbs_COMPOUND || aShType == TopAbs_COMPSOLID ) { + ok = allowCompound && checkCompound( aShape, anExpectedType ); } + else { + ok = ( anExpectedType == TopAbs_SHAPE ) || ( aShType == anExpectedType ); + } + if (!ok) + Standard_ConstructionError::Raise("Result type check failed"); aFunction->SetValue(aShape); diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index be3cffc07..46573011e 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -4679,7 +4679,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # 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. + # @return New GEOM.GEOM_Object, containing the created face (compound of faces). # # @ref tui_creation_face "Example" @ManageTransactions("ShapesOp") @@ -4699,7 +4699,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): publication is switched on, default value is used for result name. Returns: - New GEOM.GEOM_Object, containing the created face. + New GEOM.GEOM_Object, containing the created face (compound of faces). """ # Example: see GEOM_TestAll.py anObj = self.ShapesOp.MakeFace(theWire, isPlanarWanted) @@ -4721,7 +4721,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # 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. + # @return New GEOM.GEOM_Object, containing the created face (compound of faces). # # @ref tui_creation_face "Example" @ManageTransactions("ShapesOp") @@ -4741,7 +4741,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): publication is switched on, default value is used for result name. Returns: - New GEOM.GEOM_Object, containing the created face. + New GEOM.GEOM_Object, containing the created face (compound of faces). """ # Example: see GEOM_TestAll.py anObj = self.ShapesOp.MakeFaceWires(ToList(theWires), isPlanarWanted) @@ -4840,7 +4840,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # 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. + # @return New GEOM.GEOM_Object, containing the created shell (compound of shells). # # @ref tui_creation_shell "Example" @ManageTransactions("ShapesOp") @@ -4855,7 +4855,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): publication is switched on, default value is used for result name. Returns: - New GEOM.GEOM_Object, containing the created shell. + New GEOM.GEOM_Object, containing the created shell (compound of shells). """ # Example: see GEOM_TestAll.py anObj = self.ShapesOp.MakeShell( ToList( theFacesAndShells )) From c749922c02346a830293c8f344dc0187a81a8f2a Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 17 Sep 2015 16:44:08 +0300 Subject: [PATCH 37/54] 0023152: EDF GEOM: Use a self-intersected wire with MakeFace - Additional update of documentation for MakeShell() function --- doc/salome/gui/GEOM/input/creating_shell.doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/salome/gui/GEOM/input/creating_shell.doc b/doc/salome/gui/GEOM/input/creating_shell.doc index 32cc8783c..822b8d953 100644 --- a/doc/salome/gui/GEOM/input/creating_shell.doc +++ b/doc/salome/gui/GEOM/input/creating_shell.doc @@ -6,7 +6,7 @@ To create a \b Shell in the Main Menu select New Entity - > Build - > Shell \n You can create a \b Shell from a compound of faces or a list of faces or shells. -\n The \b Result will be a \b GEOM_Object (shell). +\n The \b Result will be a \b GEOM_Object. It can be either a single shell or, in specific cases, a compound of shells. \n TUI Command: geompy.MakeShell(ListOfShape) \n Arguments: Name + Compound of faces or List of faces having connected edges. From 1b44f73640fde3a290989b578cdfec8e89a406fa Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 17 Sep 2015 19:13:42 +0300 Subject: [PATCH 38/54] 0023164: Problem with Dump Study in case of an import - Fix problem caused by unhandled memory leaks --- src/BREPPlugin/BREPPlugin_GUI.cxx | 16 ++++++++++------ src/IGESPlugin/IGESPlugin_GUI.cxx | 16 ++++++++++------ src/STEPPlugin/STEPPlugin_GUI.cxx | 16 ++++++++++------ src/STLPlugin/STLPlugin_GUI.cxx | 16 ++++++++++------ src/VTKPlugin/VTKPlugin_GUI.cxx | 15 +++++++++------ src/XAOPlugin/XAOPlugin_ImportDlg.cxx | 5 +++++ 6 files changed, 54 insertions(+), 30 deletions(-) diff --git a/src/BREPPlugin/BREPPlugin_GUI.cxx b/src/BREPPlugin/BREPPlugin_GUI.cxx index 9da10a0d1..312919727 100644 --- a/src/BREPPlugin/BREPPlugin_GUI.cxx +++ b/src/BREPPlugin/BREPPlugin_GUI.cxx @@ -36,10 +36,13 @@ #include "GEOM_Operation.h" #include "GEOMBase.h" #include "GEOM_Displayer.h" +#include "GEOM_GenericObjPtr.h" #include #include CORBA_SERVER_HEADER(BREPPlugin) +typedef GEOM::GenericObjPtr BREPOpPtr; + //======================================================================= // function : BREPPlugin_GUI() // purpose : Constructor @@ -111,8 +114,8 @@ bool BREPPlugin_GUI::importBREP( SUIT_Desktop* parent ) SALOMEDS::Study_var dsStudy = GeometryGUI::ClientStudyToStudy( study->studyDS() ); GEOM::GEOM_IOperations_var op = GeometryGUI::GetGeomGen()->GetPluginOperations( dsStudy->StudyId(), "BREPPluginEngine" ); - GEOM::IBREPOperations_var brepOp = GEOM::IBREPOperations::_narrow( op ); - if ( CORBA::is_nil( brepOp ) ) return false; + BREPOpPtr brepOp = GEOM::IBREPOperations::_narrow( op ); + if ( brepOp.isNull() ) return false; QStringList fileNames = app->getOpenFileNames( SUIT_FileDlg::getLastVisitedPath().isEmpty() ? QDir::currentPath() : QString(""), tr( "BREP_FILES" ), @@ -126,7 +129,7 @@ bool BREPPlugin_GUI::importBREP( SUIT_Desktop* parent ) foreach( QString fileName, fileNames ) { SUIT_OverrideCursor wc; - GEOM_Operation transaction( app, brepOp.in() ); + GEOM_Operation transaction( app, brepOp.get() ); try { @@ -145,6 +148,7 @@ bool BREPPlugin_GUI::importBREP( SUIT_Desktop* parent ) entryList.append( so->GetID() ); transaction.commit(); GEOM_Displayer( study ).Display( main.in() ); + main->UnRegister(); } else { @@ -183,8 +187,8 @@ bool BREPPlugin_GUI::exportBREP( SUIT_Desktop* parent ) SALOMEDS::Study_var dsStudy = GeometryGUI::ClientStudyToStudy( study->studyDS() ); GEOM::GEOM_IOperations_var op = GeometryGUI::GetGeomGen()->GetPluginOperations( dsStudy->StudyId(), "BREPPluginEngine" ); - GEOM::IBREPOperations_var brepOp = GEOM::IBREPOperations::_narrow( op ); - if ( CORBA::is_nil( brepOp ) ) return false; + BREPOpPtr brepOp = GEOM::IBREPOperations::_narrow( op ); + if ( brepOp.isNull() ) return false; LightApp_SelectionMgr* sm = app->selectionMgr(); if ( !sm ) return false; @@ -212,7 +216,7 @@ bool BREPPlugin_GUI::exportBREP( SUIT_Desktop* parent ) SUIT_OverrideCursor wc; - GEOM_Operation transaction( app, brepOp.in() ); + GEOM_Operation transaction( app, brepOp.get() ); try { diff --git a/src/IGESPlugin/IGESPlugin_GUI.cxx b/src/IGESPlugin/IGESPlugin_GUI.cxx index da70682b7..f3dd0d0ac 100644 --- a/src/IGESPlugin/IGESPlugin_GUI.cxx +++ b/src/IGESPlugin/IGESPlugin_GUI.cxx @@ -37,10 +37,13 @@ #include "GEOM_Operation.h" #include "GEOMBase.h" #include "GEOM_Displayer.h" +#include "GEOM_GenericObjPtr.h" #include #include CORBA_SERVER_HEADER(IGESPlugin) +typedef GEOM::GenericObjPtr IGESOpPtr; + //======================================================================= // function : IGESPlugin_GUI() // purpose : Constructor @@ -109,8 +112,8 @@ bool IGESPlugin_GUI::importIGES( SUIT_Desktop* parent ) SALOMEDS::Study_var dsStudy = GeometryGUI::ClientStudyToStudy( study->studyDS() ); GEOM::GEOM_IOperations_var op = GeometryGUI::GetGeomGen()->GetPluginOperations( dsStudy->StudyId(), "IGESPluginEngine" ); - GEOM::IIGESOperations_var igesOp = GEOM::IIGESOperations::_narrow( op ); - if ( CORBA::is_nil( igesOp ) ) return false; + IGESOpPtr igesOp = GEOM::IIGESOperations::_narrow( op ); + if ( igesOp.isNull() ) return false; QStringList fileNames = app->getOpenFileNames( SUIT_FileDlg::getLastVisitedPath().isEmpty() ? QDir::currentPath() : QString(""), tr( "IGES_FILES" ), @@ -126,7 +129,7 @@ bool IGESPlugin_GUI::importIGES( SUIT_Desktop* parent ) { QString fileName = fileNames.at( i ); SUIT_OverrideCursor wc; - GEOM_Operation transaction( app, igesOp.in() ); + GEOM_Operation transaction( app, igesOp.get() ); bool ignoreUnits = false; try @@ -182,6 +185,7 @@ bool IGESPlugin_GUI::importIGES( SUIT_Desktop* parent ) entryList.append( so->GetID() ); transaction.commit(); GEOM_Displayer( study ).Display( main.in() ); + main->UnRegister(); } else { @@ -221,8 +225,8 @@ bool IGESPlugin_GUI::exportIGES( SUIT_Desktop* parent ) SALOMEDS::Study_var dsStudy = GeometryGUI::ClientStudyToStudy( study->studyDS() ); GEOM::GEOM_IOperations_var op = GeometryGUI::GetGeomGen()->GetPluginOperations( dsStudy->StudyId(), "IGESPluginEngine" ); - GEOM::IIGESOperations_var igesOp = GEOM::IIGESOperations::_narrow( op ); - if ( CORBA::is_nil( igesOp ) ) return false; + IGESOpPtr igesOp = GEOM::IIGESOperations::_narrow( op ); + if ( igesOp.isNull() ) return false; LightApp_SelectionMgr* sm = app->selectionMgr(); if ( !sm ) return false; @@ -251,7 +255,7 @@ bool IGESPlugin_GUI::exportIGES( SUIT_Desktop* parent ) SUIT_OverrideCursor wc; - GEOM_Operation transaction( app, igesOp.in() ); + GEOM_Operation transaction( app, igesOp.get() ); try { diff --git a/src/STEPPlugin/STEPPlugin_GUI.cxx b/src/STEPPlugin/STEPPlugin_GUI.cxx index 88686838e..c8f0300e3 100644 --- a/src/STEPPlugin/STEPPlugin_GUI.cxx +++ b/src/STEPPlugin/STEPPlugin_GUI.cxx @@ -36,10 +36,13 @@ #include "GEOM_Operation.h" #include "GEOMBase.h" #include "GEOM_Displayer.h" +#include "GEOM_GenericObjPtr.h" #include #include CORBA_SERVER_HEADER(STEPPlugin) +typedef GEOM::GenericObjPtr STEPOpPtr; + //======================================================================= // function : STEPPlugin_GUI() // purpose : Constructor @@ -111,8 +114,8 @@ bool STEPPlugin_GUI::importSTEP( SUIT_Desktop* parent ) SALOMEDS::Study_var dsStudy = GeometryGUI::ClientStudyToStudy( study->studyDS() ); GEOM::GEOM_IOperations_var op = GeometryGUI::GetGeomGen()->GetPluginOperations( dsStudy->StudyId(), "STEPPluginEngine" ); - GEOM::ISTEPOperations_var stepOp = GEOM::ISTEPOperations::_narrow( op ); - if ( CORBA::is_nil( stepOp ) ) return false; + STEPOpPtr stepOp = GEOM::ISTEPOperations::_narrow( op ); + if ( stepOp.isNull() ) return false; QStringList fileNames = app->getOpenFileNames( SUIT_FileDlg::getLastVisitedPath().isEmpty() ? QDir::currentPath() : QString(""), tr( "STEP_FILES" ), @@ -128,7 +131,7 @@ bool STEPPlugin_GUI::importSTEP( SUIT_Desktop* parent ) { QString fileName = fileNames.at( i ); SUIT_OverrideCursor wc; - GEOM_Operation transaction( app, stepOp.in() ); + GEOM_Operation transaction( app, stepOp.get() ); bool ignoreUnits = false; try @@ -189,6 +192,7 @@ bool STEPPlugin_GUI::importSTEP( SUIT_Desktop* parent ) } transaction.commit(); GEOM_Displayer( study ).Display( main.in() ); + main->UnRegister(); } else { @@ -228,8 +232,8 @@ bool STEPPlugin_GUI::exportSTEP( SUIT_Desktop* parent ) SALOMEDS::Study_var dsStudy = GeometryGUI::ClientStudyToStudy( study->studyDS() ); GEOM::GEOM_IOperations_var op = GeometryGUI::GetGeomGen()->GetPluginOperations( dsStudy->StudyId(), "STEPPluginEngine" ); - GEOM::ISTEPOperations_var stepOp = GEOM::ISTEPOperations::_narrow( op ); - if ( CORBA::is_nil( stepOp ) ) return false; + STEPOpPtr stepOp = GEOM::ISTEPOperations::_narrow( op ); + if ( stepOp.isNull() ) return false; LightApp_SelectionMgr* sm = app->selectionMgr(); if ( !sm ) return false; @@ -257,7 +261,7 @@ bool STEPPlugin_GUI::exportSTEP( SUIT_Desktop* parent ) SUIT_OverrideCursor wc; - GEOM_Operation transaction( app, stepOp.in() ); + GEOM_Operation transaction( app, stepOp.get() ); try { diff --git a/src/STLPlugin/STLPlugin_GUI.cxx b/src/STLPlugin/STLPlugin_GUI.cxx index 27311769a..d868adb97 100644 --- a/src/STLPlugin/STLPlugin_GUI.cxx +++ b/src/STLPlugin/STLPlugin_GUI.cxx @@ -37,10 +37,13 @@ #include "GEOM_Operation.h" #include "GEOMBase.h" #include "GEOM_Displayer.h" +#include "GEOM_GenericObjPtr.h" #include #include CORBA_SERVER_HEADER(STLPlugin) +typedef GEOM::GenericObjPtr STLOpPtr; + //======================================================================= // function : STLPlugin_GUI() // purpose : Constructor @@ -109,8 +112,8 @@ bool STLPlugin_GUI::importSTL( SUIT_Desktop* parent ) SALOMEDS::Study_var dsStudy = GeometryGUI::ClientStudyToStudy( study->studyDS() ); GEOM::GEOM_IOperations_var op = GeometryGUI::GetGeomGen()->GetPluginOperations( dsStudy->StudyId(), "STLPluginEngine" ); - GEOM::ISTLOperations_var stlOp = GEOM::ISTLOperations::_narrow( op ); - if ( CORBA::is_nil( stlOp ) ) return false; + STLOpPtr stlOp = GEOM::ISTLOperations::_narrow( op ); + if ( stlOp.isNull() ) return false; QStringList fileNames = app->getOpenFileNames( SUIT_FileDlg::getLastVisitedPath().isEmpty() ? QDir::currentPath() : QString(""), tr( "STL_FILES" ), @@ -124,7 +127,7 @@ bool STLPlugin_GUI::importSTL( SUIT_Desktop* parent ) foreach( QString fileName, fileNames ) { SUIT_OverrideCursor wc; - GEOM_Operation transaction( app, stlOp.in() ); + GEOM_Operation transaction( app, stlOp.get() ); try { @@ -143,6 +146,7 @@ bool STLPlugin_GUI::importSTL( SUIT_Desktop* parent ) entryList.append( so->GetID() ); transaction.commit(); GEOM_Displayer( study ).Display( main.in() ); + main->UnRegister(); } else { @@ -181,8 +185,8 @@ bool STLPlugin_GUI::exportSTL( SUIT_Desktop* parent ) SALOMEDS::Study_var dsStudy = GeometryGUI::ClientStudyToStudy( study->studyDS() ); GEOM::GEOM_IOperations_var op = GeometryGUI::GetGeomGen()->GetPluginOperations( dsStudy->StudyId(), "STLPluginEngine" ); - GEOM::ISTLOperations_var stlOp = GEOM::ISTLOperations::_narrow( op ); - if ( CORBA::is_nil( stlOp ) ) return false; + STLOpPtr stlOp = GEOM::ISTLOperations::_narrow( op ); + if ( stlOp.isNull() ) return false; LightApp_SelectionMgr* sm = app->selectionMgr(); if ( !sm ) return false; @@ -215,7 +219,7 @@ bool STLPlugin_GUI::exportSTL( SUIT_Desktop* parent ) SUIT_OverrideCursor wc; - GEOM_Operation transaction( app, stlOp.in() ); + GEOM_Operation transaction( app, stlOp.get() ); try { diff --git a/src/VTKPlugin/VTKPlugin_GUI.cxx b/src/VTKPlugin/VTKPlugin_GUI.cxx index ada1e297c..fbf7dfdc6 100644 --- a/src/VTKPlugin/VTKPlugin_GUI.cxx +++ b/src/VTKPlugin/VTKPlugin_GUI.cxx @@ -35,10 +35,13 @@ #include "GEOM_Operation.h" #include "GEOMBase.h" #include "GEOM_Displayer.h" +#include "GEOM_GenericObjPtr.h" #include #include CORBA_SERVER_HEADER(VTKPlugin) +typedef GEOM::GenericObjPtr VTKOpPtr; + //======================================================================= // function : VTKPlugin_GUI() // purpose : Constructor @@ -102,8 +105,8 @@ bool VTKPlugin_GUI::exportVTK( SUIT_Desktop* parent ) SALOMEDS::Study_var dsStudy = GeometryGUI::ClientStudyToStudy( study->studyDS() ); GEOM::GEOM_IOperations_var op = GeometryGUI::GetGeomGen()->GetPluginOperations( dsStudy->StudyId(), "VTKPluginEngine" ); - GEOM::IVTKOperations_var stlOp = GEOM::IVTKOperations::_narrow( op ); - if ( CORBA::is_nil( stlOp ) ) return false; + VTKOpPtr vtkOp = GEOM::IVTKOperations::_narrow( op ); + if ( vtkOp.isNull() ) return false; LightApp_SelectionMgr* sm = app->selectionMgr(); if ( !sm ) return false; @@ -132,16 +135,16 @@ bool VTKPlugin_GUI::exportVTK( SUIT_Desktop* parent ) SUIT_OverrideCursor wc; - GEOM_Operation transaction( app, stlOp.in() ); + GEOM_Operation transaction( app, vtkOp.get() ); try { app->putInfo( tr( "GEOM_PRP_EXPORT" ).arg( fileName ) ); transaction.start(); - stlOp->ExportVTK( obj, fileName.toUtf8().constData(), deflection ); + vtkOp->ExportVTK( obj, fileName.toUtf8().constData(), deflection ); - if ( stlOp->IsDone() ) + if ( vtkOp->IsDone() ) { transaction.commit(); } @@ -150,7 +153,7 @@ bool VTKPlugin_GUI::exportVTK( SUIT_Desktop* parent ) transaction.abort(); SUIT_MessageBox::critical( parent, tr( "GEOM_ERROR" ), - tr( "GEOM_PRP_ABORT" ) + "\n" + tr( stlOp->GetErrorCode() ) ); + tr( "GEOM_PRP_ABORT" ) + "\n" + tr( vtkOp->GetErrorCode() ) ); return false; } } diff --git a/src/XAOPlugin/XAOPlugin_ImportDlg.cxx b/src/XAOPlugin/XAOPlugin_ImportDlg.cxx index 990386361..2d061210f 100644 --- a/src/XAOPlugin/XAOPlugin_ImportDlg.cxx +++ b/src/XAOPlugin/XAOPlugin_ImportDlg.cxx @@ -280,13 +280,16 @@ bool XAOPlugin_ImportDlg::execute() { QStringList anEntryList; anEntryList << addInStudy(m_mainShape, m_mainShape->GetName()); + m_mainShape->UnRegister(); for (int i = 0; i < subShapes->length(); i++) { addInStudy(subShapes[i].in(), subShapes[i]->GetName()); + subShapes[i]->UnRegister(); } for (int i = 0; i < groups->length(); i++) { addInStudy(groups[i].in(), groups[i]->GetName()); + groups[i]->UnRegister(); } for (int i = 0; i < fields->length(); i++) { @@ -316,6 +319,7 @@ QString XAOPlugin_ImportDlg::addFieldInStudy( GEOM::GEOM_Field_ptr theField, GEO SALOMEDS::SObject_var aSO = getGeomEngine()->AddInStudy(aStudyDS, theField, theField->GetName(), theFather); + theField->UnRegister(); QString anEntry; if ( !aSO->_is_nil() ) { @@ -331,6 +335,7 @@ QString XAOPlugin_ImportDlg::addFieldInStudy( GEOM::GEOM_Field_ptr theField, GEO QString stepName = (tr("XAOPLUGIN_STEP") + " %1 %2").arg( step->GetID() ).arg( step->GetStamp() ); SALOMEDS::SObject_wrap aSOField = getGeomEngine()->AddInStudy( aStudyDS, step, stepName.toLatin1().constData(), theField ); + step->UnRegister(); } aSO->UnRegister(); From f1dfa183cbdd291eb94b0bd813b6d8da6a8d696b Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 17 Sep 2015 19:25:48 +0300 Subject: [PATCH 39/54] Fix memory leaks, causing appearance of deleted objects in study dump. --- src/GEOMGUI/GeometryGUI.cxx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 3bfe0e5b0..0d3f733a6 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -898,6 +898,11 @@ void GeometryGUI::createOriginAndBaseVectors() GetGeomGen()->PublishInStudy( aDSStudy, SALOMEDS::SObject::_nil(), anOX, "OX" ); GetGeomGen()->PublishInStudy( aDSStudy, SALOMEDS::SObject::_nil(), anOY, "OY" ); GetGeomGen()->PublishInStudy( aDSStudy, SALOMEDS::SObject::_nil(), anOZ, "OZ" ); + anOrigin->UnRegister(); + anOX->UnRegister(); + anOY->UnRegister(); + anOZ->UnRegister(); + aBasicOperations->UnRegister(); getApp()->updateObjectBrowser( true ); } From 70968a29cea3f2073ecbd616ca497dba3e3b4a8e Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 24 Sep 2015 15:01:40 +0300 Subject: [PATCH 40/54] Simplify activation of local selection on all objects --- .../AdvancedGUI_DividedDiskDlg.cxx | 4 ++-- src/AdvancedGUI/AdvancedGUI_PipeTShapeDlg.cxx | 2 +- .../AdvancedGUI_SmoothingSurfaceDlg.cxx | 8 +++---- src/BasicGUI/BasicGUI_ArcDlg.cxx | 4 ++-- src/BasicGUI/BasicGUI_CircleDlg.cxx | 4 ++-- src/BasicGUI/BasicGUI_CurveDlg.cxx | 6 ++--- src/BasicGUI/BasicGUI_EllipseDlg.cxx | 8 +++---- src/BasicGUI/BasicGUI_LineDlg.cxx | 4 ++-- src/BasicGUI/BasicGUI_MarkerDlg.cxx | 12 +++++----- src/BasicGUI/BasicGUI_PlaneDlg.cxx | 12 +++++----- src/BasicGUI/BasicGUI_PointDlg.cxx | 18 +++++++-------- src/BasicGUI/BasicGUI_VectorDlg.cxx | 4 ++-- src/BlocksGUI/BlocksGUI_BlockDlg.cxx | 4 ++-- src/BlocksGUI/BlocksGUI_QuadFaceDlg.cxx | 4 ++-- src/BooleanGUI/BooleanGUI_Dialog.cxx | 10 ++------- src/BuildGUI/BuildGUI_EdgeDlg.cxx | 14 ++++++------ src/BuildGUI/BuildGUI_FaceDlg.cxx | 12 +++++----- src/BuildGUI/BuildGUI_WireDlg.cxx | 6 ++--- src/EntityGUI/EntityGUI_3DSketcherDlg.cxx | 4 ++-- src/EntityGUI/EntityGUI_SketcherDlg.cxx | 4 ++-- src/GEOMBase/GEOMBase_Helper.cxx | 22 +++++++++++++++++++ src/GEOMBase/GEOMBase_Helper.h | 2 ++ .../GenerationGUI_FillingDlg.cxx | 2 +- src/GenerationGUI/GenerationGUI_PipeDlg.cxx | 8 +++---- .../GenerationGUI_PipePathDlg.cxx | 6 ++--- src/GenerationGUI/GenerationGUI_PrismDlg.cxx | 6 ++--- src/GenerationGUI/GenerationGUI_RevolDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_AngleDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_BndBoxDlg.cxx | 6 +---- src/MeasureGUI/MeasureGUI_CenterMassDlg.cxx | 6 +---- .../MeasureGUI_CheckSelfIntersectionsDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_DistanceDlg.cxx | 6 +---- .../MeasureGUI_FastCheckIntersectionsDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_InertiaDlg.cxx | 4 +--- src/MeasureGUI/MeasureGUI_MaxToleranceDlg.cxx | 5 +---- src/MeasureGUI/MeasureGUI_NormaleDlg.cxx | 4 ++-- src/MeasureGUI/MeasureGUI_PointDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_PropertiesDlg.cxx | 2 +- src/MeasureGUI/MeasureGUI_WhatisDlg.cxx | 2 +- src/PrimitiveGUI/PrimitiveGUI_BoxDlg.cxx | 4 ++-- src/PrimitiveGUI/PrimitiveGUI_ConeDlg.cxx | 4 ++-- src/PrimitiveGUI/PrimitiveGUI_CylinderDlg.cxx | 4 ++-- src/PrimitiveGUI/PrimitiveGUI_DiskDlg.cxx | 4 ++-- src/PrimitiveGUI/PrimitiveGUI_FaceDlg.cxx | 12 +++++----- src/PrimitiveGUI/PrimitiveGUI_SphereDlg.cxx | 4 ++-- src/PrimitiveGUI/PrimitiveGUI_TorusDlg.cxx | 4 ++-- src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx | 10 ++++----- .../TransformationGUI_MirrorDlg.cxx | 6 ++--- .../TransformationGUI_MultiRotationDlg.cxx | 2 +- .../TransformationGUI_MultiTranslationDlg.cxx | 6 ++--- .../TransformationGUI_PositionDlg.cxx | 4 ++-- .../TransformationGUI_ProjectionDlg.cxx | 10 ++++----- .../TransformationGUI_RotationDlg.cxx | 8 +++---- .../TransformationGUI_ScaleDlg.cxx | 2 +- .../TransformationGUI_TranslationDlg.cxx | 6 ++--- 55 files changed, 162 insertions(+), 163 deletions(-) diff --git a/src/AdvancedGUI/AdvancedGUI_DividedDiskDlg.cxx b/src/AdvancedGUI/AdvancedGUI_DividedDiskDlg.cxx index 4da6ad710..39197f059 100644 --- a/src/AdvancedGUI/AdvancedGUI_DividedDiskDlg.cxx +++ b/src/AdvancedGUI/AdvancedGUI_DividedDiskDlg.cxx @@ -335,11 +335,11 @@ void AdvancedGUI_DividedDiskDlg::SetEditCurrentArgument() disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); if (myEditCurrentArgument == GroupPntVecR->LineEdit2) { globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } else { globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); diff --git a/src/AdvancedGUI/AdvancedGUI_PipeTShapeDlg.cxx b/src/AdvancedGUI/AdvancedGUI_PipeTShapeDlg.cxx index 5999c6471..f00d74043 100644 --- a/src/AdvancedGUI/AdvancedGUI_PipeTShapeDlg.cxx +++ b/src/AdvancedGUI/AdvancedGUI_PipeTShapeDlg.cxx @@ -642,7 +642,7 @@ void AdvancedGUI_PipeTShapeDlg::SetEditCurrentArgument() disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); //globalSelection(GEOM_POINT); globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); } diff --git a/src/AdvancedGUI/AdvancedGUI_SmoothingSurfaceDlg.cxx b/src/AdvancedGUI/AdvancedGUI_SmoothingSurfaceDlg.cxx index e51ad791b..412fa23c6 100644 --- a/src/AdvancedGUI/AdvancedGUI_SmoothingSurfaceDlg.cxx +++ b/src/AdvancedGUI/AdvancedGUI_SmoothingSurfaceDlg.cxx @@ -120,7 +120,7 @@ void AdvancedGUI_SmoothingSurfaceDlg::Init() showOnlyPreviewControl(); globalSelection(); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); //@@ initialize dialog box widgets here @@// // Signal/slot connections @@ -163,7 +163,7 @@ bool AdvancedGUI_SmoothingSurfaceDlg::ClickOnApply() initName(); globalSelection(); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); return true; } @@ -175,7 +175,7 @@ void AdvancedGUI_SmoothingSurfaceDlg::ActivateThisDialog() { GEOMBase_Skeleton::ActivateThisDialog(); globalSelection(); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); //displayPreview(); } @@ -363,6 +363,6 @@ void AdvancedGUI_SmoothingSurfaceDlg::SetEditCurrentArgument() myEditCurrentArgument = GroupPoints->LineEdit1; myEditCurrentArgument->setFocus(); globalSelection(); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); SelectionIntoArgument(); } diff --git a/src/BasicGUI/BasicGUI_ArcDlg.cxx b/src/BasicGUI/BasicGUI_ArcDlg.cxx index 37e50ea4b..43cb1f493 100644 --- a/src/BasicGUI/BasicGUI_ArcDlg.cxx +++ b/src/BasicGUI/BasicGUI_ArcDlg.cxx @@ -330,7 +330,7 @@ void BasicGUI_ArcDlg::SelectionIntoArgument() void BasicGUI_ArcDlg::SetEditCurrentArgument() { globalSelection(); // close local selection to clear it - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); QPushButton* send = (QPushButton*)sender(); switch ( getConstructorId() ) { @@ -580,7 +580,7 @@ void BasicGUI_ArcDlg::ConstructorsClicked( int constructorId ) } globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); //Select Vertex on All Shapes + localSelection( TopAbs_VERTEX ); //Select Vertex on All Shapes qApp->processEvents(); updateGeometry(); diff --git a/src/BasicGUI/BasicGUI_CircleDlg.cxx b/src/BasicGUI/BasicGUI_CircleDlg.cxx index 21515ed32..55dabb285 100644 --- a/src/BasicGUI/BasicGUI_CircleDlg.cxx +++ b/src/BasicGUI/BasicGUI_CircleDlg.cxx @@ -283,7 +283,7 @@ void BasicGUI_CircleDlg::ConstructorsClicked( int constructorId ) myEditCurrentArgument->setFocus(); globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); @@ -471,7 +471,7 @@ void BasicGUI_CircleDlg::SetEditCurrentArgument() TopAbs_ShapeEnum aNeedType = ( myEditCurrentArgument == GroupPntVecR->LineEdit2 ) ? TopAbs_EDGE : TopAbs_VERTEX; globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), aNeedType ); + localSelection( aNeedType ); myEditCurrentArgument->setFocus(); // SelectionIntoArgument(); diff --git a/src/BasicGUI/BasicGUI_CurveDlg.cxx b/src/BasicGUI/BasicGUI_CurveDlg.cxx index 110c80c7f..0b4d9030e 100644 --- a/src/BasicGUI/BasicGUI_CurveDlg.cxx +++ b/src/BasicGUI/BasicGUI_CurveDlg.cxx @@ -280,15 +280,15 @@ void BasicGUI_CurveDlg::SetEditCurrentArgument() if (sender() == myGroupPoints->PushButton1) { myEditCurrentArgument = myGroupPoints->LineEdit1; - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } else if (sender() == myPushBtnV1) { myEditCurrentArgument = myLineEditV1; - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } else if (sender() == myPushBtnV2) { myEditCurrentArgument = myLineEditV2; - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } myEditCurrentArgument->setFocus(); diff --git a/src/BasicGUI/BasicGUI_EllipseDlg.cxx b/src/BasicGUI/BasicGUI_EllipseDlg.cxx index f1e74179f..53ac9b491 100644 --- a/src/BasicGUI/BasicGUI_EllipseDlg.cxx +++ b/src/BasicGUI/BasicGUI_EllipseDlg.cxx @@ -155,7 +155,7 @@ void BasicGUI_EllipseDlg::Init() initName( tr( "GEOM_ELLIPSE" ) ); globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); resize( minimumSizeHint() ); SelectionIntoArgument(); @@ -212,7 +212,7 @@ bool BasicGUI_EllipseDlg::ClickOnApply() myEditCurrentArgument = GroupPoints->LineEdit1; globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); displayPreview(true); return true; @@ -303,7 +303,7 @@ void BasicGUI_EllipseDlg::SetEditCurrentArgument() myEditCurrentArgument == GroupPoints->LineEdit3 ) ? TopAbs_EDGE : TopAbs_VERTEX; globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), aNeedType ); + localSelection( aNeedType ); myEditCurrentArgument->setFocus(); //SelectionIntoArgument(); @@ -333,7 +333,7 @@ void BasicGUI_EllipseDlg::ActivateThisDialog() myDir.nullify(); //globalSelection( GEOM_POINT ); globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); } //================================================================================= diff --git a/src/BasicGUI/BasicGUI_LineDlg.cxx b/src/BasicGUI/BasicGUI_LineDlg.cxx index 56a4fe041..6ac2df336 100644 --- a/src/BasicGUI/BasicGUI_LineDlg.cxx +++ b/src/BasicGUI/BasicGUI_LineDlg.cxx @@ -220,7 +220,7 @@ void BasicGUI_LineDlg::ConstructorsClicked( int constructorId ) myEditCurrentArgument == GroupFaces->LineEdit2 ) ? TopAbs_FACE : TopAbs_VERTEX; globalSelection(); // close local selection to clear it - localSelection( GEOM::GEOM_Object::_nil(), aNeedType ); + localSelection( aNeedType ); qApp->processEvents(); updateGeometry(); @@ -318,7 +318,7 @@ void BasicGUI_LineDlg::SetEditCurrentArgument() myEditCurrentArgument == GroupFaces->LineEdit2 ) ? TopAbs_FACE : TopAbs_VERTEX; globalSelection(); // close local selection to clear it - localSelection( GEOM::GEOM_Object::_nil(), aNeedType ); + localSelection( aNeedType ); myEditCurrentArgument->setFocus(); // SelectionIntoArgument(); diff --git a/src/BasicGUI/BasicGUI_MarkerDlg.cxx b/src/BasicGUI/BasicGUI_MarkerDlg.cxx index 8cb1dd447..7b2a7106c 100644 --- a/src/BasicGUI/BasicGUI_MarkerDlg.cxx +++ b/src/BasicGUI/BasicGUI_MarkerDlg.cxx @@ -228,7 +228,7 @@ void BasicGUI_MarkerDlg::ConstructorsClicked( int constructorId ) { if ( myConstructorId == constructorId && myConstructorId == 0 ) { globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); activate( GEOM_MARKER ); return; } @@ -244,7 +244,7 @@ void BasicGUI_MarkerDlg::ConstructorsClicked( int constructorId ) Group2->hide(); aMainGrp->show(); globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); activate( GEOM_MARKER ); break; } @@ -269,7 +269,7 @@ void BasicGUI_MarkerDlg::ConstructorsClicked( int constructorId ) Group2->PushButton2->setDown( false ); Group2->PushButton3->setDown( false ); globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); myEditCurrentArgument = Group2->LineEdit1; Group2->LineEdit1->setText( "" ); Group2->LineEdit2->setText( "" ); @@ -442,7 +442,7 @@ void BasicGUI_MarkerDlg::SetEditCurrentArgument() } else if ( send == Group2->PushButton1 ) { myEditCurrentArgument = Group2->LineEdit1; - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); Group2->PushButton2->setDown( false ); Group2->PushButton3->setDown( false ); Group2->LineEdit1->setEnabled( true ); @@ -451,7 +451,7 @@ void BasicGUI_MarkerDlg::SetEditCurrentArgument() } else if ( send == Group2->PushButton2 ) { myEditCurrentArgument = Group2->LineEdit2; - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); Group2->PushButton1->setDown( false ); Group2->PushButton3->setDown( false ); Group2->LineEdit1->setEnabled( false ); @@ -460,7 +460,7 @@ void BasicGUI_MarkerDlg::SetEditCurrentArgument() } else if ( send == Group2->PushButton3 ) { myEditCurrentArgument = Group2->LineEdit3; - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); Group2->PushButton1->setDown( false ); Group2->PushButton2->setDown( false ); Group2->LineEdit1->setEnabled( false ); diff --git a/src/BasicGUI/BasicGUI_PlaneDlg.cxx b/src/BasicGUI/BasicGUI_PlaneDlg.cxx index 707a45604..053fa5089 100644 --- a/src/BasicGUI/BasicGUI_PlaneDlg.cxx +++ b/src/BasicGUI/BasicGUI_PlaneDlg.cxx @@ -291,7 +291,7 @@ void BasicGUI_PlaneDlg::ConstructorsClicked( int constructorId ) /* for the first argument */ globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); break; } case 1: /* plane from 3 points */ @@ -315,7 +315,7 @@ void BasicGUI_PlaneDlg::ConstructorsClicked( int constructorId ) /* for the first argument */ globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); break; } case 2: /* plane from a planar face */ @@ -331,7 +331,7 @@ void BasicGUI_PlaneDlg::ConstructorsClicked( int constructorId ) GroupFace->PushButton1->setDown( true ); globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_FACE ); + localSelection( TopAbs_FACE ); break; } case 3: /* plane from a 2 Vectors */ @@ -347,7 +347,7 @@ void BasicGUI_PlaneDlg::ConstructorsClicked( int constructorId ) Group2Vec->PushButton1->setDown( true ); globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); break; } case 4: /* plane from a LCS */ @@ -575,7 +575,7 @@ void BasicGUI_PlaneDlg::SetEditCurrentArgument() if ( myEditCurrentArgument == GroupPntDir->LineEdit2 || myEditCurrentArgument == Group2Vec->LineEdit1 || myEditCurrentArgument == Group2Vec->LineEdit2 ) { - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); } else if ( myEditCurrentArgument == GroupFace->LineEdit1 ) { TColStd_MapOfInteger aMap; aMap.Add( GEOM_PLANE ); @@ -585,7 +585,7 @@ void BasicGUI_PlaneDlg::SetEditCurrentArgument() globalSelection( GEOM_MARKER ); } else { // 3 Pnts - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); } // SelectionIntoArgument(); diff --git a/src/BasicGUI/BasicGUI_PointDlg.cxx b/src/BasicGUI/BasicGUI_PointDlg.cxx index 0a374c4d7..96a989a88 100644 --- a/src/BasicGUI/BasicGUI_PointDlg.cxx +++ b/src/BasicGUI/BasicGUI_PointDlg.cxx @@ -335,7 +335,7 @@ void BasicGUI_PointDlg::ConstructorsClicked(int constructorId) { globalSelection(); // close local contexts, if any myNeedType = TopAbs_VERTEX; - localSelection(GEOM::GEOM_Object::_nil(), myNeedType); + localSelection(myNeedType); GroupRefPoint->hide(); GroupOnCurve->hide(); @@ -350,7 +350,7 @@ void BasicGUI_PointDlg::ConstructorsClicked(int constructorId) { globalSelection(); // close local contexts, if any myNeedType = TopAbs_VERTEX; - localSelection(GEOM::GEOM_Object::_nil(), myNeedType); + localSelection(myNeedType); myEditCurrentArgument = GroupRefPoint->LineEdit1; myEditCurrentArgument->setText(""); @@ -369,7 +369,7 @@ void BasicGUI_PointDlg::ConstructorsClicked(int constructorId) { globalSelection(); // close local contexts, if any myNeedType = TopAbs_EDGE; - localSelection(GEOM::GEOM_Object::_nil(), myNeedType); + localSelection(myNeedType); myEditCurrentArgument = GroupOnCurve->LineEdit1; myEditCurrentArgument->setText(""); @@ -392,7 +392,7 @@ void BasicGUI_PointDlg::ConstructorsClicked(int constructorId) globalSelection(); // close local contexts, if any std::list needTypes; needTypes.push_back( TopAbs_EDGE ), needTypes.push_back( TopAbs_WIRE ); - localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + localSelection(needTypes ); myEditCurrentArgument = GroupLineIntersection->LineEdit1; GroupLineIntersection->LineEdit1->setText(""); @@ -416,7 +416,7 @@ void BasicGUI_PointDlg::ConstructorsClicked(int constructorId) { globalSelection(); // close local contexts, if any myNeedType = TopAbs_FACE; - localSelection(GEOM::GEOM_Object::_nil(), myNeedType); + localSelection(myNeedType); myEditCurrentArgument = GroupOnSurface->LineEdit1; myEditCurrentArgument->setText(""); @@ -575,14 +575,14 @@ void BasicGUI_PointDlg::SetEditCurrentArgument() GroupRefPoint->LineEdit1->setFocus(); myEditCurrentArgument = GroupRefPoint->LineEdit1; globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } else if (send == GroupOnCurve->PushButton1) { GroupOnCurve->LineEdit1->setFocus(); myEditCurrentArgument = GroupOnCurve->LineEdit1; globalSelection(); // close local contexts, if any myNeedType = TopAbs_EDGE; - localSelection(GEOM::GEOM_Object::_nil(), myNeedType); + localSelection(myNeedType); GroupOnCurve->PushButton2->setDown(false); GroupOnCurve->LineEdit1->setEnabled(true); GroupOnCurve->LineEdit2->setEnabled(false); @@ -592,7 +592,7 @@ void BasicGUI_PointDlg::SetEditCurrentArgument() myEditCurrentArgument = GroupOnCurve->LineEdit2; globalSelection(); // close local contexts, if any myNeedType = TopAbs_VERTEX; - localSelection(GEOM::GEOM_Object::_nil(), myNeedType); + localSelection(myNeedType); GroupOnCurve->PushButton1->setDown(false); GroupOnCurve->LineEdit2->setEnabled(true); GroupOnCurve->LineEdit1->setEnabled(false); @@ -602,7 +602,7 @@ void BasicGUI_PointDlg::SetEditCurrentArgument() GroupOnSurface->LineEdit1->setFocus(); myEditCurrentArgument = GroupOnSurface->LineEdit1; globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_FACE); + localSelection(TopAbs_FACE); } else if (send == GroupLineIntersection->PushButton1) { GroupLineIntersection->LineEdit1->setFocus(); diff --git a/src/BasicGUI/BasicGUI_VectorDlg.cxx b/src/BasicGUI/BasicGUI_VectorDlg.cxx index 8b915423b..d2648f9cf 100644 --- a/src/BasicGUI/BasicGUI_VectorDlg.cxx +++ b/src/BasicGUI/BasicGUI_VectorDlg.cxx @@ -204,7 +204,7 @@ void BasicGUI_VectorDlg::ConstructorsClicked( int constructorId ) GroupPoints->LineEdit2->setEnabled( false ); globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); break; @@ -325,7 +325,7 @@ void BasicGUI_VectorDlg::SetEditCurrentArgument() myEditCurrentArgument->setFocus(); // SelectionIntoArgument(); globalSelection(); // close local selection to clear it - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); send->setDown(true); displayPreview(true); } diff --git a/src/BlocksGUI/BlocksGUI_BlockDlg.cxx b/src/BlocksGUI/BlocksGUI_BlockDlg.cxx index c4b986271..657d1ac39 100644 --- a/src/BlocksGUI/BlocksGUI_BlockDlg.cxx +++ b/src/BlocksGUI/BlocksGUI_BlockDlg.cxx @@ -387,7 +387,7 @@ void BlocksGUI_BlockDlg::SetEditCurrentArgument() aSender->setDown(true); globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_FACE); //Select Faces on All Shapes + localSelection(TopAbs_FACE); //Select Faces on All Shapes connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); } @@ -400,7 +400,7 @@ void BlocksGUI_BlockDlg::ActivateThisDialog() { GEOMBase_Skeleton::ActivateThisDialog(); globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_FACE); //Select Faces on All Shapes + localSelection(TopAbs_FACE); //Select Faces on All Shapes connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); displayPreview(true); diff --git a/src/BlocksGUI/BlocksGUI_QuadFaceDlg.cxx b/src/BlocksGUI/BlocksGUI_QuadFaceDlg.cxx index b004d5c87..39c42e5ba 100644 --- a/src/BlocksGUI/BlocksGUI_QuadFaceDlg.cxx +++ b/src/BlocksGUI/BlocksGUI_QuadFaceDlg.cxx @@ -466,11 +466,11 @@ void BlocksGUI_QuadFaceDlg::activateSelection() myEditCurrentArgument == mySelName[Vertex3] || myEditCurrentArgument == mySelName[Vertex4]) { - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); //Select Vertices on All Shapes + localSelection(TopAbs_VERTEX); //Select Vertices on All Shapes } else { - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); //Select Edges on All Shapes + localSelection(TopAbs_EDGE); //Select Edges on All Shapes } connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); diff --git a/src/BooleanGUI/BooleanGUI_Dialog.cxx b/src/BooleanGUI/BooleanGUI_Dialog.cxx index 115394514..1a0de1b87 100644 --- a/src/BooleanGUI/BooleanGUI_Dialog.cxx +++ b/src/BooleanGUI/BooleanGUI_Dialog.cxx @@ -198,10 +198,7 @@ void BooleanGUI_Dialog::Init() mainFrame()->RadioButton1->setFocus(); globalSelection(GEOM_ALLSHAPES); - - std::list needTypes; - needTypes.push_back( TopAbs_VERTEX ), needTypes.push_back( TopAbs_EDGE ), needTypes.push_back( TopAbs_WIRE ), needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ), needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPOUND ); - localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + localSelection(TopAbs_SHAPE); myGroup->PushButton1->click(); resize(100,100); @@ -341,10 +338,7 @@ void BooleanGUI_Dialog::SetEditCurrentArgument() } globalSelection(GEOM_ALLSHAPES); - - std::list needTypes; - needTypes.push_back( TopAbs_VERTEX ), needTypes.push_back( TopAbs_EDGE ), needTypes.push_back( TopAbs_WIRE ), needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ), needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPOUND ); - localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + localSelection(TopAbs_SHAPE); // enable line edit myEditCurrentArgument->setEnabled(true); diff --git a/src/BuildGUI/BuildGUI_EdgeDlg.cxx b/src/BuildGUI/BuildGUI_EdgeDlg.cxx index b96feeeae..c34e448e5 100644 --- a/src/BuildGUI/BuildGUI_EdgeDlg.cxx +++ b/src/BuildGUI/BuildGUI_EdgeDlg.cxx @@ -145,7 +145,7 @@ void BuildGUI_EdgeDlg::Init() myEditCurrentArgument = GroupPoints->LineEdit1; GroupPoints->PushButton1->setDown(true); globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); // signals and slots connections connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); @@ -210,7 +210,7 @@ void BuildGUI_EdgeDlg::ConstructorsClicked(int constructorId) case 0: { globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); myEditCurrentArgument = GroupPoints->LineEdit1; GroupPoints->LineEdit1->setText(""); @@ -229,7 +229,7 @@ void BuildGUI_EdgeDlg::ConstructorsClicked(int constructorId) case 1: { globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_WIRE); + localSelection(TopAbs_WIRE); myEditCurrentArgument = GroupWire->LineEdit1; GroupWire->LineEdit1->setText(""); @@ -244,7 +244,7 @@ void BuildGUI_EdgeDlg::ConstructorsClicked(int constructorId) case 2: { globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); myEditCurrentArgument = GroupOnCurve->LineEdit1; GroupOnCurve->LineEdit1->setText(""); @@ -302,7 +302,7 @@ void BuildGUI_EdgeDlg::SelectionIntoArgument() myEditCurrentArgument->setText(aName); globalSelection(); - localSelection(GEOM::GEOM_Object::_nil(), aNeedType); + localSelection(aNeedType); if (myEditCurrentArgument == GroupPoints->LineEdit1) { myPoint1 = aSelectedObject; @@ -359,7 +359,7 @@ void BuildGUI_EdgeDlg::SetEditCurrentArgument() GroupOnCurve->LineEdit2->setEnabled(false); globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } else if (send == GroupOnCurve->PushButton2) { myEditCurrentArgument = GroupOnCurve->LineEdit2; @@ -367,7 +367,7 @@ void BuildGUI_EdgeDlg::SetEditCurrentArgument() GroupOnCurve->LineEdit1->setEnabled(false); globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } // enable line edit diff --git a/src/BuildGUI/BuildGUI_FaceDlg.cxx b/src/BuildGUI/BuildGUI_FaceDlg.cxx index 14ac07bb5..d474817f1 100644 --- a/src/BuildGUI/BuildGUI_FaceDlg.cxx +++ b/src/BuildGUI/BuildGUI_FaceDlg.cxx @@ -263,7 +263,7 @@ void BuildGUI_FaceDlg::ConstructorsClicked(int constructorId) case 1: { globalSelection(GEOM_FACE); // For the first element. - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_FACE ); + localSelection( TopAbs_FACE ); myEditCurrentArgument = myGroupSurf->LineEdit1; myGroupSurf->LineEdit1->setText(""); @@ -277,7 +277,7 @@ void BuildGUI_FaceDlg::ConstructorsClicked(int constructorId) case 2: { globalSelection(); - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_WIRE ); + localSelection( TopAbs_WIRE ); myTreeConstraints->clear(); myCurrentItem = 0; @@ -323,7 +323,7 @@ void BuildGUI_FaceDlg::updateConstraintsTree() myEditCurrentArgument->setEnabled(false); globalSelection(); - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_FACE ); + localSelection( TopAbs_FACE ); myTreeConstraints->resizeColumnToContents(0); QTreeWidgetItem* firstItem = myTreeConstraints->topLevelItem(0); @@ -509,21 +509,21 @@ void BuildGUI_FaceDlg::SetEditCurrentArgument() } else if (send == myGroupSurf->PushButton1) { globalSelection(GEOM_FACE); - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_FACE ); + localSelection( TopAbs_FACE ); myEditCurrentArgument = myGroupSurf->LineEdit1; myGroupSurf->PushButton2->setDown(false); myGroupSurf->LineEdit2->setEnabled(false); } else if (send == myGroupSurf->PushButton2) { globalSelection(GEOM_WIRE); - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_WIRE ); + localSelection( TopAbs_WIRE ); myEditCurrentArgument = myGroupSurf->LineEdit2; myGroupSurf->PushButton1->setDown(false); myGroupSurf->LineEdit1->setEnabled(false); } else if (send == myGroupWireConstraints->PushButton1) { globalSelection(); - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_WIRE ); + localSelection( TopAbs_WIRE ); myEditCurrentArgument = myGroupWireConstraints->LineEdit1; myCurrentItem = 0; } diff --git a/src/BuildGUI/BuildGUI_WireDlg.cxx b/src/BuildGUI/BuildGUI_WireDlg.cxx index 83c7213cf..097028208 100644 --- a/src/BuildGUI/BuildGUI_WireDlg.cxx +++ b/src/BuildGUI/BuildGUI_WireDlg.cxx @@ -121,7 +121,7 @@ void BuildGUI_WireDlg::Init() myEdgesAndWires.clear(); - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); /* signals and slots connections */ connect( buttonOk(), SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); @@ -177,12 +177,12 @@ void BuildGUI_WireDlg::TypeButtonClicked() { if ( GroupType->RadioButton1->isChecked() ) { globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); GroupArgs->TextLabel1->setText( tr( "GEOM_EDGE" ) ); } else if ( GroupType->RadioButton2->isChecked() ) { globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_WIRE ); + localSelection( TopAbs_WIRE ); GroupArgs->TextLabel1->setText( tr( "GEOM_WIRE" ) ); } SelectionIntoArgument(); diff --git a/src/EntityGUI/EntityGUI_3DSketcherDlg.cxx b/src/EntityGUI/EntityGUI_3DSketcherDlg.cxx index 41a10d232..861d7c5b3 100755 --- a/src/EntityGUI/EntityGUI_3DSketcherDlg.cxx +++ b/src/EntityGUI/EntityGUI_3DSketcherDlg.cxx @@ -327,7 +327,7 @@ void EntityGUI_3DSketcherDlg::Init() myLengthPrs = dynamic_cast(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0)); myTextPrs = dynamic_cast(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0)); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); /* Get setting of step value from file configuration */ double step = SUIT_Session::session()->resourceMgr()->doubleValue("Geometry", "SettingsGeomStep", 100.0); @@ -823,7 +823,7 @@ void EntityGUI_3DSketcherDlg::ActivateThisDialog() connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth); } diff --git a/src/EntityGUI/EntityGUI_SketcherDlg.cxx b/src/EntityGUI/EntityGUI_SketcherDlg.cxx index f489c89c2..6b0248b08 100644 --- a/src/EntityGUI/EntityGUI_SketcherDlg.cxx +++ b/src/EntityGUI/EntityGUI_SketcherDlg.cxx @@ -541,7 +541,7 @@ void EntityGUI_SketcherDlg::InitClick() Group4Spin->hide(); GroupRect->hide(); globalSelection(); // close local selection to clear it - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); } @@ -1571,7 +1571,7 @@ void EntityGUI_SketcherDlg::SetEditCurrentArgument() selButton->setDown(true); } globalSelection(); // close local selection to clear it - localSelection(GEOM::GEOM_Object::_nil(), myNeedType); + localSelection( myNeedType ); } diff --git a/src/GEOMBase/GEOMBase_Helper.cxx b/src/GEOMBase/GEOMBase_Helper.cxx index 1e795376c..469365617 100755 --- a/src/GEOMBase/GEOMBase_Helper.cxx +++ b/src/GEOMBase/GEOMBase_Helper.cxx @@ -528,6 +528,28 @@ void GEOMBase_Helper::localSelection( GEOM::GEOM_Object_ptr obj, const int mode localSelection( obj, modes ); } +//================================================================ +// Function : localSelection +// Purpose : Activate selection of sub-shapes in accordance with mode +// modes are from TopAbs_ShapeEnum +//================================================================ +void GEOMBase_Helper::localSelection( const std::list modes ) +{ + localSelection( GEOM::GEOM_Object::_nil(), modes ); +} + +//================================================================ +// Function : localSelection +// Purpose : Activate selection of sub-shapes in accordance with mode +// mode is from TopAbs_ShapeEnum +//================================================================ +void GEOMBase_Helper::localSelection( const int mode ) +{ + std::list modes; + modes.push_back( mode ); + localSelection( modes ); +} + //================================================================ // Function : globalSelection // Purpose : Activate selection of sub-shapes. Set selection filters diff --git a/src/GEOMBase/GEOMBase_Helper.h b/src/GEOMBase/GEOMBase_Helper.h index fac2d89ba..44f424def 100755 --- a/src/GEOMBase/GEOMBase_Helper.h +++ b/src/GEOMBase/GEOMBase_Helper.h @@ -100,6 +100,8 @@ protected: void localSelection( const ObjectList&, const int ); void localSelection( GEOM::GEOM_Object_ptr, const std::list ); void localSelection( GEOM::GEOM_Object_ptr, const int ); + void localSelection( const std::list ); + void localSelection( const int ); void activate( const int ); void globalSelection( const int = GEOM_ALLOBJECTS, const bool = false ); void globalSelection( const TColStd_MapOfInteger&, const bool = false ); diff --git a/src/GenerationGUI/GenerationGUI_FillingDlg.cxx b/src/GenerationGUI/GenerationGUI_FillingDlg.cxx index e6348707f..884b75d9d 100644 --- a/src/GenerationGUI/GenerationGUI_FillingDlg.cxx +++ b/src/GenerationGUI/GenerationGUI_FillingDlg.cxx @@ -209,7 +209,7 @@ void GenerationGUI_FillingDlg::initSelection() needTypes.push_back( TopAbs_COMPOUND ); globalSelection( aTypes ); - localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + localSelection( needTypes ); } //================================================================================= diff --git a/src/GenerationGUI/GenerationGUI_PipeDlg.cxx b/src/GenerationGUI/GenerationGUI_PipeDlg.cxx index 703fe5ede..c00a0c275 100644 --- a/src/GenerationGUI/GenerationGUI_PipeDlg.cxx +++ b/src/GenerationGUI/GenerationGUI_PipeDlg.cxx @@ -280,7 +280,7 @@ void GenerationGUI_PipeDlg::SelectionTypeButtonClicked() { globalSelection(); if ( GroupPoints->CheckButton1->isChecked() ) { - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); } else { TColStd_MapOfInteger aMap; aMap.Add(GEOM_COMPOUND); @@ -382,7 +382,7 @@ void GenerationGUI_PipeDlg::SelectionIntoArgument() } } else if ( myEditCurrentArgument == GroupMakePoints->LineEdit2 ) { - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); QList objects = getSelected( TopAbs_VERTEX, -1 ); GEOMBase::Synchronize( myLocations, objects ); if ( !myLocations.isEmpty() ) { @@ -428,7 +428,7 @@ void GenerationGUI_PipeDlg::SetEditCurrentArgument() myEditCurrentArgument = GroupPoints->LineEdit2; if ( GroupPoints->CheckButton1->isChecked() ) { - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); } else { TColStd_MapOfInteger aMap; aMap.Add(GEOM_COMPOUND); @@ -441,7 +441,7 @@ void GenerationGUI_PipeDlg::SetEditCurrentArgument() else if(send == GroupPoints->PushButton3) { myEditCurrentArgument = GroupPoints->LineEdit3; GroupPoints->CheckButton1->setEnabled(false); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } GroupMakePoints->PushButton1->setDown(false); diff --git a/src/GenerationGUI/GenerationGUI_PipePathDlg.cxx b/src/GenerationGUI/GenerationGUI_PipePathDlg.cxx index a7889f101..5c465f3bb 100644 --- a/src/GenerationGUI/GenerationGUI_PipePathDlg.cxx +++ b/src/GenerationGUI/GenerationGUI_PipePathDlg.cxx @@ -148,7 +148,7 @@ void GenerationGUI_PipePathDlg::SelectionTypeButtonClicked() { globalSelection(); if (GroupPoints->CheckButton1->isChecked()) { - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } else { TColStd_MapOfInteger aMap; @@ -269,7 +269,7 @@ void GenerationGUI_PipePathDlg::SetEditCurrentArgument() myEditCurrentArgument = GroupPoints->LineEdit2; if (GroupPoints->CheckButton1->isChecked()) { - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } else { TColStd_MapOfInteger aMap; @@ -284,7 +284,7 @@ void GenerationGUI_PipePathDlg::SetEditCurrentArgument() myEditCurrentArgument = GroupPoints->LineEdit3; if (GroupPoints->CheckButton1->isChecked()) { - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } else { TColStd_MapOfInteger aMap; diff --git a/src/GenerationGUI/GenerationGUI_PrismDlg.cxx b/src/GenerationGUI/GenerationGUI_PrismDlg.cxx index e2de72611..11cfd2c6e 100644 --- a/src/GenerationGUI/GenerationGUI_PrismDlg.cxx +++ b/src/GenerationGUI/GenerationGUI_PrismDlg.cxx @@ -446,7 +446,7 @@ void GenerationGUI_PrismDlg::SetEditCurrentArgument() myEditCurrentArgument = GroupVecH->LineEdit2; GroupVecH->PushButton1->setDown(false); GroupVecH->LineEdit1->setEnabled(false); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } else if (send == Group2Points->PushButton1) { myEditCurrentArgument = Group2Points->LineEdit1; @@ -461,7 +461,7 @@ void GenerationGUI_PrismDlg::SetEditCurrentArgument() Group2Points->PushButton3->setDown(false); Group2Points->LineEdit1->setEnabled(false); Group2Points->LineEdit3->setEnabled(false); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } else if (send == Group2Points->PushButton3) { myEditCurrentArgument = Group2Points->LineEdit3; @@ -469,7 +469,7 @@ void GenerationGUI_PrismDlg::SetEditCurrentArgument() Group2Points->PushButton2->setDown(false); Group2Points->LineEdit1->setEnabled(false); Group2Points->LineEdit2->setEnabled(false); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } else if (send == GroupDXDYDZ->PushButton1) { myEditCurrentArgument = GroupDXDYDZ->LineEdit1; diff --git a/src/GenerationGUI/GenerationGUI_RevolDlg.cxx b/src/GenerationGUI/GenerationGUI_RevolDlg.cxx index 61246cf11..2d798fcbf 100644 --- a/src/GenerationGUI/GenerationGUI_RevolDlg.cxx +++ b/src/GenerationGUI/GenerationGUI_RevolDlg.cxx @@ -234,7 +234,7 @@ void GenerationGUI_RevolDlg::SetEditCurrentArgument() myEditCurrentArgument = GroupPoints->LineEdit2; GroupPoints->PushButton1->setDown(false); GroupPoints->LineEdit1->setEnabled(false); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); diff --git a/src/MeasureGUI/MeasureGUI_AngleDlg.cxx b/src/MeasureGUI/MeasureGUI_AngleDlg.cxx index 64c51cc78..2d8de0fcc 100644 --- a/src/MeasureGUI/MeasureGUI_AngleDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_AngleDlg.cxx @@ -404,5 +404,5 @@ bool MeasureGUI_AngleDlg::isValid (QString& msg) void MeasureGUI_AngleDlg::activateSelection() { globalSelection(GEOM_LINE); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); } diff --git a/src/MeasureGUI/MeasureGUI_BndBoxDlg.cxx b/src/MeasureGUI/MeasureGUI_BndBoxDlg.cxx index 56b10a092..ddb2e566a 100644 --- a/src/MeasureGUI/MeasureGUI_BndBoxDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_BndBoxDlg.cxx @@ -307,11 +307,7 @@ bool MeasureGUI_BndBoxDlg::execute (ObjectList& objects) void MeasureGUI_BndBoxDlg::activateSelection() { globalSelection( GEOM_ALLSHAPES ); - std::list needTypes; - needTypes.push_back( TopAbs_SHAPE ), needTypes.push_back( TopAbs_VERTEX ), needTypes.push_back( TopAbs_EDGE ); - needTypes.push_back( TopAbs_WIRE ), needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ); - needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPSOLID ), needTypes.push_back( TopAbs_COMPOUND ); - localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + localSelection( TopAbs_SHAPE ); } //================================================================================= diff --git a/src/MeasureGUI/MeasureGUI_CenterMassDlg.cxx b/src/MeasureGUI/MeasureGUI_CenterMassDlg.cxx index c2f5f92c1..0fdecafde 100644 --- a/src/MeasureGUI/MeasureGUI_CenterMassDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_CenterMassDlg.cxx @@ -131,11 +131,7 @@ void MeasureGUI_CenterMassDlg::Init() void MeasureGUI_CenterMassDlg::activateSelection() { globalSelection( GEOM_ALLSHAPES ); - std::list needTypes; - needTypes.push_back( TopAbs_SHAPE ), needTypes.push_back( TopAbs_VERTEX ), needTypes.push_back( TopAbs_EDGE ); - needTypes.push_back( TopAbs_WIRE ), needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ); - needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPSOLID ), needTypes.push_back( TopAbs_COMPOUND ); - localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + localSelection( TopAbs_SHAPE ); } //================================================================================= diff --git a/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx index 97b3d170e..27bebf181 100644 --- a/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_CheckSelfIntersectionsDlg.cxx @@ -439,7 +439,7 @@ void MeasureGUI_CheckSelfIntersectionsDlg::activateSelection() std::list needTypes; needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ), needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPOUND ); - localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + localSelection( needTypes ); break; } } diff --git a/src/MeasureGUI/MeasureGUI_DistanceDlg.cxx b/src/MeasureGUI/MeasureGUI_DistanceDlg.cxx index a2b0dc16c..8c7207f9a 100644 --- a/src/MeasureGUI/MeasureGUI_DistanceDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_DistanceDlg.cxx @@ -489,11 +489,7 @@ bool MeasureGUI_DistanceDlg::execute (ObjectList& objects) void MeasureGUI_DistanceDlg::activateSelection() { globalSelection( GEOM_ALLSHAPES ); - std::list needTypes; - needTypes.push_back( TopAbs_SHAPE ), needTypes.push_back( TopAbs_VERTEX ), needTypes.push_back( TopAbs_EDGE ); - needTypes.push_back( TopAbs_WIRE ), needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ); - needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPSOLID ), needTypes.push_back( TopAbs_COMPOUND ); - localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + localSelection( TopAbs_SHAPE ); } //================================================================================= diff --git a/src/MeasureGUI/MeasureGUI_FastCheckIntersectionsDlg.cxx b/src/MeasureGUI/MeasureGUI_FastCheckIntersectionsDlg.cxx index 459501c3c..ff075bc17 100644 --- a/src/MeasureGUI/MeasureGUI_FastCheckIntersectionsDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_FastCheckIntersectionsDlg.cxx @@ -317,7 +317,7 @@ void MeasureGUI_FastCheckIntersectionsDlg::activateSelection() std::list needTypes; needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ), needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPOUND ); - localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + localSelection( needTypes ); } diff --git a/src/MeasureGUI/MeasureGUI_InertiaDlg.cxx b/src/MeasureGUI/MeasureGUI_InertiaDlg.cxx index ee14238b3..61dcafdc3 100644 --- a/src/MeasureGUI/MeasureGUI_InertiaDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_InertiaDlg.cxx @@ -129,9 +129,7 @@ void MeasureGUI_InertiaDlg::Init() void MeasureGUI_InertiaDlg::activateSelection() { MeasureGUI_Skeleton::activateSelection(); - std::list needTypes; - needTypes.push_back( TopAbs_VERTEX ), needTypes.push_back( TopAbs_EDGE ), needTypes.push_back( TopAbs_WIRE ), needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ), needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPOUND ); - localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + localSelection( TopAbs_SHAPE ); } diff --git a/src/MeasureGUI/MeasureGUI_MaxToleranceDlg.cxx b/src/MeasureGUI/MeasureGUI_MaxToleranceDlg.cxx index 2c1d1dec3..6fd821b71 100644 --- a/src/MeasureGUI/MeasureGUI_MaxToleranceDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_MaxToleranceDlg.cxx @@ -184,10 +184,7 @@ bool MeasureGUI_MaxToleranceDlg::getParameters( double& theMinFaceToler, void MeasureGUI_MaxToleranceDlg::activateSelection() { globalSelection( GEOM_ALLSHAPES ); - std::list needTypes; - needTypes.push_back( TopAbs_SHAPE ), needTypes.push_back( TopAbs_EDGE ); - needTypes.push_back( TopAbs_WIRE ), needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ); - needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPSOLID ), needTypes.push_back( TopAbs_COMPOUND ); localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + localSelection( TopAbs_SHAPE ); } void MeasureGUI_MaxToleranceDlg::SelectionIntoArgument() diff --git a/src/MeasureGUI/MeasureGUI_NormaleDlg.cxx b/src/MeasureGUI/MeasureGUI_NormaleDlg.cxx index 03619dc03..f2df1b3d3 100644 --- a/src/MeasureGUI/MeasureGUI_NormaleDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_NormaleDlg.cxx @@ -267,7 +267,7 @@ void MeasureGUI_NormaleDlg::SetEditCurrentArgument() GroupArgs->PushButton2->setDown(false); GroupArgs->LineEdit2->setEnabled(false); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_FACE); + localSelection(TopAbs_FACE); } else if (send == GroupArgs->PushButton2) { myEditCurrentArgument = GroupArgs->LineEdit2; @@ -275,7 +275,7 @@ void MeasureGUI_NormaleDlg::SetEditCurrentArgument() GroupArgs->PushButton1->setDown(false); GroupArgs->LineEdit1->setEnabled(false); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); diff --git a/src/MeasureGUI/MeasureGUI_PointDlg.cxx b/src/MeasureGUI/MeasureGUI_PointDlg.cxx index a0bd2762b..d2acb6e3e 100644 --- a/src/MeasureGUI/MeasureGUI_PointDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_PointDlg.cxx @@ -112,7 +112,7 @@ void MeasureGUI_PointDlg::Init() //================================================================================= void MeasureGUI_PointDlg::activateSelection() { - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); } //================================================================================= diff --git a/src/MeasureGUI/MeasureGUI_PropertiesDlg.cxx b/src/MeasureGUI/MeasureGUI_PropertiesDlg.cxx index 620103fdf..ecaa437ba 100644 --- a/src/MeasureGUI/MeasureGUI_PropertiesDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_PropertiesDlg.cxx @@ -125,7 +125,7 @@ void MeasureGUI_PropertiesDlg::activateSelection() std::list needTypes; needTypes.push_back( TopAbs_EDGE ), needTypes.push_back( TopAbs_WIRE ), needTypes.push_back( TopAbs_FACE ), needTypes.push_back( TopAbs_SHELL ), needTypes.push_back( TopAbs_SOLID ), needTypes.push_back( TopAbs_COMPOUND ); - localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + localSelection( needTypes ); } void MeasureGUI_PropertiesDlg::SelectionIntoArgument() diff --git a/src/MeasureGUI/MeasureGUI_WhatisDlg.cxx b/src/MeasureGUI/MeasureGUI_WhatisDlg.cxx index cd4d660da..7b331751c 100644 --- a/src/MeasureGUI/MeasureGUI_WhatisDlg.cxx +++ b/src/MeasureGUI/MeasureGUI_WhatisDlg.cxx @@ -194,7 +194,7 @@ void MeasureGUI_WhatisDlg::processObject() void MeasureGUI_WhatisDlg::activateSelection() { globalSelection(); // all types of objects - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_SHAPE); // all types of sub-shapes + localSelection(TopAbs_SHAPE); // all types of sub-shapes } //================================================================================= diff --git a/src/PrimitiveGUI/PrimitiveGUI_BoxDlg.cxx b/src/PrimitiveGUI/PrimitiveGUI_BoxDlg.cxx index 7ee734a7b..f18df7940 100644 --- a/src/PrimitiveGUI/PrimitiveGUI_BoxDlg.cxx +++ b/src/PrimitiveGUI/PrimitiveGUI_BoxDlg.cxx @@ -307,7 +307,7 @@ void PrimitiveGUI_BoxDlg::SetEditCurrentArgument() disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); @@ -323,7 +323,7 @@ void PrimitiveGUI_BoxDlg::ActivateThisDialog() { GEOMBase_Skeleton::ActivateThisDialog(); if (getConstructorId() == 0) { - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); } diff --git a/src/PrimitiveGUI/PrimitiveGUI_ConeDlg.cxx b/src/PrimitiveGUI/PrimitiveGUI_ConeDlg.cxx index a3c86ed62..a69ddf957 100644 --- a/src/PrimitiveGUI/PrimitiveGUI_ConeDlg.cxx +++ b/src/PrimitiveGUI/PrimitiveGUI_ConeDlg.cxx @@ -308,7 +308,7 @@ void PrimitiveGUI_ConeDlg::SetEditCurrentArgument() GroupPoints->LineEdit2->setEnabled(false); globalSelection(GEOM_POINT); // to break previous local selection - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } else if (send == GroupPoints->PushButton2) { myEditCurrentArgument = GroupPoints->LineEdit2; @@ -317,7 +317,7 @@ void PrimitiveGUI_ConeDlg::SetEditCurrentArgument() GroupPoints->LineEdit1->setEnabled(false); globalSelection(GEOM_LINE);// to break previous local selection - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); diff --git a/src/PrimitiveGUI/PrimitiveGUI_CylinderDlg.cxx b/src/PrimitiveGUI/PrimitiveGUI_CylinderDlg.cxx index fd30c9b44..fce60b91c 100644 --- a/src/PrimitiveGUI/PrimitiveGUI_CylinderDlg.cxx +++ b/src/PrimitiveGUI/PrimitiveGUI_CylinderDlg.cxx @@ -317,7 +317,7 @@ void PrimitiveGUI_CylinderDlg::SetEditCurrentArgument() GroupPoints->LineEdit2->setEnabled(false); globalSelection(GEOM_POINT); // to break previous local selection - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } else if (send == GroupPoints->PushButton2) { myEditCurrentArgument = GroupPoints->LineEdit2; @@ -326,7 +326,7 @@ void PrimitiveGUI_CylinderDlg::SetEditCurrentArgument() GroupPoints->LineEdit1->setEnabled(false); globalSelection(GEOM_LINE); // to break previous local selection - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); diff --git a/src/PrimitiveGUI/PrimitiveGUI_DiskDlg.cxx b/src/PrimitiveGUI/PrimitiveGUI_DiskDlg.cxx index 4101be272..d558048bf 100755 --- a/src/PrimitiveGUI/PrimitiveGUI_DiskDlg.cxx +++ b/src/PrimitiveGUI/PrimitiveGUI_DiskDlg.cxx @@ -397,11 +397,11 @@ void PrimitiveGUI_DiskDlg::SetEditCurrentArgument() disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); if (myEditCurrentArgument == GroupPntVecR->LineEdit2) { globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } else { globalSelection(); // close local contexts, if any - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); diff --git a/src/PrimitiveGUI/PrimitiveGUI_FaceDlg.cxx b/src/PrimitiveGUI/PrimitiveGUI_FaceDlg.cxx index 6f6d17912..e36fd5fc0 100755 --- a/src/PrimitiveGUI/PrimitiveGUI_FaceDlg.cxx +++ b/src/PrimitiveGUI/PrimitiveGUI_FaceDlg.cxx @@ -127,7 +127,7 @@ void PrimitiveGUI_FaceDlg::Init() myEdge.nullify(); myFace.nullify(); globalSelection(); // close local contexts, if any - // localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + // localSelection( TopAbs_EDGE ); myOrientationType = 1; @@ -224,12 +224,12 @@ void PrimitiveGUI_FaceDlg::TypeButtonClicked() { if ( GroupType->RadioButton1->isChecked() ) { globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); GroupPlane->TextLabel1->setText( tr( "GEOM_EDGE" ) ); } else if ( GroupType->RadioButton2->isChecked() ) { globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_FACE ); + localSelection( TopAbs_FACE ); GroupPlane->TextLabel1->setText( tr( "GEOM_FACE" ) ); } myEditCurrentArgument = GroupPlane->LineEdit1; @@ -288,7 +288,7 @@ void PrimitiveGUI_FaceDlg::ConstructorsClicked( int constructorId ) case 1: { globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); myEditCurrentArgument = GroupPlane->LineEdit1; myEditCurrentArgument->setText(""); myEdge.nullify(); @@ -362,9 +362,9 @@ void PrimitiveGUI_FaceDlg::SetEditCurrentArgument() if ( send == GroupPlane->PushButton1 ) { myEditCurrentArgument = GroupPlane->LineEdit1; if (GroupType->RadioButton1->isChecked()) - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); else if (GroupType->RadioButton1->isChecked()) - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_FACE ); + localSelection( TopAbs_FACE ); } myEditCurrentArgument->setFocus(); diff --git a/src/PrimitiveGUI/PrimitiveGUI_SphereDlg.cxx b/src/PrimitiveGUI/PrimitiveGUI_SphereDlg.cxx index ddd615ef9..73e2c592f 100644 --- a/src/PrimitiveGUI/PrimitiveGUI_SphereDlg.cxx +++ b/src/PrimitiveGUI/PrimitiveGUI_SphereDlg.cxx @@ -165,7 +165,7 @@ void PrimitiveGUI_SphereDlg::ConstructorsClicked( int constructorId ) case 0: { globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); GroupDimensions->hide(); GroupPoints->show(); @@ -268,7 +268,7 @@ void PrimitiveGUI_SphereDlg::SetEditCurrentArgument() GroupPoints->LineEdit1->setFocus(); myEditCurrentArgument = GroupPoints->LineEdit1; globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX ); + localSelection( TopAbs_VERTEX ); SelectionIntoArgument(); } } diff --git a/src/PrimitiveGUI/PrimitiveGUI_TorusDlg.cxx b/src/PrimitiveGUI/PrimitiveGUI_TorusDlg.cxx index 3cc46d8e5..979e52412 100644 --- a/src/PrimitiveGUI/PrimitiveGUI_TorusDlg.cxx +++ b/src/PrimitiveGUI/PrimitiveGUI_TorusDlg.cxx @@ -296,7 +296,7 @@ void PrimitiveGUI_TorusDlg::SetEditCurrentArgument() GroupPoints->LineEdit2->setEnabled(false); globalSelection(GEOM_POINT); // to break previous local selection - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } else if (send == GroupPoints->PushButton2) { myEditCurrentArgument = GroupPoints->LineEdit2; @@ -305,7 +305,7 @@ void PrimitiveGUI_TorusDlg::SetEditCurrentArgument() GroupPoints->LineEdit1->setEnabled(false); globalSelection(GEOM_LINE); // to break previous local selection - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); diff --git a/src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx b/src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx index 086874a90..673f29d6b 100644 --- a/src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx +++ b/src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx @@ -550,12 +550,10 @@ bool RepairGUI_DivideEdgeDlg::getIsByParameter() const //================================================================================= void RepairGUI_DivideEdgeDlg::initSelection() { - TopAbs_ShapeEnum type = TopAbs_EDGE; - if ( myEditCurrentArgument == GroupPoints->LineEdit2 ) - type = TopAbs_VERTEX; - - globalSelection(); // close local contexts, if any - localSelection( GEOM::GEOM_Object::_nil(), type ); // load local selection on ALL objects + // close local contexts + globalSelection(); + // load local selection on ALL objects + localSelection( myEditCurrentArgument == GroupPoints->LineEdit2 ? TopAbs_VERTEX : TopAbs_EDGE ); } //================================================================================= diff --git a/src/TransformationGUI/TransformationGUI_MirrorDlg.cxx b/src/TransformationGUI/TransformationGUI_MirrorDlg.cxx index 133d181d6..ebc844cc1 100644 --- a/src/TransformationGUI/TransformationGUI_MirrorDlg.cxx +++ b/src/TransformationGUI/TransformationGUI_MirrorDlg.cxx @@ -266,14 +266,14 @@ void TransformationGUI_MirrorDlg::SetEditCurrentArgument() switch (getConstructorId()) { case 0: - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); break; case 1: - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); break; case 2: globalSelection(GEOM_PLANE); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_FACE); + localSelection(TopAbs_FACE); break; } diff --git a/src/TransformationGUI/TransformationGUI_MultiRotationDlg.cxx b/src/TransformationGUI/TransformationGUI_MultiRotationDlg.cxx index b3f04d0a0..f54ee69a3 100644 --- a/src/TransformationGUI/TransformationGUI_MultiRotationDlg.cxx +++ b/src/TransformationGUI/TransformationGUI_MultiRotationDlg.cxx @@ -330,7 +330,7 @@ void TransformationGUI_MultiRotationDlg::SetEditCurrentArgument() else if (send == GroupArgs->PushButton2) { myEditCurrentArgument = GroupArgs->LineEdit2; - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); GroupArgs->PushButton1->setDown(false); GroupArgs->LineEdit1->setEnabled(false); diff --git a/src/TransformationGUI/TransformationGUI_MultiTranslationDlg.cxx b/src/TransformationGUI/TransformationGUI_MultiTranslationDlg.cxx index da234f210..1051b8abf 100644 --- a/src/TransformationGUI/TransformationGUI_MultiTranslationDlg.cxx +++ b/src/TransformationGUI/TransformationGUI_MultiTranslationDlg.cxx @@ -429,7 +429,7 @@ void TransformationGUI_MultiTranslationDlg::SetEditCurrentArgument() else if (send == GroupPoints->PushButton2) { myEditCurrentArgument = GroupPoints->LineEdit2; - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); GroupPoints->PushButton1->setDown(false); GroupPoints->LineEdit1->setEnabled(false); @@ -445,7 +445,7 @@ void TransformationGUI_MultiTranslationDlg::SetEditCurrentArgument() else if (send == GroupDimensions->PushButton2) { myEditCurrentArgument = GroupDimensions->LineEdit2; - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); GroupDimensions->PushButton1->setDown(false); GroupDimensions->PushButton3->setDown(false); @@ -455,7 +455,7 @@ void TransformationGUI_MultiTranslationDlg::SetEditCurrentArgument() else if (send == GroupDimensions->PushButton3) { myEditCurrentArgument = GroupDimensions->LineEdit3; - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); GroupDimensions->PushButton1->setDown(false); GroupDimensions->PushButton2->setDown(false); diff --git a/src/TransformationGUI/TransformationGUI_PositionDlg.cxx b/src/TransformationGUI/TransformationGUI_PositionDlg.cxx index 87d155511..fd0283e14 100644 --- a/src/TransformationGUI/TransformationGUI_PositionDlg.cxx +++ b/src/TransformationGUI/TransformationGUI_PositionDlg.cxx @@ -259,7 +259,7 @@ void TransformationGUI_PositionDlg::ConstructorsClicked (int constructorId) void TransformationGUI_PositionDlg::SelectionTypeButtonClicked() { if ( Group1->CheckButton2->isChecked() ) { - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); } else { TColStd_MapOfInteger aMap; aMap.Add(GEOM_WIRE); @@ -433,7 +433,7 @@ void TransformationGUI_PositionDlg::SetEditCurrentArgument() Group1->CheckButton2->setEnabled(true); if ( Group1->CheckButton2->isChecked() ) { - localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE ); + localSelection( TopAbs_EDGE ); } else { TColStd_MapOfInteger aMap; aMap.Add(GEOM_WIRE); diff --git a/src/TransformationGUI/TransformationGUI_ProjectionDlg.cxx b/src/TransformationGUI/TransformationGUI_ProjectionDlg.cxx index 2e91fc3da..186e9e0c8 100644 --- a/src/TransformationGUI/TransformationGUI_ProjectionDlg.cxx +++ b/src/TransformationGUI/TransformationGUI_ProjectionDlg.cxx @@ -239,12 +239,12 @@ void TransformationGUI_ProjectionDlg::SetEditCurrentArgument() globalSelection( aMap ); std::list needTypes; needTypes.push_back( TopAbs_VERTEX ), needTypes.push_back( TopAbs_EDGE ), needTypes.push_back( TopAbs_WIRE ); - localSelection(GEOM::GEOM_Object::_nil(), needTypes ); + localSelection(needTypes); break; } case PROJ_ON_WIRE: case PROJ_ON_EDGE: { - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); break; } default:; @@ -258,9 +258,9 @@ void TransformationGUI_ProjectionDlg::SetEditCurrentArgument() myGroup->LineEdit1->setEnabled(false); switch ( getConstructorId() ) { - case PROJ_ON_FACE: localSelection(GEOM::GEOM_Object::_nil(), TopAbs_FACE); break; - case PROJ_ON_WIRE: localSelection(GEOM::GEOM_Object::_nil(), TopAbs_WIRE); break; - case PROJ_ON_EDGE: localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); break; + case PROJ_ON_FACE: localSelection(TopAbs_FACE); break; + case PROJ_ON_WIRE: localSelection(TopAbs_WIRE); break; + case PROJ_ON_EDGE: localSelection(TopAbs_EDGE); break; default:; } } diff --git a/src/TransformationGUI/TransformationGUI_RotationDlg.cxx b/src/TransformationGUI/TransformationGUI_RotationDlg.cxx index 03ce4cecb..7e9617f3d 100644 --- a/src/TransformationGUI/TransformationGUI_RotationDlg.cxx +++ b/src/TransformationGUI/TransformationGUI_RotationDlg.cxx @@ -361,9 +361,9 @@ void TransformationGUI_RotationDlg::SetEditCurrentArgument() GroupPoints->LineEdit5->setEnabled(false); if (getConstructorId() == 0) - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); else - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } else if (send == GroupPoints->PushButton4) { myEditCurrentArgument = GroupPoints->LineEdit4; @@ -375,7 +375,7 @@ void TransformationGUI_RotationDlg::SetEditCurrentArgument() GroupPoints->LineEdit2->setEnabled(false); GroupPoints->LineEdit5->setEnabled(false); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } else if (send == GroupPoints->PushButton5) { myEditCurrentArgument = GroupPoints->LineEdit5; @@ -387,7 +387,7 @@ void TransformationGUI_RotationDlg::SetEditCurrentArgument() GroupPoints->LineEdit2->setEnabled(false); GroupPoints->LineEdit4->setEnabled(false); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); diff --git a/src/TransformationGUI/TransformationGUI_ScaleDlg.cxx b/src/TransformationGUI/TransformationGUI_ScaleDlg.cxx index e43169ba3..50e338f11 100644 --- a/src/TransformationGUI/TransformationGUI_ScaleDlg.cxx +++ b/src/TransformationGUI/TransformationGUI_ScaleDlg.cxx @@ -325,7 +325,7 @@ void TransformationGUI_ScaleDlg::SetEditCurrentArgument() else if (send == PushButton2) { myEditCurrentArgument = LineEdit2; - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); PushButton1->setDown(false); LineEdit1->setEnabled(false); diff --git a/src/TransformationGUI/TransformationGUI_TranslationDlg.cxx b/src/TransformationGUI/TransformationGUI_TranslationDlg.cxx index f5622c716..23bafef69 100644 --- a/src/TransformationGUI/TransformationGUI_TranslationDlg.cxx +++ b/src/TransformationGUI/TransformationGUI_TranslationDlg.cxx @@ -385,9 +385,9 @@ void TransformationGUI_TranslationDlg::SetEditCurrentArgument() GroupPoints->LineEdit3->setEnabled(false); if (getConstructorId() == 1) - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); else - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); + localSelection(TopAbs_EDGE); } else if (send == GroupPoints->PushButton3) { myEditCurrentArgument = GroupPoints->LineEdit3; @@ -397,7 +397,7 @@ void TransformationGUI_TranslationDlg::SetEditCurrentArgument() GroupPoints->LineEdit1->setEnabled(false); GroupPoints->LineEdit2->setEnabled(false); - localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); + localSelection(TopAbs_VERTEX); } connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); From 4b7946662e2e79ef04ee3bb2ba74c7e05e063ac5 Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 24 Sep 2015 15:03:08 +0300 Subject: [PATCH 41/54] Dectivate local selection in BOP (CoTech decision) --- src/BooleanGUI/BooleanGUI_Dialog.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BooleanGUI/BooleanGUI_Dialog.cxx b/src/BooleanGUI/BooleanGUI_Dialog.cxx index 1a0de1b87..02ebd41d5 100644 --- a/src/BooleanGUI/BooleanGUI_Dialog.cxx +++ b/src/BooleanGUI/BooleanGUI_Dialog.cxx @@ -198,7 +198,7 @@ void BooleanGUI_Dialog::Init() mainFrame()->RadioButton1->setFocus(); globalSelection(GEOM_ALLSHAPES); - localSelection(TopAbs_SHAPE); + //localSelection(TopAbs_SHAPE); // VSR 24/09/2015: dectivate local selection in BOP (CoTech decision) myGroup->PushButton1->click(); resize(100,100); @@ -338,7 +338,7 @@ void BooleanGUI_Dialog::SetEditCurrentArgument() } globalSelection(GEOM_ALLSHAPES); - localSelection(TopAbs_SHAPE); + //localSelection(TopAbs_SHAPE); // VSR 24/09/2015: dectivate local selection in BOP (CoTech decision) // enable line edit myEditCurrentArgument->setEnabled(true); From cf799c8421249937467661161e4d4810c81dc2d7 Mon Sep 17 00:00:00 2001 From: vsr Date: Mon, 28 Sep 2015 18:29:48 +0300 Subject: [PATCH 42/54] 0023172: EDF 11516 - problem with StructuralElement --- src/GEOM_PY/structelem/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/GEOM_PY/structelem/__init__.py b/src/GEOM_PY/structelem/__init__.py index 47f2b6bcd..9fb941376 100644 --- a/src/GEOM_PY/structelem/__init__.py +++ b/src/GEOM_PY/structelem/__init__.py @@ -109,6 +109,8 @@ from salome.geom.geomtools import getGeompy from salome.geom.structelem import parts from salome.geom.structelem.parts import InvalidParameterError +import GEOM + ## This class manages the structural elements in the study. It is used to # create a new structural element from a list of commands. The parameter # \em studyId defines the ID of the study in which the manager will create From 55e65f660dec8de9682bd3abea0b6d4afbff5c6a Mon Sep 17 00:00:00 2001 From: Christophe Bourcier Date: Mon, 28 Sep 2015 14:37:06 +0200 Subject: [PATCH 43/54] Update translation files from Crowdin --- src/GEOMGUI/GEOM_msg_ja.ts | 158 ++++++++++++++++++------------------- 1 file changed, 77 insertions(+), 81 deletions(-) diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts index 2ed220891..0a55e444f 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -429,23 +429,7 @@ GEOM_SHAPE_STATISTICS - Shape Statistics - - - GEOM_CHECK_SELF_INTERSECTIONS_FAILED - 自己交差の検出に失敗しました - - - GEOM_NO_SELF_INTERSECTIONS - 自己交差は検出されませんでした。 - - - GEOM_SELF_INTERSECTIONS_FOUND - 自己交差が検出されました。 - - - GEOM_CHECK_SELF_INTERSECTIONS_ERRORS - 警告: 操作中にエラーがあったので、リストが不完全かもしれない + 形状の統計 GEOM_CIRCLE @@ -1363,6 +1347,10 @@ GEOM_LENGTH_VALUE 長さで + + GEOM_TAKE_ORIENTATION_INTO_ACCOUNT + エッジの方向に注意 + GEOM_PARTITION Partition @@ -1435,6 +1423,10 @@ GEOM_GROUP_NAME_PREFIX グループ名Prefix + + GEOM_STEP_BY_STEP + ステップ生成 + GEOM_PLANE Plane @@ -2433,7 +2425,7 @@ GEOM_WRN_FACES_NOT_FACE - Impossible de créer une face. Le résultat est un assemblage de faces. + たった1つの面を作成することはできません。結果は複合面になります。 WRN_SHAPE_UNCLOSED @@ -2576,8 +2568,8 @@ クイック交点 - MEN_SHAPE_STATISTICS - Shape Statistics + MEN_SHAPE_STATISTICS + 形状の統計 MEN_CHECK_FREE_BNDS @@ -2861,7 +2853,7 @@ MEN_MEASURES - Inspection + 計測 MEN_MIN_DIST @@ -3468,8 +3460,8 @@ 線幅 - PREF_DIMENSIONS_FONT - Font + PREF_DIMENSIONS_FONT + フォント PREF_DIMENSIONS_ARROW_LENGTH @@ -3493,7 +3485,7 @@ PREF_DIMENSIONS_USE_TEXT3D - Use 3D text + 3Dテキストの使用 PREF_HIDE_INPUT_OBJECT @@ -3621,7 +3613,7 @@ STB_SHAPE_STATISTICS - Shape Statistics + 形状の統計 STB_CHECK_FREE_BNDS @@ -4257,7 +4249,7 @@ TOP_SHAPE_STATISTICS - Shape Statistics + 形状の統計 TOP_CHECK_FREE_BNDS @@ -5152,8 +5144,8 @@ Z%1 : - GEOM_A_I - A%1 : + GEOM_A_I + A%1 : GEOM_SHAPES_ON_SHAPE_TITLE @@ -5373,11 +5365,11 @@ CC_PNT_ITEM_X_Y - X=%1, Y=%2 + X=%1, Y=%2 CC_PNT_ITEM_X_Y_Z - X=%1, Y=%2, Z=%3 + X=%1, Y=%2, Z=%3 GEOM_FILTER @@ -5420,24 +5412,24 @@ 修正 - GEOM_PLOT_DISTRIBUTION - Plot + GEOM_PLOT_DISTRIBUTION + Plot - GEOM_X_AXIS - Axe X + GEOM_X_AXIS + X軸 - GEOM_Y_AXIS - Axe Y + GEOM_Y_AXIS + Y軸 - GEOM_Z_AXIS - Axe Z + GEOM_Z_AXIS + Z軸 - GEOM_DIM_AXES - Dimensions along local axes + GEOM_DIM_AXES + 局所座標軸に沿った次元
      @@ -5801,11 +5793,11 @@ TABLE_X - X + X TABLE_Y - Y + Y @@ -6479,7 +6471,7 @@ Z - Z + Z @@ -6795,7 +6787,7 @@ OperationGUI_ChamferDlg D - D + D FACE_1 @@ -7266,12 +7258,12 @@ GEOMGUI_TextTreeWdg - TEXT_TREE_VIEW_TITLE - Text + TEXT_TREE_VIEW_TITLE + テキスト - TEXT_TREE_VIEW_NAME - Name + TEXT_TREE_VIEW_NAME + 名前 @@ -7297,7 +7289,7 @@ MeasureGUI_CheckSelfIntersectionsDlg GEOM_CHECK_INTERSECT_TYPE - Self-intersection Detection Type + 自己交差検出型 GEOM_CHECK_INTE_INTERSECTIONS @@ -7365,11 +7357,11 @@ GEOM_CHECK_INT_DEFLECT - Deflection coefficient + 偏向係数 GEOM_CHECK_INT_DETECT_GAPS - Detect gaps with tolerance + トレランスとのギャップ検出 @@ -7406,64 +7398,64 @@ MeasureGUI_ShapeStatisticsDlg - GEOM_SHAPE_STATISTICS_TYPE - Type + GEOM_SHAPE_STATISTICS_TYPE + タイプ - GEOM_SHAPE_STATISTICS_LENGTH - Edges length + GEOM_SHAPE_STATISTICS_LENGTH + エッジ長さ - GEOM_SHAPE_STATISTICS_AREA - Faces area + GEOM_SHAPE_STATISTICS_AREA + 面の面積 - GEOM_SHAPE_STATISTICS_VOLUME - Solids volume + GEOM_SHAPE_STATISTICS_VOLUME + ソリッドの体積 - GEOM_SHAPE_STATISTICS_NB_INTERVALS - Number of intervals + GEOM_SHAPE_STATISTICS_NB_INTERVALS + 間隔数 - GEOM_SHAPE_STATISTICS_SCALAR_RANGE - Scalar range + GEOM_SHAPE_STATISTICS_SCALAR_RANGE + スカラ範囲 - GEOM_SHAPE_STATISTICS_COMPUTE - Compute + GEOM_SHAPE_STATISTICS_COMPUTE + 計算 - GEOM_SHAPE_STATISTICS_MIN - Min + GEOM_SHAPE_STATISTICS_MIN + Min - GEOM_SHAPE_STATISTICS_MAX - Max + GEOM_SHAPE_STATISTICS_MAX + Max - GEOM_SHAPE_STATISTICS_CREATE_GROUPS - Create Groups + GEOM_SHAPE_STATISTICS_CREATE_GROUPS + グループの作成 - GEOM_SHAPE_STATISTICS_DISTRIBUTION_NB_ENT - Number of entities + GEOM_SHAPE_STATISTICS_DISTRIBUTION_NB_ENT + エンティティ数 - GEOM_SHAPE_STATISTICS_MIN_ERROR - Set minimal range value or switch-off Scalar range + GEOM_SHAPE_STATISTICS_MIN_ERROR + 範囲内最小の値をセットするかスカラ範囲のスイッチをOFFにしてください。 - GEOM_SHAPE_STATISTICS_MAX_ERROR - Set maximal range value or switch-off Scalar range + GEOM_SHAPE_STATISTICS_MAX_ERROR + 範囲内最大の値をセットするかスカラ範囲のスイッチをOFFにしてください。 - GEOM_SHAPE_STATISTICS_MIN_MAX_ERROR - Minimal range value can not be more than maximal + GEOM_SHAPE_STATISTICS_MIN_MAX_ERROR + 範囲内最小値が最大値より大きくすることはできません - GEOM_MSG_GROUPS_CREATED - %1 groups created + GEOM_MSG_GROUPS_CREATED + %1 グループを作成しました。 @@ -7593,5 +7585,9 @@ GEOM_PROJ_ON_CYL_LENGTH_ANGLE Length angle + + GEOM_PROJ_ON_CYL_ROTATION_ANGLE + 回転角度 + From 3e1586b2b466a509d049e1fd916c7ee0f9ccbb8a Mon Sep 17 00:00:00 2001 From: vsr Date: Mon, 5 Oct 2015 16:59:47 +0300 Subject: [PATCH 44/54] INT PAL 52894: TC7.7.0: 'Apply and Close' does not work in 'Sub-Shapes Selection' dialog --- src/EntityGUI/EntityGUI_SubShapeDlg.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EntityGUI/EntityGUI_SubShapeDlg.cxx b/src/EntityGUI/EntityGUI_SubShapeDlg.cxx index 9449cf030..085028ce1 100644 --- a/src/EntityGUI/EntityGUI_SubShapeDlg.cxx +++ b/src/EntityGUI/EntityGUI_SubShapeDlg.cxx @@ -334,7 +334,7 @@ void EntityGUI_SubShapeDlg::ClickOnOk() } if (isOk) - isOk = onAccept(); + isOk = onAccept( true, true, false ); if (isOk) ClickOnCancel(); From 0141ab7c44b949f57adb01cd1094d18ac55b5cec Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 6 Oct 2015 15:08:56 +0300 Subject: [PATCH 45/54] INT PAL 52894: TC7.7.0: 'Apply and Close' does not work in 'Sub-Shapes Selection' dialog - One more dialog box to fix --- src/BlocksGUI/BlocksGUI_ExplodeDlg.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/BlocksGUI/BlocksGUI_ExplodeDlg.cxx b/src/BlocksGUI/BlocksGUI_ExplodeDlg.cxx index 1f1fcda89..63352c47b 100644 --- a/src/BlocksGUI/BlocksGUI_ExplodeDlg.cxx +++ b/src/BlocksGUI/BlocksGUI_ExplodeDlg.cxx @@ -46,7 +46,7 @@ // purpose : Constructs a BlocksGUI_ExplodeDlg which is a child of 'parent'. //================================================================================= BlocksGUI_ExplodeDlg::BlocksGUI_ExplodeDlg( GeometryGUI* theGeometryGUI, QWidget* parent ) - : GEOMBase_Skeleton( theGeometryGUI, parent ) + : GEOMBase_Skeleton( theGeometryGUI, parent ), myNbBlocks( 0 ) { QPixmap image1( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_BLOCK_EXPLODE" ) ) ); QPixmap imageS( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) ); @@ -189,7 +189,7 @@ bool BlocksGUI_ExplodeDlg::ClickOnApply() } } - if ( !onAccept() ) + if ( !onAccept( true, true, false ) ) return false; activateSelection(); @@ -351,7 +351,7 @@ void BlocksGUI_ExplodeDlg::updateButtonState() //================================================================================= bool BlocksGUI_ExplodeDlg::isAllSubShapes() const { - return !myGrp1->CheckBox1->isChecked() || !myGrp1->CheckBox1->isEnabled(); + return !(myGrp1->CheckBox1->isEnabled() && myGrp1->CheckBox1->isChecked()); } //================================================================================= From 1db636b7ff138bd7b3ac84f1c77a42299b259983 Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 6 Oct 2015 15:09:51 +0300 Subject: [PATCH 46/54] 0052898: TC 7.7.0: Regression "Glue Faces" dialog glues all faces instead selected faces --- src/GEOM/GEOM_PythonDump.cxx | 4 ++-- src/RepairGUI/RepairGUI_GlueDlg.cxx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/GEOM/GEOM_PythonDump.cxx b/src/GEOM/GEOM_PythonDump.cxx index 6d697dd99..bcee3dc04 100644 --- a/src/GEOM/GEOM_PythonDump.cxx +++ b/src/GEOM/GEOM_PythonDump.cxx @@ -144,7 +144,7 @@ namespace GEOM TPythonDump::operator<< (const std::list& theObjects) { Standard_Integer aLength = theObjects.size(); - if ( aLength > 1 ) { + if ( aLength != 1 ) { myStream << "["; } std::list::const_iterator obj = theObjects.begin(); @@ -152,7 +152,7 @@ namespace GEOM *this << *obj; if ( i < aLength ) myStream << ", "; } - if ( aLength > 1 ) { + if ( aLength != 1 ) { myStream << "]"; } return *this; diff --git a/src/RepairGUI/RepairGUI_GlueDlg.cxx b/src/RepairGUI/RepairGUI_GlueDlg.cxx index 3d9c5cc1d..2c288851b 100644 --- a/src/RepairGUI/RepairGUI_GlueDlg.cxx +++ b/src/RepairGUI/RepairGUI_GlueDlg.cxx @@ -615,8 +615,6 @@ bool RepairGUI_GlueDlg::onAcceptLocal() return false; } - erasePreview(false); - try { if (openCommand()) { SUIT_OverrideCursor wc; @@ -672,6 +670,8 @@ bool RepairGUI_GlueDlg::onAcceptLocal() abortCommand(); } + erasePreview(false); + updateViewer(); activateSelection(); updateButtonState(); From 0c3f5d3c34830135f668fbdd15f2291d43265008 Mon Sep 17 00:00:00 2001 From: vsr Date: Wed, 7 Oct 2015 10:31:33 +0300 Subject: [PATCH 47/54] INT PAL 52906: TC7.7.0: SIGSEGV at attempt to restrict selection by second shape in 'Create Group' dialog box --- src/GroupGUI/GroupGUI_GroupDlg.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/GroupGUI/GroupGUI_GroupDlg.cxx b/src/GroupGUI/GroupGUI_GroupDlg.cxx index 984bc28c2..40463f32a 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.cxx +++ b/src/GroupGUI/GroupGUI_GroupDlg.cxx @@ -446,7 +446,7 @@ void GroupGUI_GroupDlg::ActivateThisDialog() //================================================================================= void GroupGUI_GroupDlg::SetEditCurrentArgument() { - QPushButton* send = (QPushButton*)sender(); + QPushButton* send = qobject_cast( sender() ); if (send == mySelBtn) { myEditCurrentArgument = myMainName; @@ -472,7 +472,8 @@ void GroupGUI_GroupDlg::SetEditCurrentArgument() // activateSelection(); if(myEditCurrentArgument) { myEditCurrentArgument->setFocus(); - send->setDown(true); + if ( send ) + send->setDown(true); } updateState(); From 1d1c325da545a4ab4fb80f7ddb590958123ad186 Mon Sep 17 00:00:00 2001 From: vsr Date: Wed, 7 Oct 2015 10:57:04 +0300 Subject: [PATCH 48/54] INT PAL 52903: TC7.7.0: Incorrect behavior in "Shape processing" dialog --- src/RepairGUI/RepairGUI_ShapeProcessDlg.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RepairGUI/RepairGUI_ShapeProcessDlg.cxx b/src/RepairGUI/RepairGUI_ShapeProcessDlg.cxx index e3df32f8a..71d3ce0f2 100755 --- a/src/RepairGUI/RepairGUI_ShapeProcessDlg.cxx +++ b/src/RepairGUI/RepairGUI_ShapeProcessDlg.cxx @@ -361,7 +361,7 @@ void RepairGUI_ShapeProcessDlg::init() //myOpList->setCurrentRow( myOpList->findItem( 0 ); reset(); - myStack->setCurrentIndex( 0 ); + myOpList->setCurrentRow(0); initName( tr( "PROCESS_SHAPE_NEW_OBJ_NAME" )); selectionChanged(); From 0068817237ae7c33dffc7bfa9de995e219faf0fc Mon Sep 17 00:00:00 2001 From: vsr Date: Wed, 7 Oct 2015 14:16:02 +0300 Subject: [PATCH 49/54] 0023180: [CEA 1602] Regression : MakePartition of a solid by an empty compound returns an error - Allow creating empty compounds --- src/GEOMImpl/GEOMImpl_ShapeDriver.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index 46b7d1d7b..8b585f83e 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -114,14 +114,15 @@ namespace { TopoDS_Iterator it( c, Standard_True, Standard_True ); - // check that compound is not empty - bool result = it.More(); + // empty compound is OK only if we explicitly create a compound of shapes + bool result = true; // => if expected type is TopAbs_SHAPE, we allow compound consisting of any shapes, this above check is enough // => otherwise we have to check compound's content // => compound sometimes can contain enclosed compound(s), we process them recursively and rebuild initial compound if ( t != TopAbs_SHAPE ) { + result = it.More(); std::list compounds, shapes; compounds.push_back( c ); while ( !compounds.empty() && result ) { From bff35f0310a15aa315b9faa36a07e24d337952a5 Mon Sep 17 00:00:00 2001 From: Florian BRUNET Date: Tue, 6 Oct 2015 16:22:30 +0200 Subject: [PATCH 50/54] French translation of GEOM new features. --- src/GEOMGUI/GEOM_msg_fr.ts | 66 +++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index ef98f61ec..1a1231364 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -433,7 +433,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau GEOM_SHAPE_STATISTICS - Shape Statistics + Statistiques sur l'objet GEOM_CIRCLE @@ -689,7 +689,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau GEOM_TOWARDS_INSIDE - Epaissit vers l'intérieur + Epaissit vers l'intérieur GEOM_SCALE_PRISM @@ -2566,7 +2566,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau MEN_SHAPE_STATISTICS - Shape Statistics + Statistiques sur l'objet MEN_CHECK_FREE_BNDS @@ -2850,7 +2850,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau MEN_MEASURES - Inspection + Inspection MEN_MIN_DIST @@ -3458,7 +3458,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau PREF_DIMENSIONS_FONT - Font + Police PREF_DIMENSIONS_ARROW_LENGTH @@ -3482,7 +3482,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau PREF_DIMENSIONS_USE_TEXT3D - Use 3D text + Utiliser du texte 3D PREF_HIDE_INPUT_OBJECT @@ -3610,7 +3610,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau STB_SHAPE_STATISTICS - Shape Statistics + Statistique de l'objet STB_CHECK_FREE_BNDS @@ -3882,7 +3882,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau STB_THICKNESS - Crée un solide par ajout d'épaisseur + Crée un solide par ajout d'épaisseur STB_PLANE @@ -4246,7 +4246,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau TOP_SHAPE_STATISTICS - Shape Statistics + Statistique de l'objet TOP_CHECK_FREE_BNDS @@ -5414,7 +5414,7 @@ le paramètre '%1' aux préférences du module Géométrie. GEOM_PLOT_DISTRIBUTION - Plot + Graphe GEOM_X_AXIS @@ -5430,7 +5430,7 @@ le paramètre '%1' aux préférences du module Géométrie. GEOM_DIM_AXES - Dimensions along local axes + Dimensions sur les axes locaux @@ -5481,7 +5481,7 @@ le paramètre '%1' aux préférences du module Géométrie. TOOL_MEASURES - Inspection + Inspection TOOL_IMPORTEXPORT @@ -7270,11 +7270,11 @@ Voulez-vous en créer un nouveau ? GEOMGUI_TextTreeWdg TEXT_TREE_VIEW_TITLE - Text + Texte TEXT_TREE_VIEW_NAME - Name + Nom @@ -7300,7 +7300,7 @@ Voulez-vous en créer un nouveau ? MeasureGUI_CheckSelfIntersectionsDlg GEOM_CHECK_INTERSECT_TYPE - Self-intersection Detection Type + Détection du type d'auto-intersection GEOM_CHECK_INTE_INTERSECTIONS @@ -7368,11 +7368,11 @@ Voulez-vous en créer un nouveau ? GEOM_CHECK_INT_DEFLECT - Deflection coefficient + Coefficient de déflexion GEOM_CHECK_INT_DETECT_GAPS - Detect gaps with tolerance + Détection des écarts avec tolérance @@ -7410,63 +7410,63 @@ Voulez-vous en créer un nouveau ? MeasureGUI_ShapeStatisticsDlg GEOM_SHAPE_STATISTICS_TYPE - Type + Type GEOM_SHAPE_STATISTICS_LENGTH - Edges length + Longueur des arêtes GEOM_SHAPE_STATISTICS_AREA - Faces area + Aire des faces GEOM_SHAPE_STATISTICS_VOLUME - Solids volume + Volume des solides GEOM_SHAPE_STATISTICS_NB_INTERVALS - Number of intervals + Nombre d'intervalles GEOM_SHAPE_STATISTICS_SCALAR_RANGE - Scalar range + Echelle de dimension GEOM_SHAPE_STATISTICS_COMPUTE - Compute + Calculer GEOM_SHAPE_STATISTICS_MIN - Min + Min GEOM_SHAPE_STATISTICS_MAX - Max + Max GEOM_SHAPE_STATISTICS_CREATE_GROUPS - Create Groups + Créer des groupes GEOM_SHAPE_STATISTICS_DISTRIBUTION_NB_ENT - Number of entities + Nombre d'entités GEOM_SHAPE_STATISTICS_MIN_ERROR - Set minimal range value or switch-off Scalar range + Spécifier une valeur minimale ou ignorer l'échelle de dimension GEOM_SHAPE_STATISTICS_MAX_ERROR - Set maximal range value or switch-off Scalar range + Spécifier une valeur maximale ou ignorer l'échelle de dimension GEOM_SHAPE_STATISTICS_MIN_MAX_ERROR - Minimal range value can not be more than maximal + La valeur minimal ne peut pas être plus grande que la maximale GEOM_MSG_GROUPS_CREATED - %1 groups created + %1 groupes créés @@ -7594,7 +7594,7 @@ Voulez-vous en créer un nouveau ? GEOM_PROJ_ON_CYL_LENGTH_ANGLE - Longueur de l'angle + Longueur de l'angle From 6c1ac0fb3115da076288afcc3f522f924e4ea157 Mon Sep 17 00:00:00 2001 From: skv Date: Mon, 12 Oct 2015 17:51:55 +0300 Subject: [PATCH 51/54] 0023169: [CEA 1594] Fuse fail --- src/GEOMImpl/GEOMImpl_BooleanDriver.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx b/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx index 4d6a72f2a..54ab68721 100644 --- a/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx @@ -82,7 +82,7 @@ static TopoDS_Shape RemoveExtraEdges(const TopoDS_Shape &theShape) else { TopoDS_Shape aFixed; ShHealOper_ShapeProcess aHealer; - aHealer.Perform(aResult, aFixed); + aHealer.Perform(aShape, aFixed); if (aHealer.isDone() && GEOMUtils::CheckShape(aFixed)) aResult = aFixed; } From c99e235ed84ad27d3d7b079f1bf68a1748fa4911 Mon Sep 17 00:00:00 2001 From: vsr Date: Mon, 12 Oct 2015 17:20:54 +0300 Subject: [PATCH 52/54] INT PAL 52900: TC7.7.0: Preview disappears for 'Block Multi-Transformation' operation --- src/BlocksGUI/BlocksGUI_TrsfDlg.cxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/BlocksGUI/BlocksGUI_TrsfDlg.cxx b/src/BlocksGUI/BlocksGUI_TrsfDlg.cxx index b441b58a8..985bfc97e 100644 --- a/src/BlocksGUI/BlocksGUI_TrsfDlg.cxx +++ b/src/BlocksGUI/BlocksGUI_TrsfDlg.cxx @@ -219,7 +219,6 @@ bool BlocksGUI_TrsfDlg::ClickOnApply() //================================================================================= void BlocksGUI_TrsfDlg::SelectionIntoArgument() { - erasePreview(); myEditCurrentArgument->setText(""); // Get index of current selection focus @@ -273,7 +272,6 @@ void BlocksGUI_TrsfDlg::SelectionIntoArgument() } myEditCurrentArgument->setText(aName); myFaces[aCurrFocus] = anIndex; - processPreview(); } switch (aCurrFocus) { @@ -316,6 +314,8 @@ void BlocksGUI_TrsfDlg::SelectionIntoArgument() default: break; } + + processPreview(); } //================================================================================= @@ -379,6 +379,8 @@ void BlocksGUI_TrsfDlg::SetEditCurrentArgument() aSender->setDown(true); activateSelection(); + + processPreview(); } //================================================================================= From d562b644282925386e7749b9ad49306c3e193121 Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 15 Oct 2015 08:56:54 +0300 Subject: [PATCH 53/54] Increment version: 7.7.0 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8637d6784..8a28f2af2 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,11 +30,11 @@ CMAKE_POLICY(SET CMP0003 NEW) STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC) SET(${PROJECT_NAME_UC}_MAJOR_VERSION 7) -SET(${PROJECT_NAME_UC}_MINOR_VERSION 6) +SET(${PROJECT_NAME_UC}_MINOR_VERSION 7) SET(${PROJECT_NAME_UC}_PATCH_VERSION 0) SET(${PROJECT_NAME_UC}_VERSION ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION}) -SET(${PROJECT_NAME_UC}_VERSION_DEV 1) +SET(${PROJECT_NAME_UC}_VERSION_DEV 0) # Find KERNEL # =========== From 9c1f3008116fecc2c3c711d8bf12cccf0dc6e295 Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 1 Dec 2015 17:51:28 +0300 Subject: [PATCH 54/54] Increment version: 7.7.1 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a28f2af2..dbe3a9531 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC) SET(${PROJECT_NAME_UC}_MAJOR_VERSION 7) SET(${PROJECT_NAME_UC}_MINOR_VERSION 7) -SET(${PROJECT_NAME_UC}_PATCH_VERSION 0) +SET(${PROJECT_NAME_UC}_PATCH_VERSION 1) SET(${PROJECT_NAME_UC}_VERSION ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION}) SET(${PROJECT_NAME_UC}_VERSION_DEV 0)