22833: [CEA 1346] to extrude a group of faces following the normal of each face

+ Optimize Belong to geom filter
+ Avoid SIGSEGV after re-computing a mesh if showing numbers was ON before
This commit is contained in:
eap 2015-01-23 18:49:49 +03:00
parent 12539a5a55
commit b13aae09cf
32 changed files with 1185 additions and 426 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
doc/salome/gui/SMESH/images/image76.jpg Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
doc/salome/gui/SMESH/images/image77.jpg Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -9,9 +9,9 @@ used for meshing entities (1D, 2D, 3D) composing geometrical objects.
<li>For meshing of 1D entities (<b>edges</b>):</li> <li>For meshing of 1D entities (<b>edges</b>):</li>
<ul> <ul>
<li>Wire Discretization meshing algorithm - splits a wire into a <li>Wire Discretization meshing algorithm - splits an edge into a
number of mesh segments following any 1D hypothesis.</li> number of mesh segments following an 1D hypothesis.</li>
<li>Composite Side Discretization algorithm - allows to apply any 1D <li>Composite Side Discretization algorithm - allows to apply an 1D
hypothesis to a whole side of a geometrical face even if it is 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 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 same hypotheses assigned and form one side in all faces of the main

View File

@ -314,8 +314,14 @@ click "Compute" button of the toolbar.
</center> </center>
After the mesh computation finishes, the Mesh Computation information After the mesh computation finishes, the Mesh Computation information
box appears. In case of a success, the box shows box appears. If you close this box and click "Compute" button again,
information on number of entities of different types in the mesh. 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 \image html meshcomputationsucceed.png

View File

@ -5,7 +5,11 @@
\n Extrusion is used to build mesh elements of plus one \n Extrusion is used to build mesh elements of plus one
dimension than the input ones. Boundary elements around elements of dimension than the input ones. Boundary elements around elements of
plus one dimension are additionally created. All created elements 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 <p>Any node, segment or 2D element can be extruded. Each type of
elements is extruded into a corresponding type of result elements: elements is extruded into a corresponding type of result elements:
<table> <table>
@ -28,12 +32,14 @@ elements is extruded into a corresponding type of result elements:
<em>"Extrusion" button</em> <em>"Extrusion" button</em>
</center> </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 extrusionalongaline1.png
\image html extrusionalongaline2.png \image html extrusionalongaline2.png
\image html extrusionalongaline3.png
</li> </li>
<li>In this dialog: <li>In this dialog:
@ -43,7 +49,7 @@ The following dialog common for line and planar elements will appear:
<li>Specify the IDs of the elements which will be extruded by one <li>Specify the IDs of the elements which will be extruded by one
following means: following means:
<ul> <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> checkbox.</li>
<li>Choose mesh elements with the mouse in the 3D Viewer. It is <li>Choose mesh elements with the mouse in the 3D Viewer. It is
possible to select a whole area with a mouse frame.</li> possible to select a whole area with a mouse frame.</li>
@ -54,35 +60,75 @@ The following dialog common for line and planar elements will appear:
the \ref filtering_elements "Selection filters" page.</li> the \ref filtering_elements "Selection filters" page.</li>
</ul> </ul>
</li> </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> <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> </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> <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 will be extruded, or select the face (the normal to the face will
define the vector),</li> 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> </ul>
<li>Specify the number of steps.</li> <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 <b>Number of steps</b>.</li>
<li>If you activate <b>Generate Groups</b> check-box, the <em>result elements</em> <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 included into new groups named by pattern "<old group
name>_extruded" and "<old group name>_top". For example if an name>_extruded" and "<old group name>_top". For example if a
extruded quadrangle is included in \a Group_1 group then result selected quadrangle is included in \a g_Faces group (see figures
hexahedra will be included in \a Group_1_extruded group and a below) then result hexahedra will be included in \a
quadrangle created at the "top" of extruded mesh will g_Faces_extruded group and a quadrangle created at the "top" of
be included in \a Group_1_top group. <br>This check-box is active extruded mesh will be included in \a g_Faces_top group. <br>
only if there are some groups in the mesh.</li> \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> </ul>
<li>Click \b Apply or <b> Apply and Close</b> button to confirm the operation.</li> <li>Click \b Apply or <b> Apply and Close</b> button to confirm the operation.</li>
</ol> </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 <br><b>See Also</b> a sample TUI Script of an
\ref tui_extrusion "Extrusion" operation. \ref tui_extrusion "Extrusion" operation.

View File

@ -39,7 +39,8 @@ with consequent transformation of all adjacent elements and edges.</li>
<li>\subpage split_to_tetra_page "Split" volumic elements into tetrahedra or prisms.</li> <li>\subpage split_to_tetra_page "Split" volumic elements into tetrahedra or prisms.</li>
<li>\subpage smoothing_page "Smooth" elements, reducung distortions in <li>\subpage smoothing_page "Smooth" elements, reducung distortions in
them by adjusting the locations of element corners.</li> 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 \subpage extrusion_along_path_page "extrusion along a path".</li>
<li>Create an edge or a surface by \subpage revolution_page "revolution" <li>Create an edge or a surface by \subpage revolution_page "revolution"
of the selected node or edge.</li> of the selected node or edge.</li>

View File

@ -130,7 +130,7 @@ Object Browser and select Clear Mesh Data in the pop-up menu.</li>
<li> if the mesh is computed on a geometry, then "Clear Mesh Data" removes <li> if the mesh is computed on a geometry, then "Clear Mesh Data" removes
all elements and nodes.</li> all elements and nodes.</li>
<li> if the mesh is not based on a geometry (imported, compound, created from <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> 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 <br><b>See Also</b> a sample TUI Script of a

View File

@ -587,6 +587,14 @@ module SMESH
in DirStruct StepVector, in DirStruct StepVector,
in long NbOfSteps) in long NbOfSteps)
raises (SALOME::SALOME_Exception); 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 { enum Extrusion_Error {
EXTR_OK, EXTR_OK,

View File

@ -1526,7 +1526,7 @@ SMDSAbs_ElementType Length::GetType() const
*/ */
//================================================================================ //================================================================================
double Length2D::GetValue( long theElementId) double Length2D::GetValue( long theElementId )
{ {
TSequenceOfXYZ P; TSequenceOfXYZ P;
@ -1558,7 +1558,7 @@ double Length2D::GetValue( long theElementId)
double L1 = getDistance(P( 1 ),P( 2 )); double L1 = getDistance(P( 1 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 3 )); double L2 = getDistance(P( 2 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 1 )); double L3 = getDistance(P( 3 ),P( 1 ));
aVal = Max(L1,Max(L2,L3)); aVal = Min(L1,Min(L2,L3));
break; break;
} }
else if (len == 4){ // quadrangles else if (len == 4){ // quadrangles
@ -1566,14 +1566,14 @@ double Length2D::GetValue( long theElementId)
double L2 = getDistance(P( 2 ),P( 3 )); double L2 = getDistance(P( 2 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 4 )); double L3 = getDistance(P( 3 ),P( 4 ));
double L4 = getDistance(P( 4 ),P( 1 )); double L4 = getDistance(P( 4 ),P( 1 ));
aVal = Max(Max(L1,L2),Max(L3,L4)); aVal = Min(Min(L1,L2),Min(L3,L4));
break; break;
} }
if (len == 6){ // quadratic triangles if (len == 6){ // quadratic triangles
double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); 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 L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 )); 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; //cout<<"L1="<<L1<<" L2="<<L2<<"L3="<<L3<<" aVal="<<aVal<<endl;
break; break;
} }
@ -1582,7 +1582,7 @@ double Length2D::GetValue( long theElementId)
double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); 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 L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 ));
double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 )); 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; break;
} }
case SMDSAbs_Volume: case SMDSAbs_Volume:
@ -1593,7 +1593,7 @@ double Length2D::GetValue( long theElementId)
double L4 = getDistance(P( 1 ),P( 4 )); double L4 = getDistance(P( 1 ),P( 4 ));
double L5 = getDistance(P( 2 ),P( 4 )); double L5 = getDistance(P( 2 ),P( 4 ));
double L6 = getDistance(P( 3 ),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; break;
} }
else if (len == 5){ // piramids else if (len == 5){ // piramids
@ -1606,8 +1606,8 @@ double Length2D::GetValue( long theElementId)
double L7 = getDistance(P( 3 ),P( 5 )); double L7 = getDistance(P( 3 ),P( 5 ));
double L8 = getDistance(P( 4 ),P( 5 )); double L8 = getDistance(P( 4 ),P( 5 ));
aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Max(aVal,Max(L7,L8)); aVal = Min(aVal,Min(L7,L8));
break; break;
} }
else if (len == 6){ // pentaidres else if (len == 6){ // pentaidres
@ -1621,8 +1621,8 @@ double Length2D::GetValue( long theElementId)
double L8 = getDistance(P( 2 ),P( 5 )); double L8 = getDistance(P( 2 ),P( 5 ));
double L9 = getDistance(P( 3 ),P( 6 )); double L9 = getDistance(P( 3 ),P( 6 ));
aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Max(aVal,Max(Max(L7,L8),L9)); aVal = Min(aVal,Min(Min(L7,L8),L9));
break; break;
} }
else if (len == 8){ // hexaider else if (len == 8){ // hexaider
@ -1639,9 +1639,9 @@ double Length2D::GetValue( long theElementId)
double L11= getDistance(P( 3 ),P( 7 )); double L11= getDistance(P( 3 ),P( 7 ));
double L12= getDistance(P( 4 ),P( 8 )); double L12= getDistance(P( 4 ),P( 8 ));
aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10))); aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10)));
aVal = Max(aVal,Max(L11,L12)); aVal = Min(aVal,Min(L11,L12));
break; break;
} }
@ -1653,7 +1653,7 @@ double Length2D::GetValue( long theElementId)
double L4 = getDistance(P( 1 ),P( 8 )) + getDistance(P( 8 ),P( 4 )); 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 L5 = getDistance(P( 2 ),P( 9 )) + getDistance(P( 9 ),P( 4 ));
double L6 = getDistance(P( 3 ),P( 10 )) + getDistance(P( 10 ),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; break;
} }
else if (len == 13){ // quadratic piramids else if (len == 13){ // quadratic piramids
@ -1665,8 +1665,8 @@ double Length2D::GetValue( long theElementId)
double L6 = getDistance(P( 2 ),P( 11 )) + getDistance(P( 11 ),P( 5 )); 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 L7 = getDistance(P( 3 ),P( 12 )) + getDistance(P( 12 ),P( 5 ));
double L8 = getDistance(P( 4 ),P( 13 )) + getDistance(P( 13 ),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 = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Max(aVal,Max(L7,L8)); aVal = Min(aVal,Min(L7,L8));
break; break;
} }
else if (len == 15){ // quadratic pentaidres else if (len == 15){ // quadratic pentaidres
@ -1679,8 +1679,8 @@ double Length2D::GetValue( long theElementId)
double L7 = getDistance(P( 1 ),P( 13 )) + getDistance(P( 13 ),P( 4 )); 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 L8 = getDistance(P( 2 ),P( 14 )) + getDistance(P( 14 ),P( 5 ));
double L9 = getDistance(P( 3 ),P( 15 )) + getDistance(P( 15 ),P( 6 )); 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 = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Max(aVal,Max(Max(L7,L8),L9)); aVal = Min(aVal,Min(Min(L7,L8),L9));
break; break;
} }
else if (len == 20){ // quadratic hexaider else if (len == 20){ // quadratic hexaider
@ -1696,9 +1696,9 @@ double Length2D::GetValue( long theElementId)
double L10= getDistance(P( 2 ),P( 18 )) + getDistance(P( 18 ),P( 6 )); 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 L11= getDistance(P( 3 ),P( 19 )) + getDistance(P( 19 ),P( 7 ));
double L12= getDistance(P( 4 ),P( 20 )) + getDistance(P( 20 ),P( 8 )); 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 = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10))); aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10)));
aVal = Max(aVal,Max(L11,L12)); aVal = Min(aVal,Min(L11,L12));
break; break;
} }
@ -1706,7 +1706,7 @@ double Length2D::GetValue( long theElementId)
default: aVal=-1; default: aVal=-1;
} }
if (aVal <0){ if (aVal < 0 ) {
return 0.; return 0.;
} }
@ -1724,7 +1724,7 @@ double Length2D::GetValue( long theElementId)
double Length2D::GetBadRate( double Value, int /*nbNodes*/ ) const 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; return Value;
} }
@ -3999,7 +3999,41 @@ void ElementsOnShape::SetAllNodes (bool theAllNodes)
void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh) 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, void ElementsOnShape::SetShape (const TopoDS_Shape& theShape,
@ -4026,6 +4060,16 @@ void ElementsOnShape::SetShape (const TopoDS_Shape& theShape,
myClassifiers.resize( shapesMap.Extent() ); myClassifiers.resize( shapesMap.Extent() );
for ( int i = 0; i < shapesMap.Extent(); ++i ) for ( int i = 0; i < shapesMap.Extent(); ++i )
myClassifiers[ i ] = new TClassifier( shapesMap( i+1 ), myToler ); 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() void ElementsOnShape::clearClassifiers()
@ -4037,23 +4081,30 @@ void ElementsOnShape::clearClassifiers()
bool ElementsOnShape::IsSatisfy (long elemId) bool ElementsOnShape::IsSatisfy (long elemId)
{ {
const SMDS_Mesh* mesh = myMeshModifTracer.GetMesh();
const SMDS_MeshElement* elem = 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() ) if ( !elem || myClassifiers.empty() )
return false; return false;
for ( size_t i = 0; i < myClassifiers.size(); ++i ) for ( size_t i = 0; i < myClassifiers.size(); ++i )
{ {
SMDS_ElemIteratorPtr aNodeItr = elem->nodesIterator(); SMDS_ElemIteratorPtr aNodeItr = elem->nodesIterator();
bool isSatisfy = myAllNodesFlag; bool isSatisfy = myAllNodesFlag, isNodeOut;
gp_XYZ centerXYZ (0, 0, 0); gp_XYZ centerXYZ (0, 0, 0);
while (aNodeItr->more() && (isSatisfy == myAllNodesFlag)) while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
{ {
SMESH_TNodeXYZ aPnt ( aNodeItr->next() ); const SMDS_MeshNode* n = (const SMDS_MeshNode*) aNodeItr->next();
centerXYZ += aPnt; if ( !getNodeIsOut( n, isNodeOut ))
isSatisfy = ! myClassifiers[i]->IsOut( aPnt ); {
SMESH_TNodeXYZ aPnt( n );
centerXYZ += aPnt;
isNodeOut = myClassifiers[i]->IsOut( aPnt );
setNodeIsOut( n, isNodeOut );
}
isSatisfy = !isNodeOut;
} }
// Check the center point for volumes MantisBug 0020168 // Check the center point for volumes MantisBug 0020168

View File

@ -867,14 +867,18 @@ namespace SMESH{
double myTol; double myTol;
}; };
void clearClassifiers(); void clearClassifiers();
bool getNodeIsOut( const SMDS_MeshNode* n, bool& isOut );
void setNodeIsOut( const SMDS_MeshNode* n, bool isOut );
std::vector< TClassifier* > myClassifiers; std::vector< TClassifier* > myClassifiers;
const SMDS_Mesh* myMesh;
SMDSAbs_ElementType myType; SMDSAbs_ElementType myType;
TopoDS_Shape myShape; TopoDS_Shape myShape;
double myToler; double myToler;
bool myAllNodesFlag; bool myAllNodesFlag;
TMeshModifTracer myMeshModifTracer;
std::vector<bool> myNodeIsChecked;
std::vector<bool> myNodeIsOut;
}; };
typedef boost::shared_ptr<ElementsOnShape> ElementsOnShapePtr; typedef boost::shared_ptr<ElementsOnShape> ElementsOnShapePtr;

View File

@ -151,48 +151,56 @@ SMESH_VisualObjDef::~SMESH_VisualObjDef()
//================================================================================= //=================================================================================
vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID ) vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID )
{ {
if (myLocalGrid) if (myLocalGrid)
{ {
TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID); TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
return i == myVTK2SMDSNodes.end() ? -1 : i->second; return i == myVTK2SMDSNodes.end() ? -1 : i->second;
} }
return this->GetMesh()->FindNodeVtk(theVTKID)->GetID(); const SMDS_MeshNode* aNode = 0;
if( this->GetMesh() )
aNode = this->GetMesh()->FindNodeVtk( theVTKID );
return aNode ? aNode->GetID() : -1;
} }
vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID ) vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
{ {
if (myLocalGrid) if (myLocalGrid)
{ {
TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID); TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID);
return i == mySMDS2VTKNodes.end() ? -1 : i->second; return i == mySMDS2VTKNodes.end() ? -1 : i->second;
} }
const SMDS_MeshNode* aNode = 0; const SMDS_MeshNode* aNode = 0;
if( this->GetMesh() ) { if( this->GetMesh() ) {
aNode = this->GetMesh()->FindNode(theObjID); aNode = this->GetMesh()->FindNode(theObjID);
} }
return aNode ? aNode->getVtkId() : -1; return aNode ? aNode->getVtkId() : -1;
} }
vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID ) vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
{ {
if (myLocalGrid) if (myLocalGrid)
{ {
TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID); TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
return i == myVTK2SMDSElems.end() ? -1 : i->second; return i == myVTK2SMDSElems.end() ? -1 : i->second;
} }
return this->GetMesh()->fromVtkToSmds(theVTKID); return this->GetMesh()->fromVtkToSmds(theVTKID);
} }
vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID ) vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
{ {
if (myLocalGrid) if (myLocalGrid)
{ {
TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID); TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID);
return i == mySMDS2VTKElems.end() ? -1 : i->second; return i == mySMDS2VTKElems.end() ? -1 : i->second;
} }
return this->GetMesh()->FindElement(theObjID)->getVtkId();
//return this->GetMesh()->fromSmdsToVtk(theObjID); const SMDS_MeshElement* e = 0;
if ( this->GetMesh() )
e = this->GetMesh()->FindElement(theObjID);
return e ? e->getVtkId() : -1;
} }
//================================================================================= //=================================================================================

View File

@ -79,7 +79,7 @@ public:
virtual int NbNodes() const; virtual int NbNodes() const;
virtual int NbEdges() const; virtual int NbEdges() const;
virtual int NbFaces() const; virtual int NbFaces() const;
inline int GetID() const { return myID; }; inline int GetID() const { return myID; }
///Return the type of the current element ///Return the type of the current element
virtual SMDSAbs_ElementType GetType() const = 0; virtual SMDSAbs_ElementType GetType() const = 0;

View File

@ -403,7 +403,8 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh,
bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theMesh, bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theMesh,
const TopoDS_Edge& theEdge, const TopoDS_Edge& theEdge,
const bool ignoreMediumNodes, const bool ignoreMediumNodes,
map< double, const SMDS_MeshNode* > & theNodes) map< double, const SMDS_MeshNode* > & theNodes,
const SMDSAbs_ElementType typeToCheck)
{ {
theNodes.clear(); theNodes.clear();
@ -423,11 +424,8 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theM
while ( nIt->more() ) while ( nIt->more() )
{ {
const SMDS_MeshNode* node = nIt->next(); const SMDS_MeshNode* node = nIt->next();
if ( ignoreMediumNodes ) { if ( ignoreMediumNodes && SMESH_MesherHelper::IsMedium( node, typeToCheck ))
SMDS_ElemIteratorPtr elemIt = node->GetInverseElementIterator(); continue;
if ( elemIt->more() && elemIt->next()->IsMediumNode( node ))
continue;
}
const SMDS_PositionPtr& pos = node->GetPosition(); const SMDS_PositionPtr& pos = node->GetPosition();
if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE ) if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE )
return false; return false;

View File

@ -323,12 +323,14 @@ public:
* \param theEdge - The geometrical edge of interest * \param theEdge - The geometrical edge of interest
* \param theNodes - The resulting map * \param theNodes - The resulting map
* \param ignoreMediumNodes - to store medium nodes of quadratic elements or not * \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 * \retval bool - false if not all parameters are OK
*/ */
static bool GetSortedNodesOnEdge(const SMESHDS_Mesh* theMesh, static bool GetSortedNodesOnEdge(const SMESHDS_Mesh* theMesh,
const TopoDS_Edge& theEdge, const TopoDS_Edge& theEdge,
const bool ignoreMediumNodes, 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 * Moved to SMESH_MesherHelper
*/ */

View File

@ -2180,10 +2180,6 @@ namespace
void SMESH_MeshEditor::SplitVolumes (const TFacetOfElem & theElems, void SMESH_MeshEditor::SplitVolumes (const TFacetOfElem & theElems,
const int theMethodFlags) 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; SMDS_VolumeTool volTool;
SMESH_MesherHelper helper( *GetMesh()), fHelper(*GetMesh()); SMESH_MesherHelper helper( *GetMesh()), fHelper(*GetMesh());
fHelper.ToFixNodeParameters( true ); fHelper.ToFixNodeParameters( true );
@ -4339,6 +4335,29 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem,
} }
} }
} }
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; int iSameNode = 0, iBeforeSame = 0, iAfterSame = 0, iOpposSame = 0;
if ( nbSame > 0 ) { if ( nbSame > 0 ) {
@ -4444,11 +4463,11 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem,
return; // medium node on axis return; // medium node on axis
} }
else if(sames[0]==0) else if(sames[0]==0)
aNewElem = aMesh->AddFace(prevNod[0], nextNod[1], prevNod[1], aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[1],
nextNod[2], midlNod[1], prevNod[2]); prevNod[2], midlNod[1], nextNod[2] );
else // sames[0]==1 else // sames[0]==1
aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], prevNod[1], aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[0],
midlNod[0], nextNod[2], prevNod[2]); prevNod[2], nextNod[2], midlNod[0]);
} }
} }
else if ( nbDouble == 3 ) else if ( nbDouble == 3 )
@ -4614,8 +4633,8 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem,
default: default:
break; break;
} } // switch ( baseType )
} } // scope
if ( !aNewElem && elem->GetType() == SMDSAbs_Face ) // try to create a polyherdal prism if ( !aNewElem && elem->GetType() == SMDSAbs_Face ) // try to create a polyherdal prism
{ {
@ -4669,7 +4688,8 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem,
polyedre_nodes.resize( prevNbNodes ); polyedre_nodes.resize( prevNbNodes );
} }
aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities); aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities);
}
} // // try to create a polyherdal prism
if ( aNewElem ) { if ( aNewElem ) {
newElems.push_back( aNewElem ); newElems.push_back( aNewElem );
@ -4681,7 +4701,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem,
for ( iNode = 0; iNode < nbNodes; iNode++ ) for ( iNode = 0; iNode < nbNodes; iNode++ )
prevNod[ iNode ] = nextNod[ iNode ]; prevNod[ iNode ] = nextNod[ iNode ];
} // for steps } // loop on steps
} }
//======================================================================= //=======================================================================
@ -5218,50 +5238,328 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
return newGroupIDs; return newGroupIDs;
} }
//=======================================================================
//function : ExtrusParam
//purpose : standard construction
//=======================================================================
//======================================================================= SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec& theStep,
//function : CreateNode const int theNbSteps,
//purpose : const int theFlags,
//======================================================================= const double theTolerance):
const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x, myDir( theStep ),
const double y, myFlags( theFlags ),
const double z, myTolerance( theTolerance ),
const double tolnode, myElemsToUse( NULL )
SMESH_SequenceOfNode& aNodes)
{ {
// myLastCreatedElems.Clear(); mySteps = new TColStd_HSequenceOfReal;
// myLastCreatedNodes.Clear(); const double stepSize = theStep.Magnitude();
for (int i=1; i<=theNbSteps; i++ )
mySteps->Append( stepSize );
gp_Pnt P1(x,y,z); if (( theFlags & EXTRUSION_FLAG_SEW ) &&
SMESHDS_Mesh * aMesh = myMesh->GetMeshDS(); ( theTolerance > 0 ))
{
// try to search in sequence of existing nodes myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByDirAndSew;
// 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);
}
} }
else { else
SMDS_NodeIteratorPtr itn = aMesh->nodesIterator(); {
while(itn->more()) { myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByDir;
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;
}
} }
// create new node and return it
const SMDS_MeshNode* NewNode = aMesh->AddNode(x,y,z);
//myLastCreatedNodes.Append(NewNode);
return NewNode;
} }
//=======================================================================
//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 : ExtrusParam
//purpose : for extrusion by normal
//=======================================================================
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 )
{
for (int i = 0; i < theNbSteps; i++ )
mySteps->Append( theStepSize );
if ( theDim == 1 )
{
myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByNormal1D;
}
else
{
myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByNormal2D;
}
}
//=======================================================================
//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();
}
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 );
}
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 //function : ExtrusionSweep
@ -5273,20 +5571,11 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
const gp_Vec& theStep, const gp_Vec& theStep,
const int theNbSteps, const int theNbSteps,
TTElemOfElemListMap& newElemsMap, TTElemOfElemListMap& newElemsMap,
const bool theMakeGroups,
const int theFlags, const int theFlags,
const double theTolerance) const double theTolerance)
{ {
ExtrusParam aParams; ExtrusParam aParams( theStep, theNbSteps, theFlags, theTolerance );
aParams.myDir = gp_Dir(theStep); return ExtrusionSweep( theElems, aParams, newElemsMap );
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);
} }
@ -5298,10 +5587,7 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
SMESH_MeshEditor::PGroupIDs SMESH_MeshEditor::PGroupIDs
SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
ExtrusParam& theParams, ExtrusParam& theParams,
TTElemOfElemListMap& newElemsMap, TTElemOfElemListMap& newElemsMap)
const bool theMakeGroups,
const int theFlags,
const double theTolerance)
{ {
myLastCreatedElems.Clear(); myLastCreatedElems.Clear();
myLastCreatedNodes.Clear(); myLastCreatedNodes.Clear();
@ -5311,7 +5597,8 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
SMESHDS_Mesh* aMesh = GetMeshDS(); SMESHDS_Mesh* aMesh = GetMeshDS();
int nbsteps = theParams.mySteps->Length(); const int nbSteps = theParams.NbSteps();
theParams.SetElementsToUse( theElems );
TNodeOfNodeListMap mapNewNodes; TNodeOfNodeListMap mapNewNodes;
//TNodeOfNodeVecMap mapNewNodes; //TNodeOfNodeVecMap mapNewNodes;
@ -5323,14 +5610,16 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
myMesh->NbVolumes(ORDER_QUADRATIC) ); myMesh->NbVolumes(ORDER_QUADRATIC) );
// loop on theElems // loop on theElems
TIDSortedElemSet::iterator itElem; TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
{
// check element type // check element type
const SMDS_MeshElement* elem = *itElem; const SMDS_MeshElement* elem = *itElem;
if ( !elem || elem->GetType() == SMDSAbs_Volume ) if ( !elem || elem->GetType() == SMDSAbs_Volume )
continue; continue;
const size_t nbNodes = elem->NbNodes();
vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ]; vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
newNodesItVec.reserve( elem->NbNodes() ); newNodesItVec.reserve( nbNodes );
// loop on elem nodes // loop on elem nodes
SMDS_ElemIteratorPtr itN = elem->nodesIterator(); SMDS_ElemIteratorPtr itN = elem->nodesIterator();
@ -5359,55 +5648,33 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems,
needMediumNodes = true; needMediumNodes = true;
} }
} }
// create nodes for all steps
double coord[] = { node->X(), node->Y(), node->Z() }; if ( theParams.MakeNodes( GetMeshDS(), node, listNewNodes, needMediumNodes ))
for ( int i = 0; i < nbsteps; i++ )
{ {
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.; myLastCreatedNodes.Append( *newNodesIt );
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);
srcNodes.Append( node ); srcNodes.Append( node );
listNewNodes.push_back( newNode );
} }
} }
else
{
break; // newNodesItVec will be shorter than nbNodes
}
} }
newNodesItVec.push_back( nIt ); newNodesItVec.push_back( nIt );
} }
// make new elements // 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 ) { if ( theParams.ToMakeBoundary() ) {
makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps, srcElems ); makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbSteps, srcElems );
} }
PGroupIDs newGroupIDs; PGroupIDs newGroupIDs;
if ( theMakeGroups ) if ( theParams.ToMakeGroups() )
newGroupIDs = generateGroups( srcNodes, srcElems, "extruded"); newGroupIDs = generateGroups( srcNodes, srcElems, "extruded");
return newGroupIDs; return newGroupIDs;

View File

@ -240,33 +240,98 @@ public:
// by theAngle by theNbSteps // by theAngle by theNbSteps
/*! /*!
* Auxilary flag for advanced extrusion. * Flags of extrusion.
* BOUNDARY: create or not boundary for result of extrusion * BOUNDARY: create or not boundary for result of extrusion
* SEW: try to use existing nodes or create new nodes in any case * 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 { enum ExtrusionFlags {
EXTRUSION_FLAG_BOUNDARY = 0x01, 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 { class ExtrusParam {
gp_Dir myDir; // direction of extrusion gp_Dir myDir; // direction of extrusion
Handle(TColStd_HSequenceOfReal) mySteps; // magnitudes for each step 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,
* Create new node in the mesh with given coordinates const SMDS_MeshNode* srcNode,
* (auxiliary for advanced extrusion) std::list<const SMDS_MeshNode*> & newNodes,
*/ const bool makeMediumNodes);
const SMDS_MeshNode* CreateNode(const double x,
const double y, public:
const double z, ExtrusParam( const gp_Vec& theStep,
const double tolnode, const int theNbSteps,
SMESH_SequenceOfNode& aNodes); 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;
};
/*! /*!
* Generate new elements by extrusion of theElements * Generate new elements by extrusion of theElements
@ -284,8 +349,7 @@ public:
const gp_Vec& theStep, const gp_Vec& theStep,
const int theNbSteps, const int theNbSteps,
TTElemOfElemListMap& newElemsMap, TTElemOfElemListMap& newElemsMap,
const bool theMakeGroups, const int theFlags,
const int theFlags = EXTRUSION_FLAG_BOUNDARY,
const double theTolerance = 1.e-6); const double theTolerance = 1.e-6);
/*! /*!
@ -300,10 +364,7 @@ public:
*/ */
PGroupIDs ExtrusionSweep (TIDSortedElemSet & theElems, PGroupIDs ExtrusionSweep (TIDSortedElemSet & theElems,
ExtrusParam& theParams, ExtrusParam& theParams,
TTElemOfElemListMap& newElemsMap, TTElemOfElemListMap& newElemsMap);
const bool theMakeGroups,
const int theFlags,
const double theTolerance);
// Generate new elements by extrusion of theElements // Generate new elements by extrusion of theElements

View File

@ -116,20 +116,20 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
ConstructorsBoxLayout->setSpacing(SPACING); ConstructorsBoxLayout->setSpacing(SPACING);
ConstructorsBoxLayout->setMargin(MARGIN); ConstructorsBoxLayout->setMargin(MARGIN);
RadioButton0= new QRadioButton(ConstructorsBox); Contructor_RBut0= new QRadioButton(ConstructorsBox);
RadioButton0->setIcon(image3); Contructor_RBut0->setIcon(image3);
RadioButton1= new QRadioButton(ConstructorsBox); Contructor_RBut1= new QRadioButton(ConstructorsBox);
RadioButton1->setIcon(image0); Contructor_RBut1->setIcon(image0);
RadioButton2= new QRadioButton(ConstructorsBox); Contructor_RBut2= new QRadioButton(ConstructorsBox);
RadioButton2->setIcon(image1); Contructor_RBut2->setIcon(image1);
ConstructorsBoxLayout->addWidget(RadioButton0); ConstructorsBoxLayout->addWidget(Contructor_RBut0);
ConstructorsBoxLayout->addWidget(RadioButton1); ConstructorsBoxLayout->addWidget(Contructor_RBut1);
ConstructorsBoxLayout->addWidget(RadioButton2); ConstructorsBoxLayout->addWidget(Contructor_RBut2);
GroupConstructors->addButton(RadioButton0, 0); GroupConstructors->addButton(Contructor_RBut0, 0);
GroupConstructors->addButton(RadioButton1, 1); GroupConstructors->addButton(Contructor_RBut1, 1);
GroupConstructors->addButton(RadioButton2, 2); GroupConstructors->addButton(Contructor_RBut2, 2);
/***************************************************************/ /***************************************************************/
GroupButtons = new QGroupBox(this); GroupButtons = new QGroupBox(this);
@ -178,10 +178,12 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
// Control for the whole mesh selection // Control for the whole mesh selection
CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments); CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
RadioButton3 = new QRadioButton(GroupArguments); ExtrMethod_RBut0 = new QRadioButton(GroupArguments);
RadioButton3->setText( tr("SMESH_EXTRUSION_TO_DISTANCE") ); ExtrMethod_RBut0->setText( tr("SMESH_EXTRUSION_TO_DISTANCE") );
RadioButton4 = new QRadioButton(GroupArguments); ExtrMethod_RBut1 = new QRadioButton(GroupArguments);
RadioButton4->setText( tr("SMESH_EXTRUSION_ALONG_VECTOR") ); 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 //Control for the Distance selection
TextLabelDistance = new QLabel(tr("SMESH_DISTANCE"), GroupArguments); TextLabelDistance = new QLabel(tr("SMESH_DISTANCE"), GroupArguments);
@ -221,6 +223,12 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
// CheckBox for groups generation // CheckBox for groups generation
MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments); 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 //Preview check box
myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments); myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
@ -229,8 +237,9 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 5); GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 5);
GroupArgumentsLayout->addWidget(myFilterBtn, 0, 7); GroupArgumentsLayout->addWidget(myFilterBtn, 0, 7);
GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 8); GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 8);
GroupArgumentsLayout->addWidget(RadioButton3, 2, 1, 1, 3); GroupArgumentsLayout->addWidget(ExtrMethod_RBut0, 2, 0, 1, 3);
GroupArgumentsLayout->addWidget(RadioButton4, 2, 5, 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(TextLabelDistance, 3, 0);
GroupArgumentsLayout->addWidget(TextLabelDx, 3, 2); GroupArgumentsLayout->addWidget(TextLabelDx, 3, 2);
GroupArgumentsLayout->addWidget(SpinBox_Dx, 3, 3); GroupArgumentsLayout->addWidget(SpinBox_Dx, 3, 3);
@ -247,12 +256,14 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
GroupArgumentsLayout->addWidget(TextLabelVz, 4, 6); GroupArgumentsLayout->addWidget(TextLabelVz, 4, 6);
GroupArgumentsLayout->addWidget(SpinBox_Vz, 4, 7); GroupArgumentsLayout->addWidget(SpinBox_Vz, 4, 7);
GroupArgumentsLayout->addWidget(TextLabelDist, 5, 0); 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(TextLabelNbSteps, 6, 0, 1, 3);
GroupArgumentsLayout->addWidget(SpinBox_NbSteps, 6, 3); GroupArgumentsLayout->addWidget(SpinBox_NbSteps, 6, 3);
GroupArgumentsLayout->addWidget(myPreviewCheckBox, 7, 0, 1, 8); GroupArgumentsLayout->addWidget(ByAverageNormalCheck, 7, 0, 1, 4);
GroupArgumentsLayout->addWidget(MakeGroupsCheck, 8, 0, 1, 8); GroupArgumentsLayout->addWidget(UseInputElemsOnlyCheck, 7, 4, 1, 4);
GroupArgumentsLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 8, 0); 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);
/***************************************************************/ /***************************************************************/
@ -261,19 +272,20 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
SMESHGUI_ExtrusionDlgLayout->addWidget(GroupButtons); SMESHGUI_ExtrusionDlgLayout->addWidget(GroupButtons);
/* Initialisations */ /* Initialisations */
SpinBox_Vx->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.01, "length_precision"); SpinBox_Vy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.1, "length_precision");
SpinBox_Vz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.01, "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_Dx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
SpinBox_Dy->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_Dz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
SpinBox_NbSteps->setRange(1, 999999); 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); Contructor_RBut0->setChecked(true);
RadioButton3->setChecked(true); ExtrMethod_RBut0->setChecked(true);
UseInputElemsOnlyCheck->setChecked(true);
MakeGroupsCheck->setChecked(true); MakeGroupsCheck->setChecked(true);
mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
@ -309,8 +321,9 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply())); connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp())); connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
connect(RadioButton3, SIGNAL(clicked()), this, SLOT(ClickOnRadio())); connect(ExtrMethod_RBut0, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
connect(RadioButton4, 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 // to update state of the Ok & Apply buttons
connect(SpinBox_Vx, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable())); connect(SpinBox_Vx, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
@ -330,14 +343,16 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
connect(LineEditElements, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); connect(LineEditElements, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool))); connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool)));
connect(SpinBox_Dx, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); connect(SpinBox_Dx, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
connect(SpinBox_Dy, 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_Dz, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
connect(SpinBox_Vx, 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_Vy, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
connect(SpinBox_Vz, 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_VDist, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
connect(SpinBox_NbSteps, SIGNAL(valueChanged(int)), 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 //To Connect preview check box
connectPreviewControl(); connectPreviewControl();
@ -416,17 +431,22 @@ void SMESHGUI_ExtrusionDlg::CheckIsEnable()
//================================================================================= //=================================================================================
bool SMESHGUI_ExtrusionDlg::isValuesValid() { bool SMESHGUI_ExtrusionDlg::isValuesValid() {
double aX, aY, aZ, aModule = 0; double aX, aY, aZ, aModule = 0;
if ( RadioButton3->isChecked() ) { if ( ExtrMethod_RBut0->isChecked() ) {
aX = SpinBox_Dx->GetValue(); aX = SpinBox_Dx->GetValue();
aY = SpinBox_Dy->GetValue(); aY = SpinBox_Dy->GetValue();
aZ = SpinBox_Dz->GetValue(); aZ = SpinBox_Dz->GetValue();
aModule = sqrt(aX*aX + aY*aY + aZ*aZ); aModule = sqrt(aX*aX + aY*aY + aZ*aZ);
} else if ( RadioButton4->isChecked() ) { }
else if ( ExtrMethod_RBut1->isChecked() ) {
aX = SpinBox_Vx->GetValue(); aX = SpinBox_Vx->GetValue();
aY = SpinBox_Vy->GetValue(); aY = SpinBox_Vy->GetValue();
aZ = SpinBox_Vz->GetValue(); aZ = SpinBox_Vz->GetValue();
aModule = sqrt(aX*aX + aY*aY + aZ*aZ); aModule = sqrt(aX*aX + aY*aY + aZ*aZ);
} }
else if ( ExtrMethod_RBut2->isChecked() ) {
aModule = 1;
}
return aModule > 1.0E-38; return aModule > 1.0E-38;
} }
@ -481,6 +501,11 @@ void SMESHGUI_ExtrusionDlg::ConstructorsClicked (int constructorId)
} }
} }
ExtrMethod_RBut2->setVisible( constructorId == 2 );
if ( !ExtrMethod_RBut2->isVisible() &&
ExtrMethod_RBut2->isChecked() )
ExtrMethod_RBut0->click();
myEditCurrentArgument = (QWidget*)LineEditElements; myEditCurrentArgument = (QWidget*)LineEditElements;
LineEditElements->setFocus(); LineEditElements->setFocus();
@ -499,7 +524,8 @@ void SMESHGUI_ExtrusionDlg::ConstructorsClicked (int constructorId)
//================================================================================= //=================================================================================
void SMESHGUI_ExtrusionDlg::ClickOnRadio() void SMESHGUI_ExtrusionDlg::ClickOnRadio()
{ {
if ( RadioButton3->isChecked() ) { if ( ExtrMethod_RBut0->isChecked() )
{
TextLabelDistance->show(); TextLabelDistance->show();
TextLabelDx->show(); TextLabelDx->show();
SpinBox_Dx->show(); SpinBox_Dx->show();
@ -518,7 +544,12 @@ void SMESHGUI_ExtrusionDlg::ClickOnRadio()
TextLabelDist->hide(); TextLabelDist->hide();
SpinBox_VDist->hide(); SpinBox_VDist->hide();
SelectVectorButton->hide(); SelectVectorButton->hide();
} else if ( RadioButton4->isChecked() ) {
ByAverageNormalCheck->hide();
UseInputElemsOnlyCheck->hide();
}
else if ( ExtrMethod_RBut1->isChecked() )
{
TextLabelDistance->hide(); TextLabelDistance->hide();
TextLabelDx->hide(); TextLabelDx->hide();
SpinBox_Dx->hide(); SpinBox_Dx->hide();
@ -537,7 +568,38 @@ void SMESHGUI_ExtrusionDlg::ClickOnRadio()
TextLabelDist->show(); TextLabelDist->show();
SpinBox_VDist->show(); SpinBox_VDist->show();
SelectVectorButton->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); onDisplaySimulation(true);
// AdjustSize // AdjustSize
qApp->processEvents(); qApp->processEvents();
@ -563,79 +625,91 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
getExtrusionVector(aVector); getExtrusionVector(aVector);
QStringList aParameters; QStringList aParameters;
if ( RadioButton3->isChecked() ) { if ( ExtrMethod_RBut0->isChecked() )
{
aParameters << SpinBox_Dx->text(); aParameters << SpinBox_Dx->text();
aParameters << SpinBox_Dy->text(); aParameters << SpinBox_Dy->text();
aParameters << SpinBox_Dz->text(); aParameters << SpinBox_Dz->text();
} else if ( RadioButton4->isChecked() ) { }
else if ( ExtrMethod_RBut1->isChecked() )
{
// only 3 coords in a python dump command :( // only 3 coords in a python dump command :(
// aParameters << SpinBox_Vx->text(); // aParameters << SpinBox_Vx->text();
// aParameters << SpinBox_Vy->text(); // aParameters << SpinBox_Vy->text();
// aParameters << SpinBox_Vz->text(); // aParameters << SpinBox_Vz->text();
// aParameters << SpinBox_VDist->text(); // aParameters << SpinBox_VDist->text();
} }
else if ( ExtrMethod_RBut2->isChecked() )
{
aParameters << SpinBox_VDist->text();
}
long aNbSteps = (long)SpinBox_NbSteps->value(); long aNbSteps = (long)SpinBox_NbSteps->value();
aParameters << SpinBox_NbSteps->text(); aParameters << SpinBox_NbSteps->text();
bool meshHadNewTypeBefore = true;
try { try {
SUIT_OverrideCursor aWaitCursor; 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(); SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); myMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->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() ) if( CheckBoxMesh->isChecked() )
switch (GetConstructorId() ) { switch (GetConstructorId() ) {
case 0: case 0:
{ groups = aMeshEditor->ExtrusionSweepObject0DMakeGroups(mySelectedObject, aVector,
SMESH::ListOfGroups_var groups = aNbSteps); break;
aMeshEditor->ExtrusionSweepObject0DMakeGroups(mySelectedObject, aVector, aNbSteps); case 1:
break; groups = aMeshEditor->ExtrusionSweepObject1DMakeGroups(mySelectedObject, aVector,
} aNbSteps); break;
case 1: case 2:
{ groups = aMeshEditor->ExtrusionSweepObject2DMakeGroups(mySelectedObject, aVector,
SMESH::ListOfGroups_var groups = aNbSteps); break;
aMeshEditor->ExtrusionSweepObject1DMakeGroups(mySelectedObject, aVector, aNbSteps);
break;
}
case 2:
{
SMESH::ListOfGroups_var groups =
aMeshEditor->ExtrusionSweepObject2DMakeGroups(mySelectedObject, aVector, aNbSteps);
break;
}
} }
else else
{ {
SMESH::ListOfGroups_var groups;
if (GetConstructorId() == 0) if (GetConstructorId() == 0)
groups = aMeshEditor->ExtrusionSweepMakeGroups0D(myElementsId.inout(), aVector, aNbSteps); groups = aMeshEditor->ExtrusionSweepMakeGroups0D(myElementsId.inout(), aVector,
aNbSteps);
else else
groups = aMeshEditor->ExtrusionSweepMakeGroups(myElementsId.inout(), aVector, aNbSteps); groups = aMeshEditor->ExtrusionSweepMakeGroups(myElementsId.inout(), aVector,
aNbSteps);
} }
} }
else { else // no groups
{
if( CheckBoxMesh->isChecked() ) if( CheckBoxMesh->isChecked() )
switch( GetConstructorId() ) { switch( GetConstructorId() ) {
case 0: case 0:
{ aMeshEditor->ExtrusionSweepObject0D(mySelectedObject, aVector, aNbSteps);
aMeshEditor->ExtrusionSweepObject0D(mySelectedObject, aVector, aNbSteps); break;
break; case 1:
} aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps);
case 1: break;
{ case 2:
aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps); aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps);
break; break;
}
case 2:
{
aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps);
break;
} }
}
else else
if (GetConstructorId() == 0) if (GetConstructorId() == 0)
aMeshEditor->ExtrusionSweep0D(myElementsId.inout(), aVector, aNbSteps); aMeshEditor->ExtrusionSweep0D(myElementsId.inout(), aVector, aNbSteps);
@ -646,14 +720,29 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
} catch (...) { } 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); SMESH::Update(myIO, SMESH::eDisplay);
if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() )
mySMESHGUI->updateObjBrowser(true); // new groups may appear mySMESHGUI->updateObjBrowser(true); // new groups may appear
Init(false); Init(false);
ConstructorsClicked(GetConstructorId());
mySelectionMgr->clearSelected(); mySelectionMgr->clearSelected();
mySelectedObject = SMESH::SMESH_IDSource::_nil(); mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument(); SelectionIntoArgument();
ConstructorsClicked(GetConstructorId());
SMESHGUI::Modified(); SMESHGUI::Modified();
} }
@ -1160,11 +1249,11 @@ bool SMESHGUI_ExtrusionDlg::isValid()
{ {
QString msg; QString msg;
bool ok = true; bool ok = true;
if ( RadioButton3->isChecked() ) { if ( ExtrMethod_RBut0->isChecked() ) {
ok = SpinBox_Dx->isValid( msg, true ) && ok; ok = SpinBox_Dx->isValid( msg, true ) && ok;
ok = SpinBox_Dy->isValid( msg, true ) && ok; ok = SpinBox_Dy->isValid( msg, true ) && ok;
ok = SpinBox_Dz->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_Vx->isValid( msg, true ) && ok;
ok = SpinBox_Vy->isValid( msg, true ) && ok; ok = SpinBox_Vy->isValid( msg, true ) && ok;
ok = SpinBox_Vz->isValid( msg, true ) && ok; ok = SpinBox_Vz->isValid( msg, true ) && ok;
@ -1186,7 +1275,8 @@ bool SMESHGUI_ExtrusionDlg::isValid()
// function : onDisplaySimulation // function : onDisplaySimulation
// purpose : Show/Hide preview // purpose : Show/Hide preview
//================================================================================= //=================================================================================
void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview ) { void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview )
{
if (myPreviewCheckBox->isChecked() && toDisplayPreview) { if (myPreviewCheckBox->isChecked() && toDisplayPreview) {
if (myNbOkElements && isValid() && isValuesValid()) { if (myNbOkElements && isValid() && isValuesValid()) {
//Get input vector //Get input vector
@ -1195,35 +1285,43 @@ void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview ) {
//Get Number of the steps //Get Number of the steps
long aNbSteps = (long)SpinBox_NbSteps->value(); long aNbSteps = (long)SpinBox_NbSteps->value();
try
try { {
SUIT_OverrideCursor aWaitCursor; SUIT_OverrideCursor aWaitCursor;
SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer(); 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()) { switch (GetConstructorId()) {
case 0: case 0:
{ {
aMeshEditor->ExtrusionSweepObject0D(mySelectedObject, aVector, aNbSteps); aMeshEditor->ExtrusionSweepObject0D(mySelectedObject, aVector, aNbSteps);
break; break;
} }
case 1: case 1:
{ {
aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps); aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps);
break; break;
} }
case 2: case 2:
{ {
aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps); aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps);
break; break;
} }
} }
} }
else else // extrude some elements
{
if(GetConstructorId() == 0) if(GetConstructorId() == 0)
aMeshEditor->ExtrusionSweep0D(myElementsId.inout(), aVector, aNbSteps); aMeshEditor->ExtrusionSweep0D(myElementsId.inout(), aVector, aNbSteps);
else else
aMeshEditor->ExtrusionSweep(myElementsId.inout(), aVector, aNbSteps); aMeshEditor->ExtrusionSweep(myElementsId.inout(), aVector, aNbSteps);
}
SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData(); SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData();
mySimulation->SetData(aMeshPreviewStruct._retn()); mySimulation->SetData(aMeshPreviewStruct._retn());
} catch (...) { } catch (...) {
@ -1241,17 +1339,19 @@ void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview ) {
// function : getExtrusionVector() // function : getExtrusionVector()
// purpose : get direction of the extrusion // purpose : get direction of the extrusion
//================================================================================= //=================================================================================
void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector) { void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector)
if ( RadioButton3->isChecked() ) { {
if ( ExtrMethod_RBut0->isChecked() )
{
aVector.PS.x = SpinBox_Dx->GetValue(); aVector.PS.x = SpinBox_Dx->GetValue();
aVector.PS.y = SpinBox_Dy->GetValue(); aVector.PS.y = SpinBox_Dy->GetValue();
aVector.PS.z = SpinBox_Dz->GetValue(); aVector.PS.z = SpinBox_Dz->GetValue();
} else if ( RadioButton4->isChecked() ) { }
else if ( ExtrMethod_RBut1->isChecked() )
{
gp_XYZ aNormale(SpinBox_Vx->GetValue(), gp_XYZ aNormale(SpinBox_Vx->GetValue(),
SpinBox_Vy->GetValue(), SpinBox_Vy->GetValue(),
SpinBox_Vz->GetValue()); SpinBox_Vz->GetValue());
aNormale /= aNormale.Modulus(); aNormale /= aNormale.Modulus();
double aVDist = (double)SpinBox_VDist->value(); double aVDist = (double)SpinBox_VDist->value();
@ -1260,3 +1360,33 @@ void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector) {
aVector.PS.z = aNormale.Z()*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 );
}

View File

@ -37,6 +37,7 @@
// IDL includes // IDL includes
#include <SALOMEconfig.h> #include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Mesh) #include CORBA_SERVER_HEADER(SMESH_Mesh)
#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
class QButtonGroup; class QButtonGroup;
class QRadioButton; class QRadioButton;
@ -74,6 +75,8 @@ private:
void keyPressEvent( QKeyEvent* ); void keyPressEvent( QKeyEvent* );
int GetConstructorId(); int GetConstructorId();
void getExtrusionVector(SMESH::DirStruct& aVector); void getExtrusionVector(SMESH::DirStruct& aVector);
void extrusionByNormal(SMESH::SMESH_MeshEditor_ptr meshEditor,
const bool makeGroups=false);
bool isValid(); bool isValid();
bool isValuesValid(); bool isValuesValid();
@ -98,11 +101,12 @@ private:
// widgets // widgets
QGroupBox* ConstructorsBox; QGroupBox* ConstructorsBox;
QButtonGroup* GroupConstructors; QButtonGroup* GroupConstructors;
QRadioButton* RadioButton0; QRadioButton* Contructor_RBut0;
QRadioButton* RadioButton1; QRadioButton* Contructor_RBut1;
QRadioButton* RadioButton2; QRadioButton* Contructor_RBut2;
QRadioButton* RadioButton3; QRadioButton* ExtrMethod_RBut0;
QRadioButton* RadioButton4; QRadioButton* ExtrMethod_RBut1;
QRadioButton* ExtrMethod_RBut2;
QGroupBox* GroupArguments; QGroupBox* GroupArguments;
QGroupBox* GroupDimensions; QGroupBox* GroupDimensions;
@ -129,6 +133,8 @@ private:
SMESHGUI_SpinBox* SpinBox_VDist; SMESHGUI_SpinBox* SpinBox_VDist;
QLabel* TextLabelNbSteps; QLabel* TextLabelNbSteps;
SalomeApp_IntSpinBox* SpinBox_NbSteps; SalomeApp_IntSpinBox* SpinBox_NbSteps;
QCheckBox* ByAverageNormalCheck;
QCheckBox* UseInputElemsOnlyCheck;
QCheckBox* MakeGroupsCheck; QCheckBox* MakeGroupsCheck;
QGroupBox* GroupButtons; QGroupBox* GroupButtons;

View File

@ -516,8 +516,18 @@ bool SMESHGUI_RevolutionDlg::ClickOnApply()
aParameters << SpinBox_NbSteps->text(); aParameters << SpinBox_NbSteps->text();
aParameters << SpinBox_Tolerance->text(); aParameters << SpinBox_Tolerance->text();
bool meshHadNewTypeBefore = true;
try { try {
SUIT_OverrideCursor aWaitCursor; 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(); SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); myMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
@ -552,14 +562,30 @@ bool SMESHGUI_RevolutionDlg::ClickOnApply()
} catch (...) { } 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::UpdateView();
SMESH::Update(myIO, SMESH::eDisplay); SMESH::Update(myIO, SMESH::eDisplay);
if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() )
mySMESHGUI->updateObjBrowser(true); // new groups may appear mySMESHGUI->updateObjBrowser(true); // new groups may appear
Init(false); Init(false);
ConstructorsClicked(GetConstructorId()); mySelectionMgr->clearSelected();
mySelectedObject = SMESH::SMESH_IDSource::_nil(); mySelectedObject = SMESH::SMESH_IDSource::_nil();
SelectionIntoArgument(); SelectionIntoArgument();
ConstructorsClicked(GetConstructorId());
SMESHGUI::Modified(); SMESHGUI::Modified();
} }

View File

@ -1693,6 +1693,10 @@ Do you want to continue ?</translation>
<source>SMESH_EXTRUSION_ALONG_VECTOR</source> <source>SMESH_EXTRUSION_ALONG_VECTOR</source>
<translation>Extrusion Along Vector</translation> <translation>Extrusion Along Vector</translation>
</message> </message>
<message>
<source>SMESH_EXTRUSION_BY_NORMAL</source>
<translation>Extrusion By Normal</translation>
</message>
<message> <message>
<source>SMESH_FACE</source> <source>SMESH_FACE</source>
<translation>Face</translation> <translation>Face</translation>
@ -5141,6 +5145,14 @@ Please select a group and try again</translation>
<source>EXTRUSION_ALONG_LINE</source> <source>EXTRUSION_ALONG_LINE</source>
<translation>Extrusion along a line</translation> <translation>Extrusion along a line</translation>
</message> </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>
<context> <context>
<name>SMESHGUI_FilterDlg</name> <name>SMESHGUI_FilterDlg</name>

View File

@ -418,7 +418,8 @@ namespace MeshEditor_I {
if ( !sameElemType ) if ( !sameElemType )
elemType = SMDSAbs_All; elemType = SMDSAbs_All;
TIDSortedElemSet visitedNodes; vector<bool> isNodeChecked( theMeshDS->NbNodes(), false );
TIDSortedElemSet::const_iterator elemIt = theElements.begin(); TIDSortedElemSet::const_iterator elemIt = theElements.begin();
for ( ; elemIt != theElements.end(); ++elemIt ) for ( ; elemIt != theElements.end(); ++elemIt )
{ {
@ -427,8 +428,9 @@ namespace MeshEditor_I {
while ( --i != -1 ) while ( --i != -1 )
{ {
const SMDS_MeshNode* n = e->GetNode( i ); 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); SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
while ( invIt->more() ) while ( invIt->more() )
{ {
@ -784,16 +786,12 @@ struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids, SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
SMESH::ElementType type) SMESH::ElementType type)
{ {
// if ( myAuxIDSources.size() > 10 ) {
// delete myAuxIDSources.front();
// myAuxIDSources.pop_front();
// }
_IDSource* idSrc = new _IDSource; _IDSource* idSrc = new _IDSource;
idSrc->_mesh = myMesh_i->_this(); idSrc->_mesh = myMesh_i->_this();
idSrc->_ids = ids; idSrc->_ids = ids;
idSrc->_type = type; 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(); SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
@ -2687,6 +2685,77 @@ SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr th
return aGroups; 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 //function : extrusionSweep
@ -2694,43 +2763,45 @@ SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr th
//======================================================================= //=======================================================================
SMESH::ListOfGroups* SMESH::ListOfGroups*
SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements, SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
const SMESH::DirStruct & theStepVector, MeshEditor_I::ExtrusionParams& theParams,
CORBA::Long theNbOfSteps, const SMDSAbs_ElementType theElementType)
bool theMakeGroups,
const SMDSAbs_ElementType theElementType)
throw (SALOME::SALOME_Exception) throw (SALOME::SALOME_Exception)
{ {
SMESH_TRY; SMESH_TRY;
initData(); initData();
TIDSortedElemSet elements, copyElements; TIDSortedElemSet elements, copyElements;
arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType); arrayToSet( theIDsOfElements, getMeshDS(), elements, theElementType );
const SMESH::PointStruct * P = &theStepVector.PS;
gp_Vec stepVec( P->x, P->y, P->z );
TIDSortedElemSet* workElements = & elements; TIDSortedElemSet* workElements = & elements;
SMDSAbs_ElementType aType = SMDSAbs_Face; if ( myIsPreviewMode )
if (theElementType == SMDSAbs_Node)
{ {
aType = SMDSAbs_Edge; SMDSAbs_ElementType previewType = SMDSAbs_Face;
} if (theElementType == SMDSAbs_Node)
if ( myIsPreviewMode ) { previewType = SMDSAbs_Edge;
SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid ); getPreviewMesh( previewType )->Copy( elements, copyElements, select, avoid );
workElements = & copyElements; 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::TTElemOfElemListMap aHystory;
::SMESH_MeshEditor::PGroupIDs groupIds = ::SMESH_MeshEditor::PGroupIDs groupIds =
getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups); getEditor().ExtrusionSweep (*workElements, theParams, aHystory );
declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
return theMakeGroups ? getGroups(groupIds.get()) : 0; return theParams.ToMakeGroups() ? getGroups(groupIds.get()) : 0;
SMESH_CATCH( SMESH::throwCorbaException ); SMESH_CATCH( SMESH::throwCorbaException );
return 0; return 0;
@ -2746,7 +2817,8 @@ void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElemen
CORBA::Long theNbOfSteps) CORBA::Long theNbOfSteps)
throw (SALOME::SALOME_Exception) throw (SALOME::SALOME_Exception)
{ {
extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false ); ExtrusionParams params( theStepVector, theNbOfSteps, false );
extrusionSweep( theIDsOfElements, params );
if (!myIsPreviewMode) { if (!myIsPreviewMode) {
TPythonDump() << this << ".ExtrusionSweep( " TPythonDump() << this << ".ExtrusionSweep( "
<< theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )"; << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
@ -2763,7 +2835,8 @@ void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElem
CORBA::Long theNbOfSteps) CORBA::Long theNbOfSteps)
throw (SALOME::SALOME_Exception) throw (SALOME::SALOME_Exception)
{ {
extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node ); ExtrusionParams params( theStepVector, theNbOfSteps, false );
extrusionSweep( theIDsOfElements, params, SMDSAbs_Node );
if (!myIsPreviewMode) { if (!myIsPreviewMode) {
TPythonDump() << this << ".ExtrusionSweep0D( " TPythonDump() << this << ".ExtrusionSweep0D( "
<< theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )"; << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
@ -2782,7 +2855,8 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObjec
{ {
prepareIdSource( theObject ); prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::long_array_var anElementsId = theObject->GetIDs();
extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false ); ExtrusionParams params( theStepVector, theNbOfSteps, false );
extrusionSweep( anElementsId, params );
if (!myIsPreviewMode) { if (!myIsPreviewMode) {
TPythonDump() << this << ".ExtrusionSweepObject( " TPythonDump() << this << ".ExtrusionSweepObject( "
<< theObject << ", " << theStepVector << ", " << theNbOfSteps << " )"; << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
@ -2801,7 +2875,12 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObj
{ {
prepareIdSource( theObject ); prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs(); 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 ) { if ( !myIsPreviewMode ) {
TPythonDump() << this << ".ExtrusionSweepObject0D( " TPythonDump() << this << ".ExtrusionSweepObject0D( "
<< theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
@ -2820,7 +2899,8 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObj
{ {
prepareIdSource( theObject ); prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs(); 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 ) { if ( !myIsPreviewMode ) {
TPythonDump() << this << ".ExtrusionSweepObject1D( " TPythonDump() << this << ".ExtrusionSweepObject1D( "
<< theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
@ -2839,7 +2919,8 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObj
{ {
prepareIdSource( theObject ); prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs(); 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 ) { if ( !myIsPreviewMode ) {
TPythonDump() << this << ".ExtrusionSweepObject2D( " TPythonDump() << this << ".ExtrusionSweepObject2D( "
<< theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
@ -2859,7 +2940,8 @@ SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfEl
{ {
TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() 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) { if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups); dumpGroupsList(aPythonDump, aGroups);
@ -2882,7 +2964,8 @@ SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOf
{ {
TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() 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) { if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups); dumpGroupsList(aPythonDump, aGroups);
@ -2907,7 +2990,8 @@ SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr the
prepareIdSource( theObject ); prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs(); 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) { if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups); dumpGroupsList(aPythonDump, aGroups);
@ -2932,8 +3016,9 @@ SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr t
prepareIdSource( theObject ); prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::long_array_var anElementsId = theObject->GetIDs();
SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, ExtrusionParams params( theStepVector, theNbOfSteps, true );
theNbOfSteps, true, SMDSAbs_Node); SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Node );
if (!myIsPreviewMode) { if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups); dumpGroupsList(aPythonDump, aGroups);
aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
@ -2957,8 +3042,9 @@ SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr t
prepareIdSource( theObject ); prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::long_array_var anElementsId = theObject->GetIDs();
SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, ExtrusionParams params( theStepVector, theNbOfSteps, true );
theNbOfSteps, true, SMDSAbs_Edge); SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Edge );
if (!myIsPreviewMode) { if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups); dumpGroupsList(aPythonDump, aGroups);
aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
@ -2982,8 +3068,9 @@ SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr t
prepareIdSource( theObject ); prepareIdSource( theObject );
SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::long_array_var anElementsId = theObject->GetIDs();
SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, ExtrusionParams params( theStepVector, theNbOfSteps, true );
theNbOfSteps, true, SMDSAbs_Face); SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Face );
if (!myIsPreviewMode) { if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups); dumpGroupsList(aPythonDump, aGroups);
aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
@ -2992,41 +3079,49 @@ SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr t
return aGroups; return aGroups;
} }
//======================================================================= //=======================================================================
//function : advancedExtrusion //function : ExtrusionByNormal
//purpose : //purpose :
//======================================================================= //=======================================================================
SMESH::ListOfGroups* SMESH::ListOfGroups*
SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements, SMESH_MeshEditor_i::ExtrusionByNormal(SMESH::SMESH_IDSource_ptr object,
const SMESH::DirStruct & theStepVector, CORBA::Double stepSize,
CORBA::Long theNbOfSteps, CORBA::Long nbOfSteps,
CORBA::Long theExtrFlags, CORBA::Boolean byAverageNormal,
CORBA::Double theSewTolerance, CORBA::Boolean useInputElemsOnly,
const bool theMakeGroups) CORBA::Boolean makeGroups,
CORBA::Short dim)
throw (SALOME::SALOME_Exception) throw (SALOME::SALOME_Exception)
{ {
SMESH_TRY; TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
initData();
TIDSortedElemSet elements; ExtrusionParams params( stepSize, nbOfSteps, dim,
arrayToSet(theIDsOfElements, getMeshDS(), elements); byAverageNormal, useInputElemsOnly, makeGroups );
const SMESH::PointStruct * P = &theStepVector.PS; SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
gp_Vec stepVec( P->x, P->y, P->z ); 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_MeshEditor::TTElemOfElemListMap aHystory; if (!myIsPreviewMode) {
::SMESH_MeshEditor::PGroupIDs groupIds = dumpGroupsList(aPythonDump, aGroups);
getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory, aPythonDump << this << ".ExtrusionByNormal( " << object
theMakeGroups, theExtrFlags, theSewTolerance); << ", " << TVar( stepSize )
<< ", " << TVar( nbOfSteps )
declareMeshModified( /*isReComputeSafe=*/true ); << ", " << byAverageNormal
<< ", " << makeGroups
return theMakeGroups ? getGroups(groupIds.get()) : 0; << ", " << dim
<< " )";
SMESH_CATCH( SMESH::throwCorbaException ); }
return 0; return aGroups;
} }
//======================================================================= //=======================================================================
@ -3041,6 +3136,9 @@ void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfEle
CORBA::Double theSewTolerance) CORBA::Double theSewTolerance)
throw (SALOME::SALOME_Exception) throw (SALOME::SALOME_Exception)
{ {
ExtrusionParams params( theStepVector, theNbOfSteps, false, theExtrFlags, theSewTolerance);
extrusionSweep( theIDsOfElements, params );
if ( !myIsPreviewMode ) { if ( !myIsPreviewMode ) {
TPythonDump() << "stepVector = " << theStepVector; TPythonDump() << "stepVector = " << theStepVector;
TPythonDump() << this << ".AdvancedExtrusion(" TPythonDump() << this << ".AdvancedExtrusion("
@ -3050,12 +3148,6 @@ void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfEle
<< theExtrFlags << ", " << theExtrFlags << ", "
<< theSewTolerance << " )"; << theSewTolerance << " )";
} }
advancedExtrusion( theIDsOfElements,
theStepVector,
theNbOfSteps,
theExtrFlags,
theSewTolerance,
false);
} }
//======================================================================= //=======================================================================
@ -3075,12 +3167,8 @@ SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsO
} }
TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements, ExtrusionParams params( theStepVector, theNbOfSteps, true, theExtrFlags, theSewTolerance);
theStepVector, SMESH::ListOfGroups * aGroups = extrusionSweep( theIDsOfElements, params );
theNbOfSteps,
theExtrFlags,
theSewTolerance,
true);
if (!myIsPreviewMode) { if (!myIsPreviewMode) {
dumpGroupsList(aPythonDump, aGroups); dumpGroupsList(aPythonDump, aGroups);

View File

@ -42,6 +42,7 @@ class SMESH_Mesh_i;
namespace MeshEditor_I { namespace MeshEditor_I {
struct TPreviewMesh; struct TPreviewMesh;
struct ExtrusionParams;
} }
class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
@ -358,6 +359,14 @@ public:
const SMESH::DirStruct & StepVector, const SMESH::DirStruct & StepVector,
CORBA::Long NbOfSteps) CORBA::Long NbOfSteps)
throw (SALOME::SALOME_Exception); 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, void AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
const SMESH::DirStruct & theStepVector, const SMESH::DirStruct & theStepVector,
CORBA::Long theNbOfSteps, CORBA::Long theNbOfSteps,
@ -1025,11 +1034,9 @@ private: //!< private methods
const bool MakeGroups, const bool MakeGroups,
const SMDSAbs_ElementType ElementType=SMDSAbs_All) const SMDSAbs_ElementType ElementType=SMDSAbs_All)
throw (SALOME::SALOME_Exception); throw (SALOME::SALOME_Exception);
SMESH::ListOfGroups* extrusionSweep(const SMESH::long_array & IDsOfElements, SMESH::ListOfGroups* extrusionSweep(const SMESH::long_array & IDsOfElements,
const SMESH::DirStruct & StepVector, MeshEditor_I::ExtrusionParams& params,
CORBA::Long NbOfSteps, const SMDSAbs_ElementType ElementType=SMDSAbs_All)
bool MakeGroups,
const SMDSAbs_ElementType ElementType=SMDSAbs_All)
throw (SALOME::SALOME_Exception); throw (SALOME::SALOME_Exception);
SMESH::ListOfGroups* advancedExtrusion(const SMESH::long_array & theIDsOfElements, SMESH::ListOfGroups* advancedExtrusion(const SMESH::long_array & theIDsOfElements,
const SMESH::DirStruct & theStepVector, const SMESH::DirStruct & theStepVector,

View File

@ -3387,7 +3387,7 @@ class Mesh:
# them with quadratic with the same id. # them with quadratic with the same id.
# @param theForce3d new node creation method: # @param theForce3d new node creation method:
# 0 - the medium node lies at the geometrical entity from which the mesh element is built # 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 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 # @param theToBiQuad If True, converts the mesh to bi-quadratic
# @ingroup l2_modif_tofromqu # @ingroup l2_modif_tofromqu
@ -3662,6 +3662,44 @@ class Mesh:
ExtrFlags, SewTolerance) ExtrFlags, SewTolerance)
return [] 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 ## Generates new elements by extrusion of the elements which belong to the object
# @param theObject the object which elements should be processed. # @param theObject the object which elements should be processed.
# It can be a mesh, a sub mesh or a group. # It can be a mesh, a sub mesh or a group.