</ul>
<li>Specify the <b>Number of steps</b>.</li>
+
+ <li>Optionally specify <b>Scale Factors</b>. Each scale factor in
+ the list is applied to nodes of a corresponding extrusion step
+ unless <b>Linear Variation of Scale Factors</b> is checked, is
+ which case the scale factors are spread over all extrusion steps.</li>
+ <ul>
+ <li><b>Scaling Center</b> 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.</li>
+ <li>\b Add button adds a scale factor to the list.
+ \image html add.png
+ <center><em>"Add" button</em></center>
+ </li>
+ <li>\b Remove button removes selected scale factors from the list.
+ \image html remove.png
+ <center><em>"Remove" button</em></center>
+ </li>
+ </ul>
+
<li>If you activate <b>Generate Groups</b> check-box, the <em>result elements</em>
created from <em>selected elements</em> contained in groups will be
included into new groups named by pattern "<old group
in ListOfIDSources faces,
in DirStruct stepVector,
in long nbOfSteps,
+ in double_array scaleFactors,
+ in boolean linearVariation,
+ in double_array basePoint,
in boolean toMakeGroups)
raises (SALOME::SALOME_Exception);
//purpose : standard construction
//=======================================================================
-SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec& theStep,
- const int theNbSteps,
- const int theFlags,
- const double theTolerance):
+SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec& theStep,
+ const int theNbSteps,
+ const std::list<double>& theScales,
+ const gp_XYZ* theBasePoint,
+ const int theFlags,
+ const double theTolerance):
myDir( theStep ),
+ myBaseP( Precision::Infinite(), 0, 0 ),
myFlags( theFlags ),
myTolerance( theTolerance ),
myElemsToUse( NULL )
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<double>::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 ))
{
//=======================================================================
//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();
+ }
}
//=======================================================================
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<double>::iterator ScaleIt;
+ ScaleIt scales[] = { myScales.begin(), myMediumScales.begin() };
+
+ size_t iSc = 0, nbScales = myScales.size() + myMediumScales.size();
+
+ gp_XYZ center = myBaseP;
+ std::list<const SMDS_MeshNode*>::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;
}
const int theFlags,
const double theTolerance)
{
- ExtrusParam aParams( theStep, theNbSteps, theFlags, theTolerance );
+ ExtrusParam aParams( theStep, theNbSteps, std::list<double>(), 0, theFlags, theTolerance );
return ExtrusionSweep( theElems, aParams, newElemsMap );
}
// 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) +
//=======================================================================
//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<double>& Angles)
{
int nbAngles = Angles.size();
- if( nbSteps > nbAngles ) {
+ if( nbSteps > nbAngles && nbAngles > 0 )
+ {
vector<double> theAngles(nbAngles);
- list<double>::iterator it = Angles.begin();
- int i = -1;
- for(; it!=Angles.end(); it++) {
- i++;
- theAngles[i] = (*it);
- }
+ theAngles.assign( Angles.begin(), Angles.end() );
+
list<double> 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 );
res.push_back(angle);
angPrev = angCur;
}
- Angles.clear();
- it = res.begin();
- for(; it!=res.end(); it++)
- Angles.push_back( *it );
+ Angles.swap( res );
}
}
* 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<double> 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
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<double>& 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,
const bool theHasRefPoint,
const gp_Pnt& theRefPoint,
const bool theMakeGroups);
- void LinearAngleVariation(const int NbSteps,
- std::list<double>& theAngles);
+ static void LinearAngleVariation(const int NbSteps,
+ std::list<double>& theAngles);
bool doubleNodes( SMESHDS_Mesh* theMeshDS,
const TIDSortedElemSet& theElems,
#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 <GEOMBase.h>
+#include <SMDS_Mesh.hxx>
#include <SMESH_Actor.h>
-#include <SMESH_TypeFilter.hxx>
#include <SMESH_LogicalFilter.hxx>
-
-#include <SMDS_Mesh.hxx>
+#include <SMESH_TypeFilter.hxx>
// SALOME GUI includes
-#include <SUIT_ResourceMgr.h>
+#include <LightApp_Application.h>
+#include <LightApp_SelectionMgr.h>
#include <SUIT_Desktop.h>
#include <SUIT_MessageBox.h>
-#include <SUIT_Session.h>
#include <SUIT_OverrideCursor.h>
-
-#include <LightApp_Application.h>
-#include <LightApp_SelectionMgr.h>
-
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
#include <SVTK_ViewModel.h>
#include <SVTK_ViewWindow.h>
-
#include <SalomeApp_IntSpinBox.h>
// OCCT includes
-#include <TColStd_MapOfInteger.hxx>
+#include <BRep_Tool.hxx>
#include <TColStd_IndexedMapOfInteger.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TopoDS_Vertex.hxx>
#include <gp_XYZ.hxx>
// Qt includes
#include <QApplication>
#include <QButtonGroup>
+#include <QCheckBox>
+#include <QGridLayout>
#include <QGroupBox>
+#include <QHBoxLayout>
+#include <QKeyEvent>
#include <QLabel>
#include <QLineEdit>
+#include <QListWidget>
#include <QPushButton>
#include <QRadioButton>
-#include <QCheckBox>
-#include <QHBoxLayout>
+#include <QToolButton>
#include <QVBoxLayout>
-#include <QGridLayout>
-#include <QKeyEvent>
// IDL includes
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Group)
#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+#include <SMESH_NumberFilter.hxx>
#define SPACING 6
#define MARGIN 11
: 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 );
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 );
//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);
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);
/***************************************************************/
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);
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()));
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();
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
{
SMESH::DirStruct aVector;
getExtrusionVector(aVector);
-
+
QStringList aParameters;
if ( ExtrMethod_RBut0->isChecked() )
{
}
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();
}
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 (...) {
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);
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<GEOM::GEOM_Object>(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();
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<SUIT_SelectionFilter*> aListOfFilters;
+ aListOfFilters << aMeshOrSubMeshFilter << aVertexFilter;
+
+ mySelectionMgr->installFilter(new SMESH_LogicalFilter
+ (aListOfFilters, SMESH_LogicalFilter::LO_OR, true));
+ }
connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
SelectionIntoArgument();
}
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() )
}
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());
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<QListWidgetItem*> 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 );
+}
#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;
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
//=================================================================================
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<double> myScalesList;
// widgets
SMESHGUI_3TypesSelector* SelectorWdg;
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;
void ActivateThisDialog();
void onOpenView();
void onCloseView();
+ void OnScaleAdded();
+ void OnScaleRemoved();
};
<source>USE_INPUT_ELEMS_ONLY</source>
<translation>Use only input elements</translation>
</message>
+ <message>
+ <source>SMESH_SCALES</source>
+ <translation>Scale Factors</translation>
+ </message>
+ <message>
+ <source>LINEAR_SCALES</source>
+ <translation>Linear Variation of Scale Factors</translation>
+ </message>
+ <message>
+ <source>BASE_POINT</source>
+ <translation>Scaling Center</translation>
+ </message>
</context>
<context>
<name>SMESHGUI_FilterDlg</name>
bool myIsExtrusionByNormal;
static int makeFlags( CORBA::Boolean MakeGroups,
+ CORBA::Boolean LinearVariation = false,
CORBA::Boolean ByAverageNormal = false,
CORBA::Boolean UseInputElemsOnly = false,
CORBA::Long Flags = 0,
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 )
{
}
theDir.PS.y,
theDir.PS.z ),
theNbOfSteps,
- makeFlags( theMakeGroups, false, false,
+ std::list<double>(),
+ 0,
+ makeFlags( theMakeGroups, false, false, false,
theExtrFlags, false ),
theSewTolerance ),
myIsExtrusionByNormal( false )
CORBA::Boolean theMakeGroups ):
::SMESH_MeshEditor::ExtrusParam ( theStepSize,
theNbOfSteps,
- makeFlags( theMakeGroups,
+ makeFlags( theMakeGroups, false,
theByAverageNormal, theUseInputElemsOnly ),
theDim),
myIsExtrusionByNormal( true )
{
Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
}
+
+ private:
+
+ static std::list<double> toList( const SMESH::double_array & theScaleFactors )
+ {
+ std::list<double> 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; }
+ };
};
}
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 ) {
<< 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
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);
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 )
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
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 );
+ }
+ }
}
//=======================================================================
"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);
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();