From 5504d02a2237b17b8459bcd3b1fb2a89468598cd Mon Sep 17 00:00:00 2001 From: eap Date: Mon, 1 Aug 2016 15:42:08 +0300 Subject: [PATCH] 23305: [EDF 10301] Extrusion with scaling --- .../gui/SMESH/images/extrusionalongaline1.png | Bin 37137 -> 45079 bytes doc/salome/gui/SMESH/input/extrusion.doc | 19 ++ idl/SMESH_MeshEditor.idl | 3 + src/SMESH/SMESH_MeshEditor.cxx | 141 ++++++-- src/SMESH/SMESH_MeshEditor.hxx | 37 ++- src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx | 303 +++++++++++++++--- src/SMESHGUI/SMESHGUI_ExtrusionDlg.h | 25 +- src/SMESHGUI/SMESH_msg_en.ts | 12 + src/SMESH_I/SMESH_MeshEditor_i.cxx | 61 +++- src/SMESH_I/SMESH_MeshEditor_i.hxx | 3 + src/SMESH_SWIG/smeshBuilder.py | 30 +- .../StdMeshers_RadialQuadrangle_1D2D.cxx | 32 +- 12 files changed, 554 insertions(+), 112 deletions(-) diff --git a/doc/salome/gui/SMESH/images/extrusionalongaline1.png b/doc/salome/gui/SMESH/images/extrusionalongaline1.png index 5f0d13039f1082c3c0e498abefb40c61dcbfe7b7..7de580be18c7ef18d5903b7752fdfb665fda67ae 100644 GIT binary patch literal 45079 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 z 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 QALb!hNhOIa#N*fh3-X!n#sB~S diff --git a/doc/salome/gui/SMESH/input/extrusion.doc b/doc/salome/gui/SMESH/input/extrusion.doc index 6b07af9e1..96da45d43 100644 --- a/doc/salome/gui/SMESH/input/extrusion.doc +++ b/doc/salome/gui/SMESH/input/extrusion.doc @@ -128,6 +128,25 @@ The following dialog will appear:
  • Specify the Number of steps.
  • + +
  • Optionally specify Scale Factors. Each scale factor in + the list is applied to nodes of a corresponding extrusion step + unless Linear Variation of Scale Factors is checked, is + which case the scale factors are spread over all extrusion steps.
  • +
      +
    • Scaling Center can be defined either using spin boxes + or by picking a node in the Viewer or by picking a geometrical + vertex in the Object Browser.
    • +
    • \b Add button adds a scale factor to the list. + \image html add.png +
      "Add" button
      +
    • +
    • \b Remove button removes selected scale factors from the list. + \image html remove.png +
      "Remove" button
      +
    • +
    +
  • If you activate Generate Groups check-box, the result elements created from selected elements contained in groups will be included into new groups named by pattern "& theScales, + const gp_XYZ* theBasePoint, + const int theFlags, + const double theTolerance): myDir( theStep ), + myBaseP( Precision::Infinite(), 0, 0 ), myFlags( theFlags ), myTolerance( theTolerance ), myElemsToUse( NULL ) @@ -5494,6 +5497,37 @@ SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec& theStep, for (int i=1; i<=theNbSteps; i++ ) mySteps->Append( stepSize ); + int nbScales = theScales.size(); + if ( nbScales > 0 ) + { + if ( IsLinearVariation() && nbScales < theNbSteps ) + { + myScales.reserve( theNbSteps ); + std::list::const_iterator scale = theScales.begin(); + double prevScale = 1.0; + for ( int iSc = 1; scale != theScales.end(); ++scale, ++iSc ) + { + int iStep = int( iSc / double( nbScales ) * theNbSteps + 0.5 ); + int stDelta = Max( 1, iStep - myScales.size()); + double scDelta = ( *scale - prevScale ) / stDelta; + for ( int iStep = 0; iStep < stDelta; ++iStep ) + { + myScales.push_back( prevScale + scDelta ); + prevScale = myScales.back(); + } + prevScale = *scale; + } + } + else + { + myScales.assign( theScales.begin(), theScales.end() ); + } + } + if ( theBasePoint ) + { + myBaseP = *theBasePoint; + } + if (( theFlags & EXTRUSION_FLAG_SEW ) && ( theTolerance > 0 )) { @@ -5562,12 +5596,38 @@ SMESH_MeshEditor::ExtrusParam::ExtrusParam( const double theStepSize, //======================================================================= //function : ExtrusParam::SetElementsToUse //purpose : stores elements to use for extrusion by normal, depending on -// state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag +// state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag; +// define myBaseP for scaling //======================================================================= -void SMESH_MeshEditor::ExtrusParam::SetElementsToUse( const TIDSortedElemSet& elems ) +void SMESH_MeshEditor::ExtrusParam::SetElementsToUse( const TIDSortedElemSet& elems, + const TIDSortedElemSet& nodes ) { myElemsToUse = ToUseInpElemsOnly() ? & elems : 0; + + if ( Precision::IsInfinite( myBaseP.X() )) // myBaseP not defined + { + myBaseP.SetCoord( 0.,0.,0. ); + TIDSortedElemSet newNodes; + + const TIDSortedElemSet* elemSets[] = { &elems, &nodes }; + for ( int is2ndSet = 0; is2ndSet < 2; ++is2ndSet ) + { + const TIDSortedElemSet& elements = *( elemSets[ is2ndSet ]); + TIDSortedElemSet::const_iterator itElem = elements.begin(); + for ( ; itElem != elements.end(); itElem++ ) + { + const SMDS_MeshElement* elem = *itElem; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + while ( itN->more() ) { + const SMDS_MeshElement* node = itN->next(); + if ( newNodes.insert( node ).second ) + myBaseP += SMESH_TNodeXYZ( node ); + } + } + } + myBaseP /= newNodes.size(); + } } //======================================================================= @@ -5637,6 +5697,41 @@ makeNodesByDir( SMESHDS_Mesh* mesh, const SMDS_MeshNode * newNode = mesh->AddNode( p.X(), p.Y(), p.Z() ); newNodes.push_back( newNode ); } + + if ( !myScales.empty() ) + { + if ( makeMediumNodes && myMediumScales.empty() ) + { + myMediumScales.resize( myScales.size() ); + double prevFactor = 1.; + for ( size_t i = 0; i < myScales.size(); ++i ) + { + myMediumScales[i] = 0.5 * ( prevFactor + myScales[i] ); + prevFactor = myScales[i]; + } + } + typedef std::vector::iterator ScaleIt; + ScaleIt scales[] = { myScales.begin(), myMediumScales.begin() }; + + size_t iSc = 0, nbScales = myScales.size() + myMediumScales.size(); + + gp_XYZ center = myBaseP; + std::list::iterator nIt = newNodes.begin(); + size_t iN = 0; + for ( beginStepIter( makeMediumNodes ); moreSteps() && ( iN < nbScales ); ++nIt, ++iN ) + { + center += myDir.XYZ() * nextStep(); + + iSc += int( makeMediumNodes ); + ScaleIt& scale = scales[ iSc % 2 ]; + + gp_XYZ xyz = SMESH_TNodeXYZ( *nIt ); + xyz = ( *scale * ( xyz - center )) + center; + mesh->MoveNode( *nIt, xyz.X(), xyz.Y(), xyz.Z() ); + + ++scale; + } + } return nbNodes; } @@ -5811,7 +5906,7 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet theElems[2], const int theFlags, const double theTolerance) { - ExtrusParam aParams( theStep, theNbSteps, theFlags, theTolerance ); + ExtrusParam aParams( theStep, theNbSteps, std::list(), 0, theFlags, theTolerance ); return ExtrusionSweep( theElems, aParams, newElemsMap ); } @@ -5832,16 +5927,12 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet theElemSets[2], // source elements for each generated one SMESH_SequenceOfElemPtr srcElems, srcNodes; - //SMESHDS_Mesh* aMesh = GetMeshDS(); - setElemsFirst( theElemSets ); const int nbSteps = theParams.NbSteps(); - theParams.SetElementsToUse( theElemSets[0] ); + theParams.SetElementsToUse( theElemSets[0], theElemSets[1] ); - TNodeOfNodeListMap mapNewNodes; - //TNodeOfNodeVecMap mapNewNodes; + TNodeOfNodeListMap mapNewNodes; TElemOfVecOfNnlmiMap mapElemNewNodes; - //TElemOfVecOfMapNodesMap mapElemNewNodes; const bool isQuadraticMesh = bool( myMesh->NbEdges(ORDER_QUADRATIC) + myMesh->NbFaces(ORDER_QUADRATIC) + @@ -6656,24 +6747,23 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet theElemSets //======================================================================= //function : LinearAngleVariation -//purpose : auxilary for ExtrusionAlongTrack +//purpose : spread values over nbSteps //======================================================================= -void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps, + +void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps, list& Angles) { int nbAngles = Angles.size(); - if( nbSteps > nbAngles ) { + if( nbSteps > nbAngles && nbAngles > 0 ) + { vector theAngles(nbAngles); - list::iterator it = Angles.begin(); - int i = -1; - for(; it!=Angles.end(); it++) { - i++; - theAngles[i] = (*it); - } + theAngles.assign( Angles.begin(), Angles.end() ); + list res; double rAn2St = double( nbAngles ) / double( nbSteps ); double angPrev = 0, angle; - for ( int iSt = 0; iSt < nbSteps; ++iSt ) { + for ( int iSt = 0; iSt < nbSteps; ++iSt ) + { double angCur = rAn2St * ( iSt+1 ); double angCurFloor = floor( angCur ); double angPrevFloor = floor( angPrev ); @@ -6695,10 +6785,7 @@ void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps, res.push_back(angle); angPrev = angCur; } - Angles.clear(); - it = res.begin(); - for(; it!=res.end(); it++) - Angles.push_back( *it ); + Angles.swap( res ); } } diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index 4e9d0220d..5dd53807a 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -293,21 +293,26 @@ public: * else step size is measured along average normal of any element * USE_INPUT_ELEMS_ONLY: to use only input elements to compute extrusion direction * for ExtrusionByNormal() + * SCALE_LINEAR_VARIATION: to make linear variation of scale factors */ enum ExtrusionFlags { EXTRUSION_FLAG_BOUNDARY = 0x01, EXTRUSION_FLAG_SEW = 0x02, EXTRUSION_FLAG_GROUPS = 0x04, EXTRUSION_FLAG_BY_AVG_NORMAL = 0x08, - EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY = 0x10 + EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY = 0x10, + EXTRUSION_FLAG_SCALE_LINEAR_VARIATION = 0x20 }; /*! * Generator of nodes for extrusion functionality */ - class SMESH_EXPORT ExtrusParam { + class SMESH_EXPORT ExtrusParam + { gp_Dir myDir; // direction of extrusion Handle(TColStd_HSequenceOfReal) mySteps; // magnitudes for each step + std::vector myScales, myMediumScales;// scale factors + gp_XYZ myBaseP; // scaling center SMESH_SequenceOfNode myNodes; // nodes for using in sewing int myFlags; // see ExtrusionFlags double myTolerance; // tolerance for sewing nodes @@ -319,29 +324,33 @@ public: const bool makeMediumNodes); public: - ExtrusParam( const gp_Vec& theStep, - const int theNbSteps, - const int theFlags = 0, - const double theTolerance = 1e-6); + ExtrusParam( const gp_Vec& theStep, + const int theNbSteps, + const std::list& theScales, + const gp_XYZ* theBaseP, + const int theFlags = 0, + const double theTolerance = 1e-6); ExtrusParam( const gp_Dir& theDir, Handle(TColStd_HSequenceOfReal) theSteps, const int theFlags = 0, const double theTolerance = 1e-6); - ExtrusParam( const double theStep, - const int theNbSteps, - const int theFlags, - const int theDim); // for extrusion by normal + ExtrusParam( const double theStep, + const int theNbSteps, + const int theFlags, + const int theDim); // for extrusion by normal SMESH_SequenceOfNode& ChangeNodes() { return myNodes; } int& Flags() { return myFlags; } bool ToMakeBoundary() const { return myFlags & EXTRUSION_FLAG_BOUNDARY; } bool ToMakeGroups() const { return myFlags & EXTRUSION_FLAG_GROUPS; } bool ToUseInpElemsOnly() const { return myFlags & EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY; } + bool IsLinearVariation() const { return myFlags & EXTRUSION_FLAG_SCALE_LINEAR_VARIATION; } int NbSteps() const { return mySteps->Length(); } // stores elements to use for extrusion by normal, depending on - // state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag - void SetElementsToUse( const TIDSortedElemSet& elems ); + // state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag; + // define myBaseP for scaling + void SetElementsToUse( const TIDSortedElemSet& elems, const TIDSortedElemSet& nodes ); // creates nodes and returns number of nodes added in \a newNodes int MakeNodes( SMESHDS_Mesh* mesh, @@ -784,8 +793,8 @@ public: const bool theHasRefPoint, const gp_Pnt& theRefPoint, const bool theMakeGroups); - void LinearAngleVariation(const int NbSteps, - std::list& theAngles); + static void LinearAngleVariation(const int NbSteps, + std::list& theAngles); bool doubleNodes( SMESHDS_Mesh* theMeshDS, const TIDSortedElemSet& theElems, diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx index af09f482c..6f944e520 100644 --- a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx @@ -28,58 +28,59 @@ #include "SMESHGUI_ExtrusionDlg.h" #include "SMESHGUI.h" -#include "SMESHGUI_Utils.h" -#include "SMESHGUI_VTKUtils.h" -#include "SMESHGUI_MeshUtils.h" -#include "SMESHGUI_SpinBox.h" -#include "SMESHGUI_IdValidator.h" #include "SMESHGUI_FilterDlg.h" +#include "SMESHGUI_IdValidator.h" #include "SMESHGUI_MeshEditPreview.h" - +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_SpinBox.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include +#include #include -#include #include - -#include +#include // SALOME GUI includes -#include +#include +#include #include #include -#include #include - -#include -#include - +#include +#include #include #include - #include // OCCT includes -#include +#include #include +#include +#include #include // Qt includes #include #include +#include +#include #include +#include +#include #include #include +#include #include #include -#include -#include +#include #include -#include -#include // IDL includes #include #include CORBA_SERVER_HEADER(SMESH_Group) #include CORBA_SERVER_HEADER(SMESH_MeshEditor) +#include #define SPACING 6 #define MARGIN 11 @@ -595,7 +596,10 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) : SMESHGUI_PreviewDlg( theModule ), mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ) { - QPixmap image (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT"))); + SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI ); + QPixmap selectImage ( mgr->loadPixmap("SMESH", tr("ICON_SELECT"))); + QPixmap addImage ( mgr->loadPixmap("SMESH", tr("ICON_APPEND"))); + QPixmap removeImage ( mgr->loadPixmap("SMESH", tr("ICON_REMOVE"))); setModal( false ); setAttribute( Qt::WA_DeleteOnClose, true ); @@ -638,8 +642,8 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) TextLabelVector = new QLabel(tr("SMESH_VECTOR"), GroupArguments); - SelectVectorButton = new QPushButton(GroupArguments); - SelectVectorButton->setIcon(image); + SelectVectorButton = new QPushButton( GroupArguments ); + SelectVectorButton->setIcon( selectImage ); SelectVectorButton->setCheckable( true ); SelectorWdg->GetButtonGroup()->addButton( SelectVectorButton ); @@ -671,6 +675,66 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) //Preview check box myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments); + // Base point + + BasePointGrp = new QGroupBox(tr("BASE_POINT"), GroupArguments); + BasePointGrp->setCheckable(true); + BasePointGrp->setChecked(false); + QHBoxLayout* BasePointGrpLayout = new QHBoxLayout(BasePointGrp); + BasePointGrpLayout->setSpacing(SPACING); BasePointGrpLayout->setMargin(MARGIN); + + SelectBasePointButton = new QPushButton(BasePointGrp); + SelectBasePointButton->setIcon(selectImage); + SelectBasePointButton->setCheckable(true); + SelectorWdg->GetButtonGroup()->addButton( SelectBasePointButton ); + + QLabel* XLab = new QLabel(tr("SMESH_X"), BasePointGrp); + BasePoint_XSpin = new SMESHGUI_SpinBox(BasePointGrp); + BasePoint_XSpin->SetValue(0.); + QLabel* YLab = new QLabel(tr("SMESH_Y"), BasePointGrp); + BasePoint_YSpin = new SMESHGUI_SpinBox(BasePointGrp); + BasePoint_YSpin->SetValue(0.); + QLabel* ZLab = new QLabel(tr("SMESH_Z"), BasePointGrp); + BasePoint_ZSpin = new SMESHGUI_SpinBox(BasePointGrp); + BasePoint_ZSpin->SetValue(0.); + + BasePointGrpLayout->addWidget(SelectBasePointButton); + BasePointGrpLayout->addWidget(XLab); + BasePointGrpLayout->addWidget(BasePoint_XSpin, 1); + BasePointGrpLayout->addWidget(YLab); + BasePointGrpLayout->addWidget(BasePoint_YSpin, 1); + BasePointGrpLayout->addWidget(ZLab); + BasePointGrpLayout->addWidget(BasePoint_ZSpin, 1); + + // Scales + + ScalesGrp = new QGroupBox(tr("SMESH_SCALES"), GroupArguments); + QGridLayout* ScalesGrpLayout = new QGridLayout( ScalesGrp ); + ScalesGrpLayout->setSpacing(SPACING); ScalesGrpLayout->setMargin(MARGIN); + + ScalesList = new QListWidget( ScalesGrp ); + ScalesList->setSelectionMode(QListWidget::ExtendedSelection); + + AddScaleButton = new QToolButton( ScalesGrp ); + AddScaleButton->setIcon( addImage ); + + RemoveScaleButton = new QToolButton( ScalesGrp ); + RemoveScaleButton->setIcon( removeImage ); + + ScaleSpin = new SMESHGUI_SpinBox( ScalesGrp ); + ScaleSpin->SetValue(2); + + LinearScalesCheck = new QCheckBox(tr("LINEAR_SCALES"), ScalesGrp ); + + ScalesGrpLayout->addWidget(ScalesList, 0, 0, 4, 1); + ScalesGrpLayout->addWidget(AddScaleButton, 0, 1); + ScalesGrpLayout->addWidget(RemoveScaleButton, 2, 1); + ScalesGrpLayout->addWidget(ScaleSpin, 0, 2); + ScalesGrpLayout->addWidget(LinearScalesCheck, 4, 0); + ScalesGrpLayout->setRowMinimumHeight(1, 10); + ScalesGrpLayout->setRowStretch(3, 10); + + // layouting GroupArgumentsLayout->addWidget(SelectorWdg, 0, 0, 1, 9); GroupArgumentsLayout->addWidget(ExtrMethod_RBut0, 1, 0, 1, 3); GroupArgumentsLayout->addWidget(ExtrMethod_RBut1, 1, 3, 1, 3); @@ -696,8 +760,10 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) GroupArgumentsLayout->addWidget(SpinBox_NbSteps, 5, 3); GroupArgumentsLayout->addWidget(ByAverageNormalCheck, 6, 0, 1, 4); GroupArgumentsLayout->addWidget(UseInputElemsOnlyCheck, 6, 4, 1, 4); - GroupArgumentsLayout->addWidget(myPreviewCheckBox, 7, 0, 1, 8); - GroupArgumentsLayout->addWidget(MakeGroupsCheck, 8, 0, 1, 8); + GroupArgumentsLayout->addWidget(BasePointGrp, 7, 0, 1, 9); + GroupArgumentsLayout->addWidget(ScalesGrp, 8, 0, 1, 9); + GroupArgumentsLayout->addWidget(myPreviewCheckBox, 9, 0, 1, 8); + GroupArgumentsLayout->addWidget(MakeGroupsCheck, 10,0, 1, 8); GroupArgumentsLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 10, 0); /***************************************************************/ @@ -740,6 +806,11 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) SpinBox_NbSteps->setRange(1, 999999); SpinBox_VDist->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + BasePoint_XSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + BasePoint_YSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + BasePoint_ZSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + ScaleSpin->RangeStepAndValidator (COORD_MIN, COORD_MAX, 1.0, "length_precision"); + ExtrMethod_RBut0->setChecked(true); UseInputElemsOnlyCheck->setChecked(true); MakeGroupsCheck->setChecked(true); @@ -771,7 +842,13 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) connect(SpinBox_Dy, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable())); connect(SpinBox_Dz, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable())); + connect(AddScaleButton, SIGNAL(clicked()), this, SLOT(OnScaleAdded())); + connect(RemoveScaleButton, SIGNAL(clicked()), this, SLOT(OnScaleRemoved())); + connect(SelectVectorButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(SelectBasePointButton,SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); + connect(BasePointGrp, SIGNAL(toggled(bool)), this, SLOT(SetEditCurrentArgument())); + connect(BasePointGrp, SIGNAL(toggled(bool)), SelectBasePointButton, SLOT(click())); connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog())); connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(toDisplaySimulation())); connect(SelectorWdg, SIGNAL(selectionChanged()), this, SLOT(toDisplaySimulation())); @@ -791,6 +868,13 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) connect(SpinBox_NbSteps, SIGNAL(valueChanged(int)), this, SLOT(toDisplaySimulation())); connect(ByAverageNormalCheck, SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation())); connect(UseInputElemsOnlyCheck, SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation())); + connect(AddScaleButton, SIGNAL(clicked()), this, SLOT(toDisplaySimulation())); + connect(RemoveScaleButton, SIGNAL(clicked()), this, SLOT(toDisplaySimulation())); + connect(LinearScalesCheck, SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation())); + connect(BasePointGrp, SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation())); + connect(BasePoint_XSpin, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(BasePoint_YSpin, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(BasePoint_ZSpin, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); //To Connect preview check box connectPreviewControl(); @@ -875,6 +959,31 @@ bool SMESHGUI_ExtrusionDlg::isValuesValid() return aModule > 1.0E-38; } +//======================================================================= +//function : getScaleParams +//purpose : return 3 scaling parameters +//======================================================================= + +bool SMESHGUI_ExtrusionDlg::getScaleParams( SMESH::double_array*& scales, + SMESH::double_array*& basePoint ) +{ + scales = new SMESH::double_array; + scales->length( myScalesList.count() ); + for ( int i = 0; i < myScalesList.count(); ++i ) + (*scales)[i] = myScalesList[i]; + + basePoint = new SMESH::double_array; + if ( BasePointGrp->isChecked() ) + { + basePoint->length( 3 ); + (*basePoint)[0] = BasePoint_XSpin->GetValue(); + (*basePoint)[1] = BasePoint_YSpin->GetValue(); + (*basePoint)[2] = BasePoint_ZSpin->GetValue(); + } + + return ( scales->length() > 0 && LinearScalesCheck->isChecked() ); +} + //================================================================================= // function : ClickOnRadio() // purpose : Radio button management @@ -989,7 +1098,7 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply() { SMESH::DirStruct aVector; getExtrusionVector(aVector); - + QStringList aParameters; if ( ExtrMethod_RBut0->isChecked() ) { @@ -1011,14 +1120,22 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply() } long aNbSteps = (long)SpinBox_NbSteps->value(); - aParameters << SpinBox_NbSteps->text(); + SMESH::double_array_var scales = new SMESH::double_array; + scales->length( myScalesList.count() ); + for (int i = 0; i < myScalesList.count(); i++) + { + scales[i] = myScalesList[i]; + aParameters << ScalesList->item(i)->text(); + } + bool meshHadNewTypeBefore = true; int maxSelType = 0; const bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ); - try { + try + { SUIT_OverrideCursor aWaitCursor; SMESH::SMESH_Mesh_var mesh = SelectorWdg->GetMesh(); @@ -1054,8 +1171,12 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply() } else { + SMESH::double_array_var scales, basePoint; + bool linVariation = getScaleParams( scales.out(), basePoint.out() ); groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces, - aVector, aNbSteps, makeGroups ); + aVector, aNbSteps, + scales, linVariation, basePoint, + makeGroups ); } } catch (...) { @@ -1180,13 +1301,13 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument() if (!GroupButtons->isEnabled()) return; + SALOME_ListIO aList; + mySelectionMgr->selectedObjects(aList); + if ( aList.IsEmpty() || aList.Extent() > 1 ) + return; + if ( SelectVectorButton->isChecked() ) { - SALOME_ListIO aList; - mySelectionMgr->selectedObjects(aList); - if ( aList.IsEmpty() || aList.Extent() > 1 ) - return; - Handle(SALOME_InteractiveObject) IO = aList.First(); TColStd_IndexedMapOfInteger aMapIndex; mySelector->GetIndex(IO,aMapIndex); @@ -1207,6 +1328,56 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument() SpinBox_Vy->SetValue(aNormale.Y()); SpinBox_Vz->SetValue(aNormale.Z()); } + else if ( SelectBasePointButton->isChecked() ) + { + if (!BasePointGrp->isChecked()) + return; + + // try to get shape from selection + Handle(SALOME_InteractiveObject) IO = aList.First(); + + // check if geom vertex is selected + GEOM::GEOM_Object_var aGeomObj = SMESH::IObjectToInterface(IO); + TopoDS_Vertex aVertex; + if (!aGeomObj->_is_nil()) { + if (aGeomObj->IsShape() && GEOMBase::GetShape(aGeomObj, aVertex) && !aVertex.IsNull()) { + gp_Pnt aPnt = BRep_Tool::Pnt(aVertex); + BasePoint_XSpin->SetValue(aPnt.X()); + BasePoint_YSpin->SetValue(aPnt.Y()); + BasePoint_ZSpin->SetValue(aPnt.Z()); + } + } + + if ( aVertex.IsNull() ) + { + // check if smesh node is selected + SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(IO); + if (aMesh->_is_nil()) + return; + + QString aString; + int aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString); + // return if more than one node is selected + if (aNbUnits != 1) + return; + + SMESH_Actor* aMeshActor = SMESH::FindActorByObject(aMesh); + if (!aMeshActor) + return; + + SMDS_Mesh* mesh = aMeshActor->GetObject()->GetMesh(); + if (!mesh) + return; + + const SMDS_MeshNode* n = mesh->FindNode(aString.toLong()); + if (!n) + return; + + BasePoint_XSpin->SetValue(n->X()); + BasePoint_YSpin->SetValue(n->Y()); + BasePoint_ZSpin->SetValue(n->Z()); + } + } onDisplaySimulation(true); CheckIsEnable(); @@ -1229,6 +1400,21 @@ void SMESHGUI_ExtrusionDlg::SetEditCurrentArgument() if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->SetSelectionMode(FaceSelection); } + else if ( send == SelectBasePointButton ) + { + SMESH::SetPointRepresentation(true); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(NodeSelection); + + SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter(SMESH::IDSOURCE); + SMESH_NumberFilter* aVertexFilter = new SMESH_NumberFilter ("GEOM", TopAbs_VERTEX, + 1, TopAbs_VERTEX); + QList aListOfFilters; + aListOfFilters << aMeshOrSubMeshFilter << aVertexFilter; + + mySelectionMgr->installFilter(new SMESH_LogicalFilter + (aListOfFilters, SMESH_LogicalFilter::LO_OR, true)); + } connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); SelectionIntoArgument(); @@ -1316,6 +1502,12 @@ bool SMESHGUI_ExtrusionDlg::isValid() } ok = SpinBox_NbSteps->isValid( msg, true ) && ok; + if ( BasePointGrp->isChecked()) { + ok = BasePoint_XSpin->isValid( msg, true ) && ok; + ok = BasePoint_YSpin->isValid( msg, true ) && ok; + ok = BasePoint_ZSpin->isValid( msg, true ) && ok; + } + if( !ok ) { QString str( tr( "SMESH_INCORRECT_INPUT" ) ); if ( !msg.isEmpty() ) @@ -1369,8 +1561,12 @@ void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview ) } else { + SMESH::double_array_var scales, basePoint; + bool linVariation = getScaleParams( scales.out(), basePoint.out() ); groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces, - aVector, aNbSteps, makeGroups ); + aVector, aNbSteps, + scales, linVariation, basePoint, + makeGroups ); } SMESH::MeshPreviewStruct_var aMeshPreviewStruct = meshEditor->GetPreviewData(); mySimulation->SetData(aMeshPreviewStruct._retn()); @@ -1411,3 +1607,38 @@ void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector) aVector.PS.z = aNormale.Z()*aVDist; } } + +//======================================================================= +// function : OnScaleAdded() +// purpose : Called when user adds Scale to the list +//======================================================================= +void SMESHGUI_ExtrusionDlg::OnScaleAdded() +{ + QString msg; + if( !ScaleSpin->isValid( msg, true ) ) { + QString str( tr( "SMESH_INCORRECT_INPUT" ) ); + if ( !msg.isEmpty() ) + str += "\n" + msg; + SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str ); + return; + } + ScalesList->addItem(ScaleSpin->text()); + myScalesList.append(ScaleSpin->GetValue()); +} + +//======================================================================= +// function : OnScaleRemoved() +// purpose : Called when user removes Scale(s) from the list +//======================================================================= +void SMESHGUI_ExtrusionDlg::OnScaleRemoved() +{ + QList aList = ScalesList->selectedItems(); + QListWidgetItem* anItem; + int row = 0; + foreach(anItem, aList) { + row = ScalesList->row(anItem); + myScalesList.removeAt(row); + delete anItem; + } + ScalesList->setCurrentRow( row, QItemSelectionModel::Select ); +} diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.h b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.h index ed94f5c84..b86138e08 100644 --- a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.h +++ b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.h @@ -41,12 +41,14 @@ #include CORBA_SERVER_HEADER(SMESH_MeshEditor) class QButtonGroup; -class QRadioButton; +class QCheckBox; class QGroupBox; class QLabel; class QLineEdit; -class QCheckBox; +class QListWidget; class QPushButton; +class QRadioButton; +class QToolButton; class SMESHGUI; class SMESH_Actor; @@ -59,7 +61,7 @@ class SUIT_SelectionFilter; class SalomeApp_IntSpinBox; //================================================================================= -// class : SMESHGUI_ExtrusionDlg +// class : SMESHGUI_3TypesSelector // purpose : A widget used to select both nodes, edges and faces for // Extrusion and Revolution operations //================================================================================= @@ -143,12 +145,15 @@ private: void getExtrusionVector(SMESH::DirStruct& aVector); void extrusionByNormal(SMESH::SMESH_MeshEditor_ptr meshEditor, const bool makeGroups=false); + bool getScaleParams( SMESH::double_array*& scales, + SMESH::double_array*& basePoint ); bool isValid(); bool isValuesValid(); LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ SVTK_Selector* mySelector; + QList myScalesList; // widgets SMESHGUI_3TypesSelector* SelectorWdg; @@ -180,6 +185,18 @@ private: QCheckBox* UseInputElemsOnlyCheck; QCheckBox* MakeGroupsCheck; + QCheckBox* LinearScalesCheck; + QGroupBox* ScalesGrp; + QListWidget* ScalesList; + QToolButton* AddScaleButton; + QToolButton* RemoveScaleButton; + SMESHGUI_SpinBox* ScaleSpin; + QGroupBox* BasePointGrp; + QPushButton* SelectBasePointButton; + SMESHGUI_SpinBox* BasePoint_XSpin; + SMESHGUI_SpinBox* BasePoint_YSpin; + SMESHGUI_SpinBox* BasePoint_ZSpin; + QGroupBox* GroupButtons; QPushButton* buttonOk; QPushButton* buttonCancel; @@ -205,6 +222,8 @@ private slots: void ActivateThisDialog(); void onOpenView(); void onCloseView(); + void OnScaleAdded(); + void OnScaleRemoved(); }; diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index a235b9cc9..6f6d0c605 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -5267,6 +5267,18 @@ Please select a group and try again USE_INPUT_ELEMS_ONLY Use only input elements + + SMESH_SCALES + Scale Factors + + + LINEAR_SCALES + Linear Variation of Scale Factors + + + BASE_POINT + Scaling Center + SMESHGUI_FilterDlg diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index cecee4596..f9fb06334 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -2484,6 +2484,7 @@ namespace MeshEditor_I bool myIsExtrusionByNormal; static int makeFlags( CORBA::Boolean MakeGroups, + CORBA::Boolean LinearVariation = false, CORBA::Boolean ByAverageNormal = false, CORBA::Boolean UseInputElemsOnly = false, CORBA::Long Flags = 0, @@ -2492,18 +2493,24 @@ namespace MeshEditor_I if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS; if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL; if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY; + if ( LinearVariation ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_SCALE_LINEAR_VARIATION; if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY; return Flags; } // standard params - ExtrusionParams(const SMESH::DirStruct & theDir, - CORBA::Long theNbOfSteps, - CORBA::Boolean theMakeGroups): + ExtrusionParams(const SMESH::DirStruct & theDir, + CORBA::Long theNbOfSteps, + const SMESH::double_array & theScaleFactors, + CORBA::Boolean theLinearVariation, + const SMESH::double_array & theBasePoint, + CORBA::Boolean theMakeGroups): ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x, theDir.PS.y, theDir.PS.z ), theNbOfSteps, - makeFlags( theMakeGroups )), + toList( theScaleFactors ), + TBasePoint( theBasePoint ), + makeFlags( theMakeGroups, theLinearVariation )), myIsExtrusionByNormal( false ) { } @@ -2517,7 +2524,9 @@ namespace MeshEditor_I theDir.PS.y, theDir.PS.z ), theNbOfSteps, - makeFlags( theMakeGroups, false, false, + std::list(), + 0, + makeFlags( theMakeGroups, false, false, false, theExtrFlags, false ), theSewTolerance ), myIsExtrusionByNormal( false ) @@ -2532,7 +2541,7 @@ namespace MeshEditor_I CORBA::Boolean theMakeGroups ): ::SMESH_MeshEditor::ExtrusParam ( theStepSize, theNbOfSteps, - makeFlags( theMakeGroups, + makeFlags( theMakeGroups, false, theByAverageNormal, theUseInputElemsOnly ), theDim), myIsExtrusionByNormal( true ) @@ -2543,6 +2552,32 @@ namespace MeshEditor_I { Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS); } + + private: + + static std::list toList( const SMESH::double_array & theScaleFactors ) + { + std::list scales; + for ( CORBA::ULong i = 0; i < theScaleFactors.length(); ++i ) + scales.push_back( theScaleFactors[i] ); + return scales; + } + + // structure used to convert SMESH::double_array to gp_XYZ* + struct TBasePoint + { + gp_XYZ *pp, p; + TBasePoint( const SMESH::double_array & theBasePoint ) + { + pp = 0; + if ( theBasePoint.length() == 3 ) + { + p.SetCoord( theBasePoint[0], theBasePoint[1], theBasePoint[2] ); + pp = &p; + } + } + operator const gp_XYZ*() const { return pp; } + }; }; } @@ -2566,13 +2601,17 @@ SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNode const SMESH::ListOfIDSources & theFaces, const SMESH::DirStruct & theStepVector, CORBA::Long theNbOfSteps, + const SMESH::double_array & theScaleFactors, + CORBA::Boolean theLinearVariation, + const SMESH::double_array & theBasePoint, CORBA::Boolean theToMakeGroups) throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); - ExtrusionParams params( theStepVector, theNbOfSteps, theToMakeGroups ); + ExtrusionParams params( theStepVector, theNbOfSteps, theScaleFactors, + theLinearVariation, theBasePoint, theToMakeGroups ); TIDSortedElemSet elemsNodes[2]; for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) { @@ -2916,13 +2955,13 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & the << thePathShape << ", " << theNodeStart << ", " << theHasAngles << ", " - << theAngles << ", " + << TVar( theAngles ) << ", " << theLinearVariation << ", " << theHasRefPoint << ", " << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ), " + << TVar( theHasRefPoint ? theRefPoint.x : 0 ) << ", " + << TVar( theHasRefPoint ? theRefPoint.y : 0 ) << ", " + << TVar( theHasRefPoint ? theRefPoint.z : 0 ) << " ), " << theMakeGroups << " )"; } else diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index c3b0a4286..ab953091e 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -330,6 +330,9 @@ public: const SMESH::ListOfIDSources & faces, const SMESH::DirStruct & stepVector, CORBA::Long nbOfSteps, + const SMESH::double_array & theScaleFactors, + CORBA::Boolean theLinearVariation, + const SMESH::double_array & theBasePoint, CORBA::Boolean toMakeGroups) throw (SALOME::SALOME_Exception); diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index f56f9551c..b4da6ea8e 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -3820,17 +3820,27 @@ class Mesh: NbOfSteps, Tolerance, MakeGroups, TotalAngle) ## Generates new elements by extrusion of the given elements and nodes - # @param nodes - nodes to extrude: a list including ids, groups, sub-meshes or a mesh - # @param edges - edges to extrude: a list including ids, groups, sub-meshes or a mesh - # @param faces - faces to extrude: a list including ids, groups, sub-meshes or a mesh + # @param nodes nodes to extrude: a list including ids, groups, sub-meshes or a mesh + # @param edges edges to extrude: a list including ids, groups, sub-meshes or a mesh + # @param faces faces to extrude: a list including ids, groups, sub-meshes or a mesh # @param StepVector vector or DirStruct or 3 vector components, defining # the direction and value of extrusion for one step (the total extrusion # length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param MakeGroups forces the generation of new groups from existing ones + # @param scaleFactors optional scale factors to apply during extrusion + # @param linearVariation if @c True, scaleFactors are spread over all @a scaleFactors, + # else scaleFactors[i] is applied to nodes at the i-th extrusion step + # @param basePoint optional scaling center; if not provided, a gravity center of + # nodes and elements being extruded is used as the scaling center. + # It can be either + # - a list of tree components of the point or + # - a node ID or + # - a GEOM point # @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise # @ingroup l2_modif_extrurev - def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False): + def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False, + scaleFactors=[], linearVariation=False, basePoint=[] ): unRegister = genObjUnRegister() nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister ) edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister ) @@ -3841,12 +3851,22 @@ class Mesh: if isinstance( StepVector, list ): StepVector = self.smeshpyD.MakeDirStruct(*StepVector) + if isinstance( basePoint, int): + xyz = self.GetNodeXYZ( basePoint ) + if not xyz: + raise RuntimeError, "Invalid node ID: %s" % basePoint + basePoint = xyz + if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ): + basePoint = self.geompyD.PointCoordinates( basePoint ) + NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps) Parameters = StepVector.PS.parameters + var_separator + Parameters self.mesh.SetParameters(Parameters) return self.editor.ExtrusionSweepObjects( nodes, edges, faces, - StepVector, NbOfSteps, MakeGroups) + StepVector, NbOfSteps, + scaleFactors, linearVariation, basePoint, + MakeGroups) ## Generates new elements by extrusion of the elements with given ids diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx index 4f2329d59..9de37716a 100644 --- a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx @@ -732,13 +732,13 @@ protected: void StdMeshers_RadialQuadrangle_1D2D::SubmeshRestored(SMESH_subMesh* faceSubMesh) { - // if ( !faceSubMesh->IsEmpty() ) - // { - // for ( TopExp_Explorer e( faceSubMesh->GetSubShape(), TopAbs_EDGE ); e.More(); e.Next() ) - // { - // markEdgeAsComputedByMe( TopoDS::Edge( e.Current() ), faceSubMesh ); - // } - // } + if ( !faceSubMesh->IsEmpty() ) + { + for ( TopExp_Explorer e( faceSubMesh->GetSubShape(), TopAbs_EDGE ); e.More(); e.Next() ) + { + markEdgeAsComputedByMe( TopoDS::Edge( e.Current() ), faceSubMesh ); + } + } } //======================================================================= @@ -762,12 +762,12 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, "of edges is less or equal to 3 and one of them is an ellipse curve)"); // get not yet computed EDGEs - // list< TopoDS_Edge > emptyEdges; - // for ( TopExp_Explorer e( aShape, TopAbs_EDGE ); e.More(); e.Next() ) - // { - // if ( aMesh.GetSubMesh( e.Current() )->IsEmpty() ) - // emptyEdges.push_back( TopoDS::Edge( e.Current() )); - // } + list< TopoDS_Edge > emptyEdges; + for ( TopExp_Explorer e( aShape, TopAbs_EDGE ); e.More(); e.Next() ) + { + if ( aMesh.GetSubMesh( e.Current() )->IsEmpty() ) + emptyEdges.push_back( TopoDS::Edge( e.Current() )); + } TNodeDistributor* algo1d = TNodeDistributor::GetDistributor(aMesh); @@ -941,9 +941,9 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, centerUV = nodes2.back().UV(); } - // list< TopoDS_Edge >::iterator ee = emptyEdges.begin(); - // for ( ; ee != emptyEdges.end(); ++ee ) - // markEdgeAsComputedByMe( *ee, aMesh.GetSubMesh( F )); + list< TopoDS_Edge >::iterator ee = emptyEdges.begin(); + for ( ; ee != emptyEdges.end(); ++ee ) + markEdgeAsComputedByMe( *ee, aMesh.GetSubMesh( F )); circSide->GetUVPtStruct(); // let sides take into account just computed nodes linSide1->GetUVPtStruct(); -- 2.39.2