<li>For meshing of 1D entities (<b>edges</b>):</li>
<ul>
-<li>Wire Discretization meshing algorithm - splits a wire into a
-number of mesh segments following any 1D hypothesis.</li>
-<li>Composite Side Discretization algorithm - allows to apply any 1D
+<li>Wire Discretization meshing algorithm - splits an edge into a
+number of mesh segments following an 1D hypothesis.</li>
+<li>Composite Side Discretization algorithm - allows to apply an 1D
hypothesis to a whole side of a geometrical face even if it is
composed of several edges provided that they form C1 curve, have the
same hypotheses assigned and form one side in all faces of the main
</center>
After the mesh computation finishes, the Mesh Computation information
-box appears. In case of a success, the box shows
-information on number of entities of different types in the mesh.
+box appears. If you close this box and click "Compute" button again,
+without previously changing hypotheses and/or algorithms, the mesh is
+NOT re-computed and the Mesh Computation information box with
+the same contents is shown. (To fully re-compute the mesh, invoke \ref
+clear_mesh_anchor "Clear Mesh Data" command before).
+
+In case of a success, the box shows information on number of entities
+of different types in the mesh.
\image html meshcomputationsucceed.png
\n Extrusion is used to build mesh elements of plus one
dimension than the input ones. Boundary elements around elements of
plus one dimension are additionally created. All created elements
-can be automatically grouped.
+can be automatically grouped. Extrusion can be used to create a
+\ref extrusion_struct "structured mesh from scratch".
+
+\image html extrusion_box.png "If you extruded e.g. several quadrangles, you get exactly same mesh as if you meshed a geometrical box (except that the initial quadrangles can be incorrectly oriented)"
+
<p>Any node, segment or 2D element can be extruded. Each type of
elements is extruded into a corresponding type of result elements:
<table>
<em>"Extrusion" button</em>
</center>
-The following dialog common for line and planar elements will appear:
+The following dialog common for node, segments and faces will appear:
\image html extrusionalongaline1.png
\image html extrusionalongaline2.png
+\image html extrusionalongaline3.png
+
</li>
<li>In this dialog:
<li>Specify the IDs of the elements which will be extruded by one
following means:
<ul>
- <li><b>Select the whole mesh, submesh or group</b> activating this
+ <li><b>Select the whole mesh, sub-mesh or group</b> activating this
checkbox.</li>
<li>Choose mesh elements with the mouse in the 3D Viewer. It is
possible to select a whole area with a mouse frame.</li>
the \ref filtering_elements "Selection filters" page.</li>
</ul>
</li>
- <li>If the <b>Extrude to Distance</b> radio button is selected</li>
+ <li>If the <b>Extrusion to Distance</b> radio button is selected</li>
<ul>
- <li>specify the distance at which the elements will be extruded.</li>
+ <li>specify the translation vector by which the elements will be extruded.</li>
</ul>
- <li>If the <b>Extrude Along Vector</b> radio button is selected</li>
+ <li>If the <b>Extrusion Along Vector</b> radio button is selected</li>
<ul>
- <li>specify the coordinates of the vector along which the elements
+ <li>specify the coordinates of the \b Vector along which the elements
will be extruded, or select the face (the normal to the face will
define the vector),</li>
- <li>specify the distance of extrusion along the vector.</li>
+ <li>specify the \b Distance of extrusion along the vector (it can
+ be negative).</li>
+ </ul>
+ <li>If the <b>Extrusion By Normal</b> radio button is selected,
+ which is visible in \b 2D mode only, every node of selected
+ elements is extruded along the \a average of the \a normal vectors to
+ the faces sharing the node.</li>
+ <ul>
+ <li>Specify the \b Distance of extrusion (it can be negative),</li>
+ <li>Use <b>Along average normal</b> check-box to specify along
+ what vector the distance is measured. If it is \a activated the
+ distance is measured along the average normal mentioned
+ above. If it is \a deactivated every node is extruded along the
+ average normal till its intersection with the virtual plane got
+ by translation of the face sharing the node along its own normal
+ by the distance. <br>
+ The picture below shows a cross-section of a 2D mesh extruded
+ with <b>Along average normal</b> activated (to the left) and
+ deactivated (to the right).
+
+ \image html extrusionbynormal_alongavgnorm.png
+ <p></li>
+ <li>Using <b>Use only input elements</b> check-box to specify what
+ elements to use to compute the average normal. If it is \a
+ activated only selected faces, among faces sharing the node,
+ are used to compute the average normal at the node. Else all
+ faces sharing the node are used. <br>
+ The picture below shows a cross-section of a 2D mesh the upper
+ plane of which is extruded with <b>Use only input elements</b>
+ activated (to the left) and deactivated (to the right).
+
+ \image html extrusionbynormal_useonly.png
+ <p></li>
</ul>
- <li>Specify the number of steps.</li>
+ <li>Specify the <b>Number of steps</b>.</li>
<li>If you activate <b>Generate Groups</b> check-box, the <em>result elements</em>
- created from <em>extruded elements</em> contained in groups will be
+ created from <em>selected elements</em> contained in groups will be
included into new groups named by pattern "<old group
- name>_extruded" and "<old group name>_top". For example if an
- extruded quadrangle is included in \a Group_1 group then result
- hexahedra will be included in \a Group_1_extruded group and a
- quadrangle created at the "top" of extruded mesh will
- be included in \a Group_1_top group. <br>This check-box is active
- only if there are some groups in the mesh.</li>
+ name>_extruded" and "<old group name>_top". For example if a
+ selected quadrangle is included in \a g_Faces group (see figures
+ below) then result hexahedra will be included in \a
+ g_Faces_extruded group and a quadrangle created at the "top" of
+ extruded mesh will be included in \a g_Faces_top group. <br>
+\image html extrusion_groups.png
+\image html extrusion_groups_res.png
+ <p> This check-box is active only if there are some groups in the mesh.
+ </li>
</ul>
<li>Click \b Apply or <b> Apply and Close</b> button to confirm the operation.</li>
</ol>
+\anchor extrusion_struct
+<h2>Example: creation of a structured mesh from scratch</h2>
-\image html image77.jpg "The mesh with an edge selected for extrusion"
+\image html image75.jpg "A node is extruded into a line of segments"
+<br>
+\image html image76.jpg "The line of segments is extruded into a quadrangle mesh"
+<br>
+\image html image77.jpg "The quadrangle mesh is revolved into a hexahedral mesh"
-\image html image76.jpg "The mesh with extruded edge"
<br><b>See Also</b> a sample TUI Script of an
\ref tui_extrusion "Extrusion" operation.
<li>\subpage split_to_tetra_page "Split" volumic elements into tetrahedra or prisms.</li>
<li>\subpage smoothing_page "Smooth" elements, reducung distortions in
them by adjusting the locations of element corners.</li>
-<li>Create an \subpage extrusion_page "extrusion" along a vector.</li>
+<li>Create an \subpage extrusion_page "extrusion" along a vector or by
+normal to a discretized surface.</li>
<li>Create an \subpage extrusion_along_path_page "extrusion along a path".</li>
<li>Create an edge or a surface by \subpage revolution_page "revolution"
of the selected node or edge.</li>
<li> if the mesh is computed on a geometry, then "Clear Mesh Data" removes
all elements and nodes.</li>
<li> if the mesh is not based on a geometry (imported, compound, created from
- scratch etc), then "Clear Mesh Data" removes only the elements and
+ scratch etc.), then "Clear Mesh Data" removes only the elements and
nodes computed by algorithms. If no such elements or nodes have been created, can remove nothing.</li></ul>
<br><b>See Also</b> a sample TUI Script of a
in DirStruct StepVector,
in long NbOfSteps)
raises (SALOME::SALOME_Exception);
+ ListOfGroups ExtrusionByNormal(in SMESH_IDSource theObject,
+ in double stepSize,
+ in long nbOfSteps,
+ in boolean byAverageNormal,
+ in boolean useInputElemsOnly,
+ in boolean makeGroups,
+ in short dim)
+ raises (SALOME::SALOME_Exception);
enum Extrusion_Error {
EXTR_OK,
*/
//================================================================================
-double Length2D::GetValue( long theElementId)
+double Length2D::GetValue( long theElementId )
{
TSequenceOfXYZ P;
double L1 = getDistance(P( 1 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 1 ));
- aVal = Max(L1,Max(L2,L3));
+ aVal = Min(L1,Min(L2,L3));
break;
}
else if (len == 4){ // quadrangles
double L2 = getDistance(P( 2 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 4 ));
double L4 = getDistance(P( 4 ),P( 1 ));
- aVal = Max(Max(L1,L2),Max(L3,L4));
+ aVal = Min(Min(L1,L2),Min(L3,L4));
break;
}
if (len == 6){ // quadratic triangles
double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 ));
- aVal = Max(L1,Max(L2,L3));
+ aVal = Min(L1,Min(L2,L3));
//cout<<"L1="<<L1<<" L2="<<L2<<"L3="<<L3<<" aVal="<<aVal<<endl;
break;
}
double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 ));
double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 ));
- aVal = Max(Max(L1,L2),Max(L3,L4));
+ aVal = Min(Min(L1,L2),Min(L3,L4));
break;
}
case SMDSAbs_Volume:
double L4 = getDistance(P( 1 ),P( 4 ));
double L5 = getDistance(P( 2 ),P( 4 ));
double L6 = getDistance(P( 3 ),P( 4 ));
- aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+ aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
break;
}
else if (len == 5){ // piramids
double L7 = getDistance(P( 3 ),P( 5 ));
double L8 = getDistance(P( 4 ),P( 5 ));
- aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
- aVal = Max(aVal,Max(L7,L8));
+ aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+ aVal = Min(aVal,Min(L7,L8));
break;
}
else if (len == 6){ // pentaidres
double L8 = getDistance(P( 2 ),P( 5 ));
double L9 = getDistance(P( 3 ),P( 6 ));
- aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
- aVal = Max(aVal,Max(Max(L7,L8),L9));
+ aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+ aVal = Min(aVal,Min(Min(L7,L8),L9));
break;
}
else if (len == 8){ // hexaider
double L11= getDistance(P( 3 ),P( 7 ));
double L12= getDistance(P( 4 ),P( 8 ));
- aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
- aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10)));
- aVal = Max(aVal,Max(L11,L12));
+ aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+ aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10)));
+ aVal = Min(aVal,Min(L11,L12));
break;
}
double L4 = getDistance(P( 1 ),P( 8 )) + getDistance(P( 8 ),P( 4 ));
double L5 = getDistance(P( 2 ),P( 9 )) + getDistance(P( 9 ),P( 4 ));
double L6 = getDistance(P( 3 ),P( 10 )) + getDistance(P( 10 ),P( 4 ));
- aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+ aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
break;
}
else if (len == 13){ // quadratic piramids
double L6 = getDistance(P( 2 ),P( 11 )) + getDistance(P( 11 ),P( 5 ));
double L7 = getDistance(P( 3 ),P( 12 )) + getDistance(P( 12 ),P( 5 ));
double L8 = getDistance(P( 4 ),P( 13 )) + getDistance(P( 13 ),P( 5 ));
- aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
- aVal = Max(aVal,Max(L7,L8));
+ aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+ aVal = Min(aVal,Min(L7,L8));
break;
}
else if (len == 15){ // quadratic pentaidres
double L7 = getDistance(P( 1 ),P( 13 )) + getDistance(P( 13 ),P( 4 ));
double L8 = getDistance(P( 2 ),P( 14 )) + getDistance(P( 14 ),P( 5 ));
double L9 = getDistance(P( 3 ),P( 15 )) + getDistance(P( 15 ),P( 6 ));
- aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
- aVal = Max(aVal,Max(Max(L7,L8),L9));
+ aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+ aVal = Min(aVal,Min(Min(L7,L8),L9));
break;
}
else if (len == 20){ // quadratic hexaider
double L10= getDistance(P( 2 ),P( 18 )) + getDistance(P( 18 ),P( 6 ));
double L11= getDistance(P( 3 ),P( 19 )) + getDistance(P( 19 ),P( 7 ));
double L12= getDistance(P( 4 ),P( 20 )) + getDistance(P( 20 ),P( 8 ));
- aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
- aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10)));
- aVal = Max(aVal,Max(L11,L12));
+ aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+ aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10)));
+ aVal = Min(aVal,Min(L11,L12));
break;
}
default: aVal=-1;
}
- if (aVal <0){
+ if (aVal < 0 ) {
return 0.;
}
double Length2D::GetBadRate( double Value, int /*nbNodes*/ ) const
{
- // meaningless as it is not quality control functor
+ // meaningless as it is not a quality control functor
return Value;
}
void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh)
{
- myMesh = theMesh;
+ myMeshModifTracer.SetMesh( theMesh );
+ if ( myMeshModifTracer.IsMeshModified())
+ {
+ size_t nbNodes = theMesh ? theMesh->NbNodes() : 0;
+ if ( myNodeIsChecked.size() == nbNodes )
+ {
+ std::fill( myNodeIsChecked.begin(), myNodeIsChecked.end(), false );
+ }
+ else
+ {
+ SMESHUtils::FreeVector( myNodeIsChecked );
+ SMESHUtils::FreeVector( myNodeIsOut );
+ myNodeIsChecked.resize( nbNodes, false );
+ myNodeIsOut.resize( nbNodes );
+ }
+ }
+}
+
+bool ElementsOnShape::getNodeIsOut( const SMDS_MeshNode* n, bool& isOut )
+{
+ if ( n->GetID() >= (int) myNodeIsChecked.size() ||
+ !myNodeIsChecked[ n->GetID() ])
+ return false;
+
+ isOut = myNodeIsOut[ n->GetID() ];
+ return true;
+}
+
+void ElementsOnShape::setNodeIsOut( const SMDS_MeshNode* n, bool isOut )
+{
+ if ( n->GetID() < (int) myNodeIsChecked.size() )
+ {
+ myNodeIsChecked[ n->GetID() ] = true;
+ myNodeIsOut [ n->GetID() ] = isOut;
+ }
}
void ElementsOnShape::SetShape (const TopoDS_Shape& theShape,
myType = theType;
myShape = theShape;
if ( myShape.IsNull() ) return;
-
+
TopTools_IndexedMapOfShape shapesMap;
TopAbs_ShapeEnum shapeTypes[4] = { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX };
TopExp_Explorer sub;
myClassifiers.resize( shapesMap.Extent() );
for ( int i = 0; i < shapesMap.Extent(); ++i )
myClassifiers[ i ] = new TClassifier( shapesMap( i+1 ), myToler );
+
+ if ( theType == SMDSAbs_Node )
+ {
+ SMESHUtils::FreeVector( myNodeIsChecked );
+ SMESHUtils::FreeVector( myNodeIsOut );
+ }
+ else
+ {
+ std::fill( myNodeIsChecked.begin(), myNodeIsChecked.end(), false );
+ }
}
void ElementsOnShape::clearClassifiers()
bool ElementsOnShape::IsSatisfy (long elemId)
{
+ const SMDS_Mesh* mesh = myMeshModifTracer.GetMesh();
const SMDS_MeshElement* elem =
- ( myType == SMDSAbs_Node ? myMesh->FindNode( elemId ) : myMesh->FindElement( elemId ));
+ ( myType == SMDSAbs_Node ? mesh->FindNode( elemId ) : mesh->FindElement( elemId ));
if ( !elem || myClassifiers.empty() )
return false;
for ( size_t i = 0; i < myClassifiers.size(); ++i )
{
SMDS_ElemIteratorPtr aNodeItr = elem->nodesIterator();
- bool isSatisfy = myAllNodesFlag;
+ bool isSatisfy = myAllNodesFlag, isNodeOut;
gp_XYZ centerXYZ (0, 0, 0);
while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
{
- SMESH_TNodeXYZ aPnt ( aNodeItr->next() );
- centerXYZ += aPnt;
- isSatisfy = ! myClassifiers[i]->IsOut( aPnt );
+ const SMDS_MeshNode* n = (const SMDS_MeshNode*) aNodeItr->next();
+ if ( !getNodeIsOut( n, isNodeOut ))
+ {
+ SMESH_TNodeXYZ aPnt( n );
+ centerXYZ += aPnt;
+ isNodeOut = myClassifiers[i]->IsOut( aPnt );
+ setNodeIsOut( n, isNodeOut );
+ }
+ isSatisfy = !isNodeOut;
}
// Check the center point for volumes MantisBug 0020168
double myTol;
};
void clearClassifiers();
+ bool getNodeIsOut( const SMDS_MeshNode* n, bool& isOut );
+ void setNodeIsOut( const SMDS_MeshNode* n, bool isOut );
std::vector< TClassifier* > myClassifiers;
- const SMDS_Mesh* myMesh;
SMDSAbs_ElementType myType;
TopoDS_Shape myShape;
double myToler;
bool myAllNodesFlag;
+ TMeshModifTracer myMeshModifTracer;
+ std::vector<bool> myNodeIsChecked;
+ std::vector<bool> myNodeIsOut;
};
typedef boost::shared_ptr<ElementsOnShape> ElementsOnShapePtr;
//=================================================================================
vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID )
{
- if (myLocalGrid)
- {
- TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
- return i == myVTK2SMDSNodes.end() ? -1 : i->second;
- }
- return this->GetMesh()->FindNodeVtk(theVTKID)->GetID();
+ if (myLocalGrid)
+ {
+ TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
+ return i == myVTK2SMDSNodes.end() ? -1 : i->second;
+ }
+ const SMDS_MeshNode* aNode = 0;
+ if( this->GetMesh() )
+ aNode = this->GetMesh()->FindNodeVtk( theVTKID );
+
+ return aNode ? aNode->GetID() : -1;
}
vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
{
- if (myLocalGrid)
- {
- TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID);
+ if (myLocalGrid)
+ {
+ TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID);
return i == mySMDS2VTKNodes.end() ? -1 : i->second;
- }
+ }
- const SMDS_MeshNode* aNode = 0;
- if( this->GetMesh() ) {
- aNode = this->GetMesh()->FindNode(theObjID);
- }
- return aNode ? aNode->getVtkId() : -1;
+ const SMDS_MeshNode* aNode = 0;
+ if( this->GetMesh() ) {
+ aNode = this->GetMesh()->FindNode(theObjID);
+ }
+ return aNode ? aNode->getVtkId() : -1;
}
vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
{
- if (myLocalGrid)
- {
- TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
- return i == myVTK2SMDSElems.end() ? -1 : i->second;
- }
+ if (myLocalGrid)
+ {
+ TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
+ return i == myVTK2SMDSElems.end() ? -1 : i->second;
+ }
return this->GetMesh()->fromVtkToSmds(theVTKID);
}
vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
{
- if (myLocalGrid)
- {
- TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID);
- return i == mySMDS2VTKElems.end() ? -1 : i->second;
- }
- return this->GetMesh()->FindElement(theObjID)->getVtkId();
- //return this->GetMesh()->fromSmdsToVtk(theObjID);
+ if (myLocalGrid)
+ {
+ TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID);
+ return i == mySMDS2VTKElems.end() ? -1 : i->second;
+ }
+
+ const SMDS_MeshElement* e = 0;
+ if ( this->GetMesh() )
+ e = this->GetMesh()->FindElement(theObjID);
+
+ return e ? e->getVtkId() : -1;
}
//=================================================================================
virtual int NbNodes() const;
virtual int NbEdges() const;
virtual int NbFaces() const;
- inline int GetID() const { return myID; };
+ inline int GetID() const { return myID; }
///Return the type of the current element
virtual SMDSAbs_ElementType GetType() const = 0;
bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theMesh,
const TopoDS_Edge& theEdge,
const bool ignoreMediumNodes,
- map< double, const SMDS_MeshNode* > & theNodes)
+ map< double, const SMDS_MeshNode* > & theNodes,
+ const SMDSAbs_ElementType typeToCheck)
{
theNodes.clear();
while ( nIt->more() )
{
const SMDS_MeshNode* node = nIt->next();
- if ( ignoreMediumNodes ) {
- SMDS_ElemIteratorPtr elemIt = node->GetInverseElementIterator();
- if ( elemIt->more() && elemIt->next()->IsMediumNode( node ))
- continue;
- }
+ if ( ignoreMediumNodes && SMESH_MesherHelper::IsMedium( node, typeToCheck ))
+ continue;
const SMDS_PositionPtr& pos = node->GetPosition();
if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE )
return false;
* \param theEdge - The geometrical edge of interest
* \param theNodes - The resulting map
* \param ignoreMediumNodes - to store medium nodes of quadratic elements or not
+ * \param typeToCheck - type of elements to check for medium nodes
* \retval bool - false if not all parameters are OK
*/
static bool GetSortedNodesOnEdge(const SMESHDS_Mesh* theMesh,
const TopoDS_Edge& theEdge,
const bool ignoreMediumNodes,
- std::map< double, const SMDS_MeshNode* > & theNodes);
+ std::map< double, const SMDS_MeshNode* > & theNodes,
+ const SMDSAbs_ElementType typeToCheck = SMDSAbs_All);
/*!
* Moved to SMESH_MesherHelper
*/
void SMESH_MeshEditor::SplitVolumes (const TFacetOfElem & theElems,
const int theMethodFlags)
{
- // std-like iterator on coordinates of nodes of mesh element
- typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > NXyzIterator;
- NXyzIterator xyzEnd;
-
SMDS_VolumeTool volTool;
SMESH_MesherHelper helper( *GetMesh()), fHelper(*GetMesh());
fHelper.ToFixNodeParameters( true );
}
}
}
+ else if ( elem->GetType() == SMDSAbs_Edge )
+ {
+ // orient a new face same as adjacent one
+ int i1, i2;
+ const SMDS_MeshElement* e;
+ TIDSortedElemSet dummy;
+ if (( e = SMESH_MeshAlgos::FindFaceInSet( nextNod[0], prevNod[0], dummy,dummy, &i1, &i2 )) ||
+ ( e = SMESH_MeshAlgos::FindFaceInSet( prevNod[1], nextNod[1], dummy,dummy, &i1, &i2 )) ||
+ ( e = SMESH_MeshAlgos::FindFaceInSet( prevNod[0], prevNod[1], dummy,dummy, &i1, &i2 )))
+ {
+ // there is an adjacent face, check order of nodes in it
+ bool sameOrder = ( Abs( i2 - i1 ) == 1 ) ? ( i2 > i1 ) : ( i2 < i1 );
+ if ( sameOrder )
+ {
+ std::swap( itNN[0], itNN[1] );
+ std::swap( prevNod[0], prevNod[1] );
+ std::swap( nextNod[0], nextNod[1] );
+ if ( nbSame > 0 )
+ sames[0] = 1 - sames[0];
+ iNotSameNode = 1 - iNotSameNode;
+ }
+ }
+ }
int iSameNode = 0, iBeforeSame = 0, iAfterSame = 0, iOpposSame = 0;
if ( nbSame > 0 ) {
return; // medium node on axis
}
else if(sames[0]==0)
- aNewElem = aMesh->AddFace(prevNod[0], nextNod[1], prevNod[1],
- nextNod[2], midlNod[1], prevNod[2]);
+ aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[1],
+ prevNod[2], midlNod[1], nextNod[2] );
else // sames[0]==1
- aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], prevNod[1],
- midlNod[0], nextNod[2], prevNod[2]);
+ aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[0],
+ prevNod[2], nextNod[2], midlNod[0]);
}
}
else if ( nbDouble == 3 )
default:
break;
- }
- }
+ } // switch ( baseType )
+ } // scope
if ( !aNewElem && elem->GetType() == SMDSAbs_Face ) // try to create a polyherdal prism
{
polyedre_nodes.resize( prevNbNodes );
}
aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities);
- }
+
+ } // // try to create a polyherdal prism
if ( aNewElem ) {
newElems.push_back( aNewElem );
for ( iNode = 0; iNode < nbNodes; iNode++ )
prevNod[ iNode ] = nextNod[ iNode ];
- } // for steps
+ } // loop on steps
}
//=======================================================================
return newGroupIDs;
}
+//=======================================================================
+//function : ExtrusParam
+//purpose : standard construction
+//=======================================================================
+
+SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec& theStep,
+ const int theNbSteps,
+ const int theFlags,
+ const double theTolerance):
+ myDir( theStep ),
+ myFlags( theFlags ),
+ myTolerance( theTolerance ),
+ myElemsToUse( NULL )
+{
+ mySteps = new TColStd_HSequenceOfReal;
+ const double stepSize = theStep.Magnitude();
+ for (int i=1; i<=theNbSteps; i++ )
+ mySteps->Append( stepSize );
+
+ if (( theFlags & EXTRUSION_FLAG_SEW ) &&
+ ( theTolerance > 0 ))
+ {
+ myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByDirAndSew;
+ }
+ else
+ {
+ myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByDir;
+ }
+}
+
+//=======================================================================
+//function : ExtrusParam
+//purpose : steps are given explicitly
+//=======================================================================
+
+SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Dir& theDir,
+ Handle(TColStd_HSequenceOfReal) theSteps,
+ const int theFlags,
+ const double theTolerance):
+ myDir( theDir ),
+ mySteps( theSteps ),
+ myFlags( theFlags ),
+ myTolerance( theTolerance ),
+ myElemsToUse( NULL )
+{
+ if (( theFlags & EXTRUSION_FLAG_SEW ) &&
+ ( theTolerance > 0 ))
+ {
+ myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByDirAndSew;
+ }
+ else
+ {
+ myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByDir;
+ }
+}
//=======================================================================
-//function : CreateNode
-//purpose :
+//function : ExtrusParam
+//purpose : for extrusion by normal
//=======================================================================
-const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
- const double y,
- const double z,
- const double tolnode,
- SMESH_SequenceOfNode& aNodes)
+
+SMESH_MeshEditor::ExtrusParam::ExtrusParam( const double theStepSize,
+ const int theNbSteps,
+ const int theFlags,
+ const int theDim ):
+ myDir( 1,0,0 ),
+ mySteps( new TColStd_HSequenceOfReal ),
+ myFlags( theFlags ),
+ myTolerance( 0 ),
+ myElemsToUse( NULL )
{
- // myLastCreatedElems.Clear();
- // myLastCreatedNodes.Clear();
+ for (int i = 0; i < theNbSteps; i++ )
+ mySteps->Append( theStepSize );
- gp_Pnt P1(x,y,z);
- SMESHDS_Mesh * aMesh = myMesh->GetMeshDS();
+ if ( theDim == 1 )
+ {
+ myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByNormal1D;
+ }
+ else
+ {
+ myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByNormal2D;
+ }
+}
- // try to search in sequence of existing nodes
- // if aNodes.Length()>0 we 'nave to use given sequence
- // else - use all nodes of mesh
- if(aNodes.Length()>0) {
- int i;
- for(i=1; i<=aNodes.Length(); i++) {
- gp_Pnt P2(aNodes.Value(i)->X(),aNodes.Value(i)->Y(),aNodes.Value(i)->Z());
- if(P1.Distance(P2)<tolnode)
- return aNodes.Value(i);
+//=======================================================================
+//function : ExtrusParam::SetElementsToUse
+//purpose : stores elements to use for extrusion by normal, depending on
+// state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag
+//=======================================================================
+
+void SMESH_MeshEditor::ExtrusParam::SetElementsToUse( const TIDSortedElemSet& elems )
+{
+ myElemsToUse = ToUseInpElemsOnly() ? & elems : 0;
+}
+
+//=======================================================================
+//function : ExtrusParam::beginStepIter
+//purpose : prepare iteration on steps
+//=======================================================================
+
+void SMESH_MeshEditor::ExtrusParam::beginStepIter( bool withMediumNodes )
+{
+ myWithMediumNodes = withMediumNodes;
+ myNextStep = 1;
+ myCurSteps.clear();
+}
+//=======================================================================
+//function : ExtrusParam::moreSteps
+//purpose : are there more steps?
+//=======================================================================
+
+bool SMESH_MeshEditor::ExtrusParam::moreSteps()
+{
+ return myNextStep <= mySteps->Length() || !myCurSteps.empty();
+}
+//=======================================================================
+//function : ExtrusParam::nextStep
+//purpose : returns the next step
+//=======================================================================
+
+double SMESH_MeshEditor::ExtrusParam::nextStep()
+{
+ double res = 0;
+ if ( !myCurSteps.empty() )
+ {
+ res = myCurSteps.back();
+ myCurSteps.pop_back();
+ }
+ else if ( myNextStep <= mySteps->Length() )
+ {
+ myCurSteps.push_back( mySteps->Value( myNextStep ));
+ ++myNextStep;
+ if ( myWithMediumNodes )
+ {
+ myCurSteps.back() /= 2.;
+ myCurSteps.push_back( myCurSteps.back() );
}
+ res = nextStep();
}
- else {
- SMDS_NodeIteratorPtr itn = aMesh->nodesIterator();
- while(itn->more()) {
- const SMDS_MeshNode* aN = static_cast<const SMDS_MeshNode*> (itn->next());
- gp_Pnt P2(aN->X(),aN->Y(),aN->Z());
- if(P1.Distance(P2)<tolnode)
- return aN;
+ return res;
+}
+
+//=======================================================================
+//function : ExtrusParam::makeNodesByDir
+//purpose : create nodes for standard extrusion
+//=======================================================================
+
+int SMESH_MeshEditor::ExtrusParam::
+makeNodesByDir( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes)
+{
+ gp_XYZ p = SMESH_TNodeXYZ( srcNode );
+
+ int nbNodes = 0;
+ for ( beginStepIter( makeMediumNodes ); moreSteps(); ++nbNodes ) // loop on steps
+ {
+ p += myDir.XYZ() * nextStep();
+ const SMDS_MeshNode * newNode = mesh->AddNode( p.X(), p.Y(), p.Z() );
+ newNodes.push_back( newNode );
+ }
+ return nbNodes;
+}
+
+//=======================================================================
+//function : ExtrusParam::makeNodesByDirAndSew
+//purpose : create nodes for standard extrusion with sewing
+//=======================================================================
+
+int SMESH_MeshEditor::ExtrusParam::
+makeNodesByDirAndSew( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes)
+{
+ gp_XYZ P1 = SMESH_TNodeXYZ( srcNode );
+
+ int nbNodes = 0;
+ for ( beginStepIter( makeMediumNodes ); moreSteps(); ++nbNodes ) // loop on steps
+ {
+ P1 += myDir.XYZ() * nextStep();
+
+ // try to search in sequence of existing nodes
+ // if myNodes.Length()>0 we 'nave to use given sequence
+ // else - use all nodes of mesh
+ const SMDS_MeshNode * node = 0;
+ if ( myNodes.Length() > 0 ) {
+ int i;
+ for(i=1; i<=myNodes.Length(); i++) {
+ gp_XYZ P2 = SMESH_TNodeXYZ( myNodes.Value(i) );
+ if (( P1 - P2 ).SquareModulus() < myTolerance * myTolerance )
+ {
+ node = myNodes.Value(i);
+ break;
+ }
+ }
}
+ else {
+ SMDS_NodeIteratorPtr itn = mesh->nodesIterator();
+ while(itn->more()) {
+ SMESH_TNodeXYZ P2( itn->next() );
+ if (( P1 - P2 ).SquareModulus() < myTolerance * myTolerance )
+ {
+ node = P2._node;
+ break;
+ }
+ }
+ }
+
+ if ( !node )
+ node = mesh->AddNode( P1.X(), P1.Y(), P1.Z() );
+
+ newNodes.push_back( node );
+
+ } // loop on steps
+
+ return nbNodes;
+}
+
+//=======================================================================
+//function : ExtrusParam::makeNodesByNormal2D
+//purpose : create nodes for extrusion using normals of faces
+//=======================================================================
+
+int SMESH_MeshEditor::ExtrusParam::
+makeNodesByNormal2D( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes)
+{
+ const bool alongAvgNorm = ( myFlags & EXTRUSION_FLAG_BY_AVG_NORMAL );
+
+ gp_XYZ p = SMESH_TNodeXYZ( srcNode );
+
+ // get normals to faces sharing srcNode
+ vector< gp_XYZ > norms, baryCenters;
+ gp_XYZ norm, avgNorm( 0,0,0 );
+ SMDS_ElemIteratorPtr faceIt = srcNode->GetInverseElementIterator( SMDSAbs_Face );
+ while ( faceIt->more() )
+ {
+ const SMDS_MeshElement* face = faceIt->next();
+ if ( myElemsToUse && !myElemsToUse->count( face ))
+ continue;
+ if ( SMESH_MeshAlgos::FaceNormal( face, norm, /*normalized=*/true ))
+ {
+ norms.push_back( norm );
+ avgNorm += norm;
+ if ( !alongAvgNorm )
+ {
+ gp_XYZ bc(0,0,0);
+ int nbN = 0;
+ for ( SMDS_ElemIteratorPtr nIt = face->nodesIterator(); nIt->more(); ++nbN )
+ bc += SMESH_TNodeXYZ( nIt->next() );
+ baryCenters.push_back( bc / nbN );
+ }
+ }
+ }
+
+ if ( norms.empty() ) return 0;
+
+ double normSize = avgNorm.Modulus();
+ if ( normSize < std::numeric_limits<double>::min() )
+ return 0;
+
+ if ( myFlags & EXTRUSION_FLAG_BY_AVG_NORMAL ) // extrude along avgNorm
+ {
+ myDir = avgNorm;
+ return makeNodesByDir( mesh, srcNode, newNodes, makeMediumNodes );
}
- // create new node and return it
- const SMDS_MeshNode* NewNode = aMesh->AddNode(x,y,z);
- //myLastCreatedNodes.Append(NewNode);
- return NewNode;
+ avgNorm /= normSize;
+
+ int nbNodes = 0;
+ for ( beginStepIter( makeMediumNodes ); moreSteps(); ++nbNodes ) // loop on steps
+ {
+ gp_XYZ pNew = p;
+ double stepSize = nextStep();
+
+ if ( norms.size() > 1 )
+ {
+ for ( size_t iF = 0; iF < norms.size(); ++iF ) // loop on faces
+ {
+ // translate plane of a face
+ baryCenters[ iF ] += norms[ iF ] * stepSize;
+
+ // find point of intersection of the face plane located at baryCenters[ iF ]
+ // and avgNorm located at pNew
+ double d = -( norms[ iF ] * baryCenters[ iF ]); // d of plane equation ax+by+cz+d=0
+ double dot = ( norms[ iF ] * avgNorm );
+ if ( dot < std::numeric_limits<double>::min() )
+ dot = stepSize * 1e-3;
+ double step = -( norms[ iF ] * pNew + d ) / dot;
+ pNew += step * avgNorm;
+ }
+ }
+ else
+ {
+ pNew += stepSize * avgNorm;
+ }
+ p = pNew;
+
+ const SMDS_MeshNode * newNode = mesh->AddNode( p.X(), p.Y(), p.Z() );
+ newNodes.push_back( newNode );
+ }
+ return nbNodes;
}
+//=======================================================================
+//function : ExtrusParam::makeNodesByNormal1D
+//purpose : create nodes for extrusion using normals of edges
+//=======================================================================
+
+int SMESH_MeshEditor::ExtrusParam::
+makeNodesByNormal1D( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes)
+{
+ throw SALOME_Exception("Extrusion 1D by Normal not implemented");
+ return 0;
+}
//=======================================================================
//function : ExtrusionSweep
const gp_Vec& theStep,
const int theNbSteps,
TTElemOfElemListMap& newElemsMap,
- const bool theMakeGroups,
const int theFlags,
const double theTolerance)
{
- ExtrusParam aParams;
- aParams.myDir = gp_Dir(theStep);
- aParams.myNodes.Clear();
- aParams.mySteps = new TColStd_HSequenceOfReal;
- int i;
- for(i=1; i<=theNbSteps; i++)
- aParams.mySteps->Append(theStep.Magnitude());
-
- return
- ExtrusionSweep(theElems,aParams,newElemsMap,theMakeGroups,theFlags,theTolerance);
+ ExtrusParam aParams( theStep, theNbSteps, theFlags, theTolerance );
+ return ExtrusionSweep( theElems, aParams, newElemsMap );
}
SMESH_MeshEditor::PGroupIDs
SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
ExtrusParam& theParams,
- TTElemOfElemListMap& newElemsMap,
- const bool theMakeGroups,
- const int theFlags,
- const double theTolerance)
+ TTElemOfElemListMap& newElemsMap)
{
myLastCreatedElems.Clear();
myLastCreatedNodes.Clear();
SMESHDS_Mesh* aMesh = GetMeshDS();
- int nbsteps = theParams.mySteps->Length();
+ const int nbSteps = theParams.NbSteps();
+ theParams.SetElementsToUse( theElems );
TNodeOfNodeListMap mapNewNodes;
//TNodeOfNodeVecMap mapNewNodes;
myMesh->NbVolumes(ORDER_QUADRATIC) );
// loop on theElems
TIDSortedElemSet::iterator itElem;
- for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
+ for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
+ {
// check element type
const SMDS_MeshElement* elem = *itElem;
if ( !elem || elem->GetType() == SMDSAbs_Volume )
continue;
+ const size_t nbNodes = elem->NbNodes();
vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
- newNodesItVec.reserve( elem->NbNodes() );
+ newNodesItVec.reserve( nbNodes );
// loop on elem nodes
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
needMediumNodes = true;
}
}
-
- double coord[] = { node->X(), node->Y(), node->Z() };
- for ( int i = 0; i < nbsteps; i++ )
+ // create nodes for all steps
+ if ( theParams.MakeNodes( GetMeshDS(), node, listNewNodes, needMediumNodes ))
{
- if ( needMediumNodes ) // create a medium node
+ list<const SMDS_MeshNode*>::iterator newNodesIt = listNewNodes.begin();
+ for ( ; newNodesIt != listNewNodes.end(); ++newNodesIt )
{
- double x = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1)/2.;
- double y = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1)/2.;
- double z = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1)/2.;
- if( theFlags & EXTRUSION_FLAG_SEW ) {
- const SMDS_MeshNode * newNode = CreateNode(x, y, z,
- theTolerance, theParams.myNodes);
- listNewNodes.push_back( newNode );
- }
- else {
- const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
- myLastCreatedNodes.Append(newNode);
- srcNodes.Append( node );
- listNewNodes.push_back( newNode );
- }
- }
- // create a corner node
- coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1);
- coord[1] = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1);
- coord[2] = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1);
- if( theFlags & EXTRUSION_FLAG_SEW ) {
- const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1], coord[2],
- theTolerance, theParams.myNodes);
- listNewNodes.push_back( newNode );
- }
- else {
- const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
- myLastCreatedNodes.Append(newNode);
+ myLastCreatedNodes.Append( *newNodesIt );
srcNodes.Append( node );
- listNewNodes.push_back( newNode );
}
}
+ else
+ {
+ break; // newNodesItVec will be shorter than nbNodes
+ }
}
newNodesItVec.push_back( nIt );
}
// make new elements
- sweepElement( elem, newNodesItVec, newElemsMap[elem], nbsteps, srcElems );
+ if ( newNodesItVec.size() == nbNodes )
+ sweepElement( elem, newNodesItVec, newElemsMap[elem], nbSteps, srcElems );
}
- if( theFlags & EXTRUSION_FLAG_BOUNDARY ) {
- makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps, srcElems );
+ if ( theParams.ToMakeBoundary() ) {
+ makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbSteps, srcElems );
}
PGroupIDs newGroupIDs;
- if ( theMakeGroups )
+ if ( theParams.ToMakeGroups() )
newGroupIDs = generateGroups( srcNodes, srcElems, "extruded");
return newGroupIDs;
// by theAngle by theNbSteps
/*!
- * Auxilary flag for advanced extrusion.
+ * Flags of extrusion.
* BOUNDARY: create or not boundary for result of extrusion
* SEW: try to use existing nodes or create new nodes in any case
+ * GROUPS: to create groups
+ * BY_AVG_NORMAL: step size is measured along average normal to elements,
+ * 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()
*/
enum ExtrusionFlags {
EXTRUSION_FLAG_BOUNDARY = 0x01,
- EXTRUSION_FLAG_SEW = 0x02
+ EXTRUSION_FLAG_SEW = 0x02,
+ EXTRUSION_FLAG_GROUPS = 0x04,
+ EXTRUSION_FLAG_BY_AVG_NORMAL = 0x08,
+ EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY = 0x10
};
-
+
/*!
- * special structure for control of extrusion functionality
+ * Generator of nodes for extrusion functionality
*/
- struct ExtrusParam {
- gp_Dir myDir; // direction of extrusion
+ class ExtrusParam {
+ gp_Dir myDir; // direction of extrusion
Handle(TColStd_HSequenceOfReal) mySteps; // magnitudes for each step
- SMESH_SequenceOfNode myNodes; // nodes for using in sewing
+ SMESH_SequenceOfNode myNodes; // nodes for using in sewing
+ int myFlags; // see ExtrusionFlags
+ double myTolerance; // tolerance for sewing nodes
+ const TIDSortedElemSet* myElemsToUse; // elements to use for extrusion by normal
+
+ int (ExtrusParam::*myMakeNodesFun)(SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes);
+
+ public:
+ ExtrusParam( const gp_Vec& theStep,
+ const int theNbSteps,
+ 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
+
+ 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; }
+ 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 );
+
+ // creates nodes and returns number of nodes added in \a newNodes
+ int MakeNodes( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes)
+ {
+ return (this->*myMakeNodesFun)( mesh, srcNode, newNodes, makeMediumNodes );
+ }
+ private:
+
+ int makeNodesByDir( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes);
+ int makeNodesByDirAndSew( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes);
+ int makeNodesByNormal2D( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes);
+ int makeNodesByNormal1D( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes);
+ // step iteration
+ void beginStepIter( bool withMediumNodes );
+ bool moreSteps();
+ double nextStep();
+ std::vector< double > myCurSteps;
+ bool myWithMediumNodes;
+ int myNextStep;
};
- /*!
- * Create new node in the mesh with given coordinates
- * (auxiliary for advanced extrusion)
- */
- const SMDS_MeshNode* CreateNode(const double x,
- const double y,
- const double z,
- const double tolnode,
- SMESH_SequenceOfNode& aNodes);
-
/*!
* Generate new elements by extrusion of theElements
* It is a method used in .idl file. All functionality
const gp_Vec& theStep,
const int theNbSteps,
TTElemOfElemListMap& newElemsMap,
- const bool theMakeGroups,
- const int theFlags = EXTRUSION_FLAG_BOUNDARY,
+ const int theFlags,
const double theTolerance = 1.e-6);
/*!
*/
PGroupIDs ExtrusionSweep (TIDSortedElemSet & theElems,
ExtrusParam& theParams,
- TTElemOfElemListMap& newElemsMap,
- const bool theMakeGroups,
- const int theFlags,
- const double theTolerance);
+ TTElemOfElemListMap& newElemsMap);
// Generate new elements by extrusion of theElements
ConstructorsBoxLayout->setSpacing(SPACING);
ConstructorsBoxLayout->setMargin(MARGIN);
- RadioButton0= new QRadioButton(ConstructorsBox);
- RadioButton0->setIcon(image3);
- RadioButton1= new QRadioButton(ConstructorsBox);
- RadioButton1->setIcon(image0);
- RadioButton2= new QRadioButton(ConstructorsBox);
- RadioButton2->setIcon(image1);
+ Contructor_RBut0= new QRadioButton(ConstructorsBox);
+ Contructor_RBut0->setIcon(image3);
+ Contructor_RBut1= new QRadioButton(ConstructorsBox);
+ Contructor_RBut1->setIcon(image0);
+ Contructor_RBut2= new QRadioButton(ConstructorsBox);
+ Contructor_RBut2->setIcon(image1);
- ConstructorsBoxLayout->addWidget(RadioButton0);
- ConstructorsBoxLayout->addWidget(RadioButton1);
- ConstructorsBoxLayout->addWidget(RadioButton2);
+ ConstructorsBoxLayout->addWidget(Contructor_RBut0);
+ ConstructorsBoxLayout->addWidget(Contructor_RBut1);
+ ConstructorsBoxLayout->addWidget(Contructor_RBut2);
- GroupConstructors->addButton(RadioButton0, 0);
- GroupConstructors->addButton(RadioButton1, 1);
- GroupConstructors->addButton(RadioButton2, 2);
+ GroupConstructors->addButton(Contructor_RBut0, 0);
+ GroupConstructors->addButton(Contructor_RBut1, 1);
+ GroupConstructors->addButton(Contructor_RBut2, 2);
/***************************************************************/
GroupButtons = new QGroupBox(this);
// Control for the whole mesh selection
CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
- RadioButton3 = new QRadioButton(GroupArguments);
- RadioButton3->setText( tr("SMESH_EXTRUSION_TO_DISTANCE") );
- RadioButton4 = new QRadioButton(GroupArguments);
- RadioButton4->setText( tr("SMESH_EXTRUSION_ALONG_VECTOR") );
+ ExtrMethod_RBut0 = new QRadioButton(GroupArguments);
+ ExtrMethod_RBut0->setText( tr("SMESH_EXTRUSION_TO_DISTANCE") );
+ ExtrMethod_RBut1 = new QRadioButton(GroupArguments);
+ ExtrMethod_RBut1->setText( tr("SMESH_EXTRUSION_ALONG_VECTOR") );
+ ExtrMethod_RBut2 = new QRadioButton(GroupArguments);
+ ExtrMethod_RBut2->setText( tr("SMESH_EXTRUSION_BY_NORMAL") );
//Control for the Distance selection
TextLabelDistance = new QLabel(tr("SMESH_DISTANCE"), GroupArguments);
// CheckBox for groups generation
MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
+ // CheckBox for ByAverageNormal arg of ExtrusionByNormal()
+ ByAverageNormalCheck = new QCheckBox(tr("BY_AVERAGE_NORMAL"), GroupArguments);
+
+ // CheckBox for UseInputElemsOnly arg of ExtrusionByNormal()
+ UseInputElemsOnlyCheck = new QCheckBox(tr("USE_INPUT_ELEMS_ONLY"), GroupArguments);
+
//Preview check box
myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 5);
GroupArgumentsLayout->addWidget(myFilterBtn, 0, 7);
GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 8);
- GroupArgumentsLayout->addWidget(RadioButton3, 2, 1, 1, 3);
- GroupArgumentsLayout->addWidget(RadioButton4, 2, 5, 1, 3);
+ GroupArgumentsLayout->addWidget(ExtrMethod_RBut0, 2, 0, 1, 3);
+ GroupArgumentsLayout->addWidget(ExtrMethod_RBut1, 2, 3, 1, 3);
+ GroupArgumentsLayout->addWidget(ExtrMethod_RBut2, 2, 6, 1, 3);
GroupArgumentsLayout->addWidget(TextLabelDistance, 3, 0);
GroupArgumentsLayout->addWidget(TextLabelDx, 3, 2);
GroupArgumentsLayout->addWidget(SpinBox_Dx, 3, 3);
GroupArgumentsLayout->addWidget(TextLabelVz, 4, 6);
GroupArgumentsLayout->addWidget(SpinBox_Vz, 4, 7);
GroupArgumentsLayout->addWidget(TextLabelDist, 5, 0);
- GroupArgumentsLayout->addWidget(SpinBox_VDist, 5, 3);
+ GroupArgumentsLayout->addWidget(SpinBox_VDist, 5, 3);
GroupArgumentsLayout->addWidget(TextLabelNbSteps, 6, 0, 1, 3);
GroupArgumentsLayout->addWidget(SpinBox_NbSteps, 6, 3);
- GroupArgumentsLayout->addWidget(myPreviewCheckBox, 7, 0, 1, 8);
- GroupArgumentsLayout->addWidget(MakeGroupsCheck, 8, 0, 1, 8);
- GroupArgumentsLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 8, 0);
+ GroupArgumentsLayout->addWidget(ByAverageNormalCheck, 7, 0, 1, 4);
+ GroupArgumentsLayout->addWidget(UseInputElemsOnlyCheck, 7, 4, 1, 4);
+ GroupArgumentsLayout->addWidget(myPreviewCheckBox, 8, 0, 1, 8);
+ GroupArgumentsLayout->addWidget(MakeGroupsCheck, 9, 0, 1, 8);
+ GroupArgumentsLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 10, 0);
/***************************************************************/
SMESHGUI_ExtrusionDlgLayout->addWidget(GroupButtons);
/* Initialisations */
- SpinBox_Vx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.01, "length_precision");
- SpinBox_Vy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.01, "length_precision");
- SpinBox_Vz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.01, "length_precision");
+ SpinBox_Vx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.1, "length_precision");
+ SpinBox_Vy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.1, "length_precision");
+ SpinBox_Vz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.1, "length_precision");
SpinBox_Dx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
SpinBox_Dy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
SpinBox_Dz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
SpinBox_NbSteps->setRange(1, 999999);
- SpinBox_VDist->RangeStepAndValidator(0, COORD_MAX, 10.0, "length_precision");
+ SpinBox_VDist->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
- RadioButton0->setChecked(true);
- RadioButton3->setChecked(true);
+ Contructor_RBut0->setChecked(true);
+ ExtrMethod_RBut0->setChecked(true);
+ UseInputElemsOnlyCheck->setChecked(true);
MakeGroupsCheck->setChecked(true);
mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
- connect(RadioButton3, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
- connect(RadioButton4, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
+ connect(ExtrMethod_RBut0, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
+ connect(ExtrMethod_RBut1, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
+ connect(ExtrMethod_RBut2, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
// to update state of the Ok & Apply buttons
connect(SpinBox_Vx, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
connect(LineEditElements, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool)));
- connect(SpinBox_Dx, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
- connect(SpinBox_Dy, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
- connect(SpinBox_Dz, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
- connect(SpinBox_Vx, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
- connect(SpinBox_Vy, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
- connect(SpinBox_Vz, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
- connect(SpinBox_VDist, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
- connect(SpinBox_NbSteps, SIGNAL(valueChanged(int)), this, SLOT(toDisplaySimulation()));
+ connect(SpinBox_Dx, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+ connect(SpinBox_Dy, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+ connect(SpinBox_Dz, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+ connect(SpinBox_Vx, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+ connect(SpinBox_Vy, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+ connect(SpinBox_Vz, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+ connect(SpinBox_VDist, SIGNAL(valueChanged(double)), 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()));
//To Connect preview check box
connectPreviewControl();
//=================================================================================
bool SMESHGUI_ExtrusionDlg::isValuesValid() {
double aX, aY, aZ, aModule = 0;
- if ( RadioButton3->isChecked() ) {
+ if ( ExtrMethod_RBut0->isChecked() ) {
aX = SpinBox_Dx->GetValue();
aY = SpinBox_Dy->GetValue();
aZ = SpinBox_Dz->GetValue();
aModule = sqrt(aX*aX + aY*aY + aZ*aZ);
- } else if ( RadioButton4->isChecked() ) {
+ }
+ else if ( ExtrMethod_RBut1->isChecked() ) {
aX = SpinBox_Vx->GetValue();
aY = SpinBox_Vy->GetValue();
aZ = SpinBox_Vz->GetValue();
aModule = sqrt(aX*aX + aY*aY + aZ*aZ);
}
+ else if ( ExtrMethod_RBut2->isChecked() ) {
+ aModule = 1;
+ }
+
return aModule > 1.0E-38;
}
}
}
+ ExtrMethod_RBut2->setVisible( constructorId == 2 );
+ if ( !ExtrMethod_RBut2->isVisible() &&
+ ExtrMethod_RBut2->isChecked() )
+ ExtrMethod_RBut0->click();
+
myEditCurrentArgument = (QWidget*)LineEditElements;
LineEditElements->setFocus();
//=================================================================================
void SMESHGUI_ExtrusionDlg::ClickOnRadio()
{
- if ( RadioButton3->isChecked() ) {
+ if ( ExtrMethod_RBut0->isChecked() )
+ {
TextLabelDistance->show();
TextLabelDx->show();
SpinBox_Dx->show();
TextLabelDist->hide();
SpinBox_VDist->hide();
SelectVectorButton->hide();
- } else if ( RadioButton4->isChecked() ) {
+
+ ByAverageNormalCheck->hide();
+ UseInputElemsOnlyCheck->hide();
+ }
+ else if ( ExtrMethod_RBut1->isChecked() )
+ {
TextLabelDistance->hide();
TextLabelDx->hide();
SpinBox_Dx->hide();
TextLabelDist->show();
SpinBox_VDist->show();
SelectVectorButton->show();
+
+ ByAverageNormalCheck->hide();
+ UseInputElemsOnlyCheck->hide();
}
+ else if ( ExtrMethod_RBut2->isChecked() )
+ {
+ TextLabelDistance->hide();
+ TextLabelDx->hide();
+ SpinBox_Dx->hide();
+ TextLabelDy->hide();
+ SpinBox_Dy->hide();
+ TextLabelDz->hide();
+ SpinBox_Dz->hide();
+
+ TextLabelVector->hide();
+ TextLabelVx->hide();
+ SpinBox_Vx->hide();
+ TextLabelVy->hide();
+ SpinBox_Vy->hide();
+ TextLabelVz->hide();
+ SpinBox_Vz->hide();
+
+ TextLabelDist->show();
+ SpinBox_VDist->show();
+ SelectVectorButton->hide();
+
+ ByAverageNormalCheck->show();
+ UseInputElemsOnlyCheck->show();
+ }
+
+ CheckIsEnable();
+
onDisplaySimulation(true);
// AdjustSize
qApp->processEvents();
getExtrusionVector(aVector);
QStringList aParameters;
- if ( RadioButton3->isChecked() ) {
+ if ( ExtrMethod_RBut0->isChecked() )
+ {
aParameters << SpinBox_Dx->text();
aParameters << SpinBox_Dy->text();
aParameters << SpinBox_Dz->text();
- } else if ( RadioButton4->isChecked() ) {
+ }
+ else if ( ExtrMethod_RBut1->isChecked() )
+ {
// only 3 coords in a python dump command :(
// aParameters << SpinBox_Vx->text();
// aParameters << SpinBox_Vy->text();
// aParameters << SpinBox_Vz->text();
// aParameters << SpinBox_VDist->text();
}
+ else if ( ExtrMethod_RBut2->isChecked() )
+ {
+ aParameters << SpinBox_VDist->text();
+ }
long aNbSteps = (long)SpinBox_NbSteps->value();
aParameters << SpinBox_NbSteps->text();
+ bool meshHadNewTypeBefore = true;
+
try {
SUIT_OverrideCursor aWaitCursor;
+
+ // is it necessary to switch on the next Display Mode?
+ SMESH::ElementType newType = (SMESH::ElementType)( SMESH::EDGE + GetConstructorId() );
+ SMESH::array_of_ElementType_var oldTypes = myMesh->GetTypes();
+ meshHadNewTypeBefore = false;
+ for ( size_t i = 0; i < oldTypes->length() && !meshHadNewTypeBefore; ++i )
+ meshHadNewTypeBefore = ( oldTypes[i] >= newType );
+
SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
myMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
- if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) {
- if( CheckBoxMesh->isChecked() )
+ const bool makeGroups = MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked();
+
+ if ( ExtrMethod_RBut2->isVisible() &&
+ ExtrMethod_RBut2->isChecked() ) // Extrusion by normal
+ {
+ extrusionByNormal( aMeshEditor, makeGroups );
+ }
+ else if ( makeGroups ) // create groups
+ {
+ SMESH::ListOfGroups_var groups;
+ if( CheckBoxMesh->isChecked() )
switch (GetConstructorId() ) {
- case 0:
- {
- SMESH::ListOfGroups_var groups =
- aMeshEditor->ExtrusionSweepObject0DMakeGroups(mySelectedObject, aVector, aNbSteps);
- break;
- }
- case 1:
- {
- SMESH::ListOfGroups_var groups =
- aMeshEditor->ExtrusionSweepObject1DMakeGroups(mySelectedObject, aVector, aNbSteps);
- break;
- }
- case 2:
- {
- SMESH::ListOfGroups_var groups =
- aMeshEditor->ExtrusionSweepObject2DMakeGroups(mySelectedObject, aVector, aNbSteps);
- break;
- }
+ case 0:
+ groups = aMeshEditor->ExtrusionSweepObject0DMakeGroups(mySelectedObject, aVector,
+ aNbSteps); break;
+ case 1:
+ groups = aMeshEditor->ExtrusionSweepObject1DMakeGroups(mySelectedObject, aVector,
+ aNbSteps); break;
+ case 2:
+ groups = aMeshEditor->ExtrusionSweepObject2DMakeGroups(mySelectedObject, aVector,
+ aNbSteps); break;
}
else
{
- SMESH::ListOfGroups_var groups;
if (GetConstructorId() == 0)
- groups = aMeshEditor->ExtrusionSweepMakeGroups0D(myElementsId.inout(), aVector, aNbSteps);
+ groups = aMeshEditor->ExtrusionSweepMakeGroups0D(myElementsId.inout(), aVector,
+ aNbSteps);
else
- groups = aMeshEditor->ExtrusionSweepMakeGroups(myElementsId.inout(), aVector, aNbSteps);
+ groups = aMeshEditor->ExtrusionSweepMakeGroups(myElementsId.inout(), aVector,
+ aNbSteps);
}
-
}
- else {
- if( CheckBoxMesh->isChecked() )
+ else // no groups
+ {
+ if( CheckBoxMesh->isChecked() )
switch( GetConstructorId() ) {
- case 0:
- {
- aMeshEditor->ExtrusionSweepObject0D(mySelectedObject, aVector, aNbSteps);
- break;
- }
- case 1:
- {
- aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps);
- break;
- }
- case 2:
- {
- aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps);
- break;
+ case 0:
+ aMeshEditor->ExtrusionSweepObject0D(mySelectedObject, aVector, aNbSteps);
+ break;
+ case 1:
+ aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps);
+ break;
+ case 2:
+ aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps);
+ break;
}
- }
else
if (GetConstructorId() == 0)
aMeshEditor->ExtrusionSweep0D(myElementsId.inout(), aVector, aNbSteps);
} catch (...) {
}
+ if ( myActor && !meshHadNewTypeBefore )
+ {
+ unsigned int aMode = myActor->GetEntityMode();
+ switch ( GetConstructorId() ) {
+ case 0: // extrude node -> edges
+ myActor->SetRepresentation(SMESH_Actor::eEdge);
+ myActor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
+ case 1: // edge -> faces
+ myActor->SetRepresentation(SMESH_Actor::eSurface);
+ myActor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
+ case 2: // faces -> volumes
+ myActor->SetRepresentation(SMESH_Actor::eSurface);
+ myActor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
+ }
+ }
SMESH::Update(myIO, SMESH::eDisplay);
if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() )
mySMESHGUI->updateObjBrowser(true); // new groups may appear
Init(false);
- ConstructorsClicked(GetConstructorId());
mySelectionMgr->clearSelected();
mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument();
+ ConstructorsClicked(GetConstructorId());
SMESHGUI::Modified();
}
{
QString msg;
bool ok = true;
- if ( RadioButton3->isChecked() ) {
+ if ( ExtrMethod_RBut0->isChecked() ) {
ok = SpinBox_Dx->isValid( msg, true ) && ok;
ok = SpinBox_Dy->isValid( msg, true ) && ok;
ok = SpinBox_Dz->isValid( msg, true ) && ok;
- } else if ( RadioButton4->isChecked() ) {
+ } else if ( ExtrMethod_RBut1->isChecked() ) {
ok = SpinBox_Vx->isValid( msg, true ) && ok;
ok = SpinBox_Vy->isValid( msg, true ) && ok;
ok = SpinBox_Vz->isValid( msg, true ) && ok;
// function : onDisplaySimulation
// purpose : Show/Hide preview
//=================================================================================
-void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview ) {
+void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview )
+{
if (myPreviewCheckBox->isChecked() && toDisplayPreview) {
if (myNbOkElements && isValid() && isValuesValid()) {
//Get input vector
SMESH::DirStruct aVector;
getExtrusionVector(aVector);
- //Get Number of the steps
+ //Get Number of the steps
long aNbSteps = (long)SpinBox_NbSteps->value();
-
- try {
+ try
+ {
SUIT_OverrideCursor aWaitCursor;
SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer();
- if( CheckBoxMesh->isChecked() ) {
+
+ if ( ExtrMethod_RBut2->isVisible() &&
+ ExtrMethod_RBut2->isChecked() ) // Extrusion by normal
+ {
+ extrusionByNormal( aMeshEditor );
+ }
+ else if ( CheckBoxMesh->isChecked() ) // Extrude the whole object
+ {
switch (GetConstructorId()) {
- case 0:
- {
- aMeshEditor->ExtrusionSweepObject0D(mySelectedObject, aVector, aNbSteps);
- break;
- }
- case 1:
- {
- aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps);
- break;
- }
- case 2:
- {
- aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps);
- break;
- }
+ case 0:
+ {
+ aMeshEditor->ExtrusionSweepObject0D(mySelectedObject, aVector, aNbSteps);
+ break;
+ }
+ case 1:
+ {
+ aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps);
+ break;
+ }
+ case 2:
+ {
+ aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps);
+ break;
+ }
}
}
- else
+ else // extrude some elements
+ {
if(GetConstructorId() == 0)
aMeshEditor->ExtrusionSweep0D(myElementsId.inout(), aVector, aNbSteps);
else
aMeshEditor->ExtrusionSweep(myElementsId.inout(), aVector, aNbSteps);
-
+ }
SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData();
mySimulation->SetData(aMeshPreviewStruct._retn());
} catch (...) {
// function : getExtrusionVector()
// purpose : get direction of the extrusion
//=================================================================================
-void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector) {
- if ( RadioButton3->isChecked() ) {
+void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector)
+{
+ if ( ExtrMethod_RBut0->isChecked() )
+ {
aVector.PS.x = SpinBox_Dx->GetValue();
aVector.PS.y = SpinBox_Dy->GetValue();
- aVector.PS.z = SpinBox_Dz->GetValue();
- } else if ( RadioButton4->isChecked() ) {
+ aVector.PS.z = SpinBox_Dz->GetValue();
+ }
+ else if ( ExtrMethod_RBut1->isChecked() )
+ {
gp_XYZ aNormale(SpinBox_Vx->GetValue(),
SpinBox_Vy->GetValue(),
SpinBox_Vz->GetValue());
-
-
aNormale /= aNormale.Modulus();
double aVDist = (double)SpinBox_VDist->value();
-
+
aVector.PS.x = aNormale.X()*aVDist;
aVector.PS.y = aNormale.Y()*aVDist;
aVector.PS.z = aNormale.Z()*aVDist;
}
}
+
+//=======================================================================
+//function : extrusionByNormal
+//purpose : performs extrusion by normal
+//=======================================================================
+
+void SMESHGUI_ExtrusionDlg::extrusionByNormal( SMESH::SMESH_MeshEditor_ptr meshEditor,
+ const bool makeGroups)
+{
+ SMESH::SMESH_IDSource_wrap anIDSource;
+ if ( CheckBoxMesh->isChecked() )
+ {
+ anIDSource = mySelectedObject;
+ anIDSource->Register();
+ }
+ else // make a temporary id source
+ {
+ anIDSource = meshEditor->MakeIDSource( myElementsId, SMESH::ALL );
+ }
+
+ double stepSize = (double) SpinBox_VDist->value();
+ long nbSteps = (long)SpinBox_NbSteps->value();
+ bool useInputElemsOnly = UseInputElemsOnlyCheck->isChecked();
+ bool byAverageNormal = ByAverageNormalCheck->isChecked();
+ int dim = GetConstructorId();
+
+ SMESH::ListOfGroups_var groups =
+ meshEditor->ExtrusionByNormal( anIDSource, stepSize, nbSteps,
+ useInputElemsOnly, byAverageNormal, makeGroups, dim );
+}
// IDL includes
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
class QButtonGroup;
class QRadioButton;
void keyPressEvent( QKeyEvent* );
int GetConstructorId();
void getExtrusionVector(SMESH::DirStruct& aVector);
+ void extrusionByNormal(SMESH::SMESH_MeshEditor_ptr meshEditor,
+ const bool makeGroups=false);
bool isValid();
bool isValuesValid();
// widgets
QGroupBox* ConstructorsBox;
QButtonGroup* GroupConstructors;
- QRadioButton* RadioButton0;
- QRadioButton* RadioButton1;
- QRadioButton* RadioButton2;
- QRadioButton* RadioButton3;
- QRadioButton* RadioButton4;
+ QRadioButton* Contructor_RBut0;
+ QRadioButton* Contructor_RBut1;
+ QRadioButton* Contructor_RBut2;
+ QRadioButton* ExtrMethod_RBut0;
+ QRadioButton* ExtrMethod_RBut1;
+ QRadioButton* ExtrMethod_RBut2;
QGroupBox* GroupArguments;
QGroupBox* GroupDimensions;
SMESHGUI_SpinBox* SpinBox_VDist;
QLabel* TextLabelNbSteps;
SalomeApp_IntSpinBox* SpinBox_NbSteps;
+ QCheckBox* ByAverageNormalCheck;
+ QCheckBox* UseInputElemsOnlyCheck;
QCheckBox* MakeGroupsCheck;
QGroupBox* GroupButtons;
aParameters << SpinBox_NbSteps->text();
aParameters << SpinBox_Tolerance->text();
+ bool meshHadNewTypeBefore = true;
+
try {
SUIT_OverrideCursor aWaitCursor;
+
+ // is it necessary to switch on the next Display Mode?
+ SMESH::ElementType newType = (SMESH::ElementType)( SMESH::FACE + GetConstructorId() );
+ SMESH::array_of_ElementType_var oldTypes = myMesh->GetTypes();
+ meshHadNewTypeBefore = false;
+ for ( size_t i = 0; i < oldTypes->length() && !meshHadNewTypeBefore; ++i )
+ meshHadNewTypeBefore = ( oldTypes[i] >= newType );
+
SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
myMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
} catch (...) {
}
+ if ( myActor && !meshHadNewTypeBefore )
+ {
+ unsigned int aMode = myActor->GetEntityMode();
+ switch ( GetConstructorId() ) {
+ case 0-1: // extrude node -> edges
+ myActor->SetRepresentation(SMESH_Actor::eEdge);
+ myActor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
+ case 1-1: // edge -> faces
+ myActor->SetRepresentation(SMESH_Actor::eSurface);
+ myActor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
+ case 2-1: // faces -> volumes
+ myActor->SetRepresentation(SMESH_Actor::eSurface);
+ myActor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
+ }
+ }
SMESH::UpdateView();
SMESH::Update(myIO, SMESH::eDisplay);
if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() )
mySMESHGUI->updateObjBrowser(true); // new groups may appear
Init(false);
- ConstructorsClicked(GetConstructorId());
+ mySelectionMgr->clearSelected();
mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument();
+ ConstructorsClicked(GetConstructorId());
SMESHGUI::Modified();
}
<source>SMESH_EXTRUSION_ALONG_VECTOR</source>
<translation>Extrusion Along Vector</translation>
</message>
+ <message>
+ <source>SMESH_EXTRUSION_BY_NORMAL</source>
+ <translation>Extrusion By Normal</translation>
+ </message>
<message>
<source>SMESH_FACE</source>
<translation>Face</translation>
<source>EXTRUSION_ALONG_LINE</source>
<translation>Extrusion along a line</translation>
</message>
+ <message>
+ <source>BY_AVERAGE_NORMAL</source>
+ <translation>Along average normal</translation>
+ </message>
+ <message>
+ <source>USE_INPUT_ELEMS_ONLY</source>
+ <translation>Use only input elements</translation>
+ </message>
</context>
<context>
<name>SMESHGUI_FilterDlg</name>
if ( !sameElemType )
elemType = SMDSAbs_All;
- TIDSortedElemSet visitedNodes;
+ vector<bool> isNodeChecked( theMeshDS->NbNodes(), false );
+
TIDSortedElemSet::const_iterator elemIt = theElements.begin();
for ( ; elemIt != theElements.end(); ++elemIt )
{
while ( --i != -1 )
{
const SMDS_MeshNode* n = e->GetNode( i );
- if ( visitedNodes.insert( n ).second )
+ if ( !isNodeChecked[ n->GetID() ])
{
+ isNodeChecked[ n->GetID() ] = true;
SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
while ( invIt->more() )
{
SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
SMESH::ElementType type)
{
- // if ( myAuxIDSources.size() > 10 ) {
- // delete myAuxIDSources.front();
- // myAuxIDSources.pop_front();
- // }
-
_IDSource* idSrc = new _IDSource;
idSrc->_mesh = myMesh_i->_this();
idSrc->_ids = ids;
idSrc->_type = type;
- //myAuxIDSources.push_back( idSrc );
+ if ( type == SMESH::ALL && ids.length() > 0 )
+ idSrc->_type = myMesh_i->GetElementType( ids[0], true );
SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
return aGroups;
}
+namespace MeshEditor_I
+{
+ /*!
+ * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor
+ */
+ struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam
+ {
+ bool myIsExtrusionByNormal;
+
+ static int makeFlags( CORBA::Boolean MakeGroups,
+ CORBA::Boolean ByAverageNormal = false,
+ CORBA::Boolean UseInputElemsOnly = false,
+ CORBA::Long Flags = 0,
+ CORBA::Boolean MakeBoundary = true )
+ {
+ 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 ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
+ return Flags;
+ }
+ // standard params
+ ExtrusionParams(const SMESH::DirStruct & theDir,
+ CORBA::Long theNbOfSteps,
+ CORBA::Boolean theMakeGroups):
+ ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
+ theDir.PS.y,
+ theDir.PS.z ),
+ theNbOfSteps,
+ makeFlags( theMakeGroups )),
+ myIsExtrusionByNormal( false )
+ {
+ }
+ // advanced params
+ ExtrusionParams(const SMESH::DirStruct & theDir,
+ CORBA::Long theNbOfSteps,
+ CORBA::Boolean theMakeGroups,
+ CORBA::Long theExtrFlags,
+ CORBA::Double theSewTolerance):
+ ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
+ theDir.PS.y,
+ theDir.PS.z ),
+ theNbOfSteps,
+ makeFlags( theMakeGroups, false, false,
+ theExtrFlags, false ),
+ theSewTolerance ),
+ myIsExtrusionByNormal( false )
+ {
+ }
+ // params for extrusion by normal
+ ExtrusionParams(CORBA::Double theStepSize,
+ CORBA::Long theNbOfSteps,
+ CORBA::Short theDim,
+ CORBA::Boolean theUseInputElemsOnly,
+ CORBA::Boolean theByAverageNormal,
+ CORBA::Boolean theMakeGroups ):
+ ::SMESH_MeshEditor::ExtrusParam ( theStepSize,
+ theNbOfSteps,
+ makeFlags( theMakeGroups,
+ theByAverageNormal, theUseInputElemsOnly ),
+ theDim),
+ myIsExtrusionByNormal( true )
+ {
+ }
+
+ void SetNoGroups()
+ {
+ Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
+ }
+ };
+}
//=======================================================================
//function : extrusionSweep
//=======================================================================
SMESH::ListOfGroups*
-SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
- const SMESH::DirStruct & theStepVector,
- CORBA::Long theNbOfSteps,
- bool theMakeGroups,
- const SMDSAbs_ElementType theElementType)
+SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
+ MeshEditor_I::ExtrusionParams& theParams,
+ const SMDSAbs_ElementType theElementType)
throw (SALOME::SALOME_Exception)
{
SMESH_TRY;
initData();
TIDSortedElemSet elements, copyElements;
- arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
-
- const SMESH::PointStruct * P = &theStepVector.PS;
- gp_Vec stepVec( P->x, P->y, P->z );
+ arrayToSet( theIDsOfElements, getMeshDS(), elements, theElementType );
TIDSortedElemSet* workElements = & elements;
- SMDSAbs_ElementType aType = SMDSAbs_Face;
- if (theElementType == SMDSAbs_Node)
+ if ( myIsPreviewMode )
{
- aType = SMDSAbs_Edge;
- }
- if ( myIsPreviewMode ) {
+ SMDSAbs_ElementType previewType = SMDSAbs_Face;
+ if (theElementType == SMDSAbs_Node)
+ previewType = SMDSAbs_Edge;
+
SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
- getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
+ getPreviewMesh( previewType )->Copy( elements, copyElements, select, avoid );
workElements = & copyElements;
- theMakeGroups = false;
+ theParams.SetNoGroups();
+
+ if ( theParams.myIsExtrusionByNormal && !theParams.ToUseInpElemsOnly() )
+ {
+ TIDSortedElemSet elemsAround, elemsAroundCopy;
+ getElementsAround( elements, getMeshDS(), elemsAround );
+ getPreviewMesh( previewType )->Copy( elemsAround, elemsAroundCopy, select, avoid );
+ }
}
::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
- ::SMESH_MeshEditor::PGroupIDs groupIds =
- getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
+ ::SMESH_MeshEditor::PGroupIDs groupIds =
+ getEditor().ExtrusionSweep (*workElements, theParams, aHystory );
declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
- return theMakeGroups ? getGroups(groupIds.get()) : 0;
+ return theParams.ToMakeGroups() ? getGroups(groupIds.get()) : 0;
SMESH_CATCH( SMESH::throwCorbaException );
return 0;
CORBA::Long theNbOfSteps)
throw (SALOME::SALOME_Exception)
{
- extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
+ ExtrusionParams params( theStepVector, theNbOfSteps, false );
+ extrusionSweep( theIDsOfElements, params );
if (!myIsPreviewMode) {
TPythonDump() << this << ".ExtrusionSweep( "
<< theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
CORBA::Long theNbOfSteps)
throw (SALOME::SALOME_Exception)
{
- extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
+ ExtrusionParams params( theStepVector, theNbOfSteps, false );
+ extrusionSweep( theIDsOfElements, params, SMDSAbs_Node );
if (!myIsPreviewMode) {
TPythonDump() << this << ".ExtrusionSweep0D( "
<< theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
{
prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs();
- extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
+ ExtrusionParams params( theStepVector, theNbOfSteps, false );
+ extrusionSweep( anElementsId, params );
if (!myIsPreviewMode) {
TPythonDump() << this << ".ExtrusionSweepObject( "
<< theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
{
prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs();
- extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
+ if ( anElementsId->length() == 0 )
+ if ( SMESH_Mesh_i* mesh = SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
+ anElementsId = mesh->GetNodesId();
+
+ ExtrusionParams params( theStepVector, theNbOfSteps, false );
+ extrusionSweep( anElementsId, params, SMDSAbs_Node );
if ( !myIsPreviewMode ) {
TPythonDump() << this << ".ExtrusionSweepObject0D( "
<< theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
{
prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs();
- extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
+ ExtrusionParams params( theStepVector, theNbOfSteps, false );
+ extrusionSweep( anElementsId, params, SMDSAbs_Edge );
if ( !myIsPreviewMode ) {
TPythonDump() << this << ".ExtrusionSweepObject1D( "
<< theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
{
prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs();
- extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
+ ExtrusionParams params( theStepVector, theNbOfSteps, false );
+ extrusionSweep( anElementsId, params, SMDSAbs_Face );
if ( !myIsPreviewMode ) {
TPythonDump() << this << ".ExtrusionSweepObject2D( "
<< theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
{
TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
- SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
+ ExtrusionParams params( theStepVector, theNbOfSteps, true );
+ SMESH::ListOfGroups* aGroups = extrusionSweep( theIDsOfElements, params );
if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups);
{
TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
- SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
+ ExtrusionParams params( theStepVector, theNbOfSteps, true );
+ SMESH::ListOfGroups* aGroups = extrusionSweep( theIDsOfElements, params, SMDSAbs_Node );
if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups);
prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs();
- SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
+ ExtrusionParams params( theStepVector, theNbOfSteps, true );
+ SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params );
if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups);
prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs();
- SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
- theNbOfSteps, true, SMDSAbs_Node);
+ ExtrusionParams params( theStepVector, theNbOfSteps, true );
+ SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Node );
+
if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups);
aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs();
- SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
- theNbOfSteps, true, SMDSAbs_Edge);
+ ExtrusionParams params( theStepVector, theNbOfSteps, true );
+ SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Edge );
+
if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups);
aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs();
- SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
- theNbOfSteps, true, SMDSAbs_Face);
+ ExtrusionParams params( theStepVector, theNbOfSteps, true );
+ SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Face );
+
if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups);
aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
return aGroups;
}
-
//=======================================================================
-//function : advancedExtrusion
+//function : ExtrusionByNormal
//purpose :
//=======================================================================
SMESH::ListOfGroups*
-SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
- const SMESH::DirStruct & theStepVector,
- CORBA::Long theNbOfSteps,
- CORBA::Long theExtrFlags,
- CORBA::Double theSewTolerance,
- const bool theMakeGroups)
+SMESH_MeshEditor_i::ExtrusionByNormal(SMESH::SMESH_IDSource_ptr object,
+ CORBA::Double stepSize,
+ CORBA::Long nbOfSteps,
+ CORBA::Boolean byAverageNormal,
+ CORBA::Boolean useInputElemsOnly,
+ CORBA::Boolean makeGroups,
+ CORBA::Short dim)
throw (SALOME::SALOME_Exception)
{
- SMESH_TRY;
- initData();
-
- TIDSortedElemSet elements;
- arrayToSet(theIDsOfElements, getMeshDS(), elements);
-
- const SMESH::PointStruct * P = &theStepVector.PS;
- gp_Vec stepVec( P->x, P->y, P->z );
-
- ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
- ::SMESH_MeshEditor::PGroupIDs groupIds =
- getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
- theMakeGroups, theExtrFlags, theSewTolerance);
+ TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
- declareMeshModified( /*isReComputeSafe=*/true );
+ ExtrusionParams params( stepSize, nbOfSteps, dim,
+ byAverageNormal, useInputElemsOnly, makeGroups );
- return theMakeGroups ? getGroups(groupIds.get()) : 0;
+ SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
+ if ( !SMESH::DownCast<SMESH_Mesh_i*>( object ))
+ {
+ SMESH::array_of_ElementType_var elemTypes = object->GetTypes();
+ if (( elemTypes->length() == 1 ) &&
+ ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE ))
+ elemType = ( SMDSAbs_ElementType ) elemTypes[0];
+ }
+ prepareIdSource( object );
+ SMESH::long_array_var anElementsId = object->GetIDs();
+ SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, elemType );
- SMESH_CATCH( SMESH::throwCorbaException );
- return 0;
+ if (!myIsPreviewMode) {
+ dumpGroupsList(aPythonDump, aGroups);
+ aPythonDump << this << ".ExtrusionByNormal( " << object
+ << ", " << TVar( stepSize )
+ << ", " << TVar( nbOfSteps )
+ << ", " << byAverageNormal
+ << ", " << makeGroups
+ << ", " << dim
+ << " )";
+ }
+ return aGroups;
}
//=======================================================================
CORBA::Double theSewTolerance)
throw (SALOME::SALOME_Exception)
{
+ ExtrusionParams params( theStepVector, theNbOfSteps, false, theExtrFlags, theSewTolerance);
+ extrusionSweep( theIDsOfElements, params );
+
if ( !myIsPreviewMode ) {
TPythonDump() << "stepVector = " << theStepVector;
TPythonDump() << this << ".AdvancedExtrusion("
<< theExtrFlags << ", "
<< theSewTolerance << " )";
}
- advancedExtrusion( theIDsOfElements,
- theStepVector,
- theNbOfSteps,
- theExtrFlags,
- theSewTolerance,
- false);
}
//=======================================================================
}
TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
- SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
- theStepVector,
- theNbOfSteps,
- theExtrFlags,
- theSewTolerance,
- true);
+ ExtrusionParams params( theStepVector, theNbOfSteps, true, theExtrFlags, theSewTolerance);
+ SMESH::ListOfGroups * aGroups = extrusionSweep( theIDsOfElements, params );
if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups);
namespace MeshEditor_I {
struct TPreviewMesh;
+ struct ExtrusionParams;
}
class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
const SMESH::DirStruct & StepVector,
CORBA::Long NbOfSteps)
throw (SALOME::SALOME_Exception);
+ SMESH::ListOfGroups* ExtrusionByNormal(SMESH::SMESH_IDSource_ptr object,
+ CORBA::Double stepSize,
+ CORBA::Long nbOfSteps,
+ CORBA::Boolean byAverageNormal,
+ CORBA::Boolean useInputElemsOnly,
+ CORBA::Boolean makeGroups,
+ CORBA::Short dim)
+ throw (SALOME::SALOME_Exception);
void AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
const SMESH::DirStruct & theStepVector,
CORBA::Long theNbOfSteps,
const bool MakeGroups,
const SMDSAbs_ElementType ElementType=SMDSAbs_All)
throw (SALOME::SALOME_Exception);
- SMESH::ListOfGroups* extrusionSweep(const SMESH::long_array & IDsOfElements,
- const SMESH::DirStruct & StepVector,
- CORBA::Long NbOfSteps,
- bool MakeGroups,
- const SMDSAbs_ElementType ElementType=SMDSAbs_All)
+ SMESH::ListOfGroups* extrusionSweep(const SMESH::long_array & IDsOfElements,
+ MeshEditor_I::ExtrusionParams& params,
+ const SMDSAbs_ElementType ElementType=SMDSAbs_All)
throw (SALOME::SALOME_Exception);
SMESH::ListOfGroups* advancedExtrusion(const SMESH::long_array & theIDsOfElements,
const SMESH::DirStruct & theStepVector,
# them with quadratic with the same id.
# @param theForce3d new node creation method:
# 0 - the medium node lies at the geometrical entity from which the mesh element is built
- # 1 - the medium node lies at the middle of the line segments connecting start and end node of a mesh element
+ # 1 - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
# @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal
# @param theToBiQuad If True, converts the mesh to bi-quadratic
# @ingroup l2_modif_tofromqu
ExtrFlags, SewTolerance)
return []
+ ## Generates new elements by extrusion along the normal to a discretized surface or wire
+ # @param Elements container of elements to extrude;
+ # it can be Mesh, Group, Sub-mesh, Filter or list of IDs;
+ # Only faces can be extruded so far. Sub-mesh sould be a sub-mesh on geom faces.
+ # @param StepSize length of one extrusion step (the total extrusion
+ # length will be \a NbOfSteps * \a StepSize ).
+ # @param NbOfSteps number of extrusion steps.
+ # @param ByAverageNormal if True each node is translated by \a StepSize
+ # along the average of the normal vectors to the faces sharing the node;
+ # else each node is translated along the same average normal till
+ # intersection with the plane got by translation of the face sharing
+ # the node along its own normal by \a StepSize.
+ # @param UseInputElemsOnly to use only \a Elements when computing extrusion direction
+ # for every node of \a Elements.
+ # @param MakeGroups forces generation of new groups from existing ones.
+ # @param Dim dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
+ # is not yet implemented. This parameter is used if \a Elements contains
+ # both faces and edges, i.e. \a Elements is a Mesh.
+ # @return the list of created groups (SMESH_GroupBase) if \a MakeGroups=True,
+ # empty list otherwise.
+ # @ingroup l2_modif_extrurev
+ def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
+ ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
+ unRegister = genObjUnRegister()
+ if isinstance( Elements, Mesh ):
+ Elements = Elements.GetMesh()
+ if isinstance( Elements, list ):
+ if not Elements:
+ raise RuntimeError, "List of element IDs is empty!"
+ if not isinstance( Elements[0], int ):
+ raise RuntimeError, "List must contain element IDs and not %s"% Elements[0]
+ Elements = self.GetIDSource( Elements, SMESH.ALL )
+ unRegister.set( Elements )
+ StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
+ self.mesh.SetParameters(Parameters)
+ return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
+ UseInputElemsOnly, ByAverageNormal, MakeGroups, Dim)
+
## Generates new elements by extrusion of the elements which belong to the object
# @param theObject the object which elements should be processed.
# It can be a mesh, a sub mesh or a group.