0023064: [CEA 1471] Create and support quadratic polygons in SMESH

This commit is contained in:
eap 2015-06-24 12:17:07 +03:00
parent 03a1295ce9
commit 23d90107ac
64 changed files with 2886 additions and 2090 deletions

BIN
doc/salome/gui/SMESH/images/image152.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -97,10 +97,14 @@ generated on (if any). The node generated on the geometrical edge or
surface in addition stores its position in parametric space of the surface in addition stores its position in parametric space of the
associated geometrical entity. associated geometrical entity.
Mesh entities are identified by integer IDs starting from 1.
Nodes and elements are countered separately, i.e. there can be a node
and element with the same ID.
SALOME supports elements of second order, without a central node SALOME supports elements of second order, without a central node
(quadratic triangle, quadrangle, tetrahedron, hexahedron, pentahedron (quadratic triangle, quadrangle, polygon, tetrahedron, hexahedron,
and pyramid) and with central nodes (bi-quadratic triangle and pentahedron and pyramid) and with central nodes (bi-quadratic triangle
quadrangle and tri-quadratic hexahedron).<br> and quadrangle and tri-quadratic hexahedron).<br>
Quadratic mesh can be obtained in two ways: Quadratic mesh can be obtained in two ways:
- Using a global \ref quadratic_mesh_anchor "Quadratic Mesh" - Using a global \ref quadratic_mesh_anchor "Quadratic Mesh"
hypothesis. (Elements with the central node are not generated in this way). hypothesis. (Elements with the central node are not generated in this way).

View File

@ -32,7 +32,7 @@ nodal connectivity of elements in the documentation on MED library or
<li>From the \b Modification menu choose the \b Add item, the <li>From the \b Modification menu choose the \b Add item, the
following associated sub-menu will appear:</li> following associated sub-menu will appear:</li>
\image html image146.png \image html image152.png
From this sub-menu select the type of element which you would like to add to your mesh. From this sub-menu select the type of element which you would like to add to your mesh.
@ -47,10 +47,13 @@ existing groups of the corresponding type becomes available. By
default, no group is selected. In this case, when the user presses default, no group is selected. In this case, when the user presses
<b>Apply</b> or <b>Apply & Close</b> button, the warning message box <b>Apply</b> or <b>Apply & Close</b> button, the warning message box
informs the user about the necessity to input new group name. The informs the user about the necessity to input new group name. The
combo box lists both \ref standalone_group "standalone groups" combo box lists groups of all the
and \ref group_on_geom "groups on geometry". If the user chooses a \ref grouping_elements_page "three types": both
group on geometry, he is warned and proposed to \ref standalone_group "standalone groups",
\ref convert_to_standalone "convert this group to standalone". \ref group_on_filter "groups on filter", and
\ref group_on_geom "groups on geometry". If the user chooses a
group on geometry or on filter, he is warned and proposed to
convert this group to standalone.
If the user rejects conversion operation, it is cancelled and If the user rejects conversion operation, it is cancelled and
a new node/element is not created! a new node/element is not created!

View File

@ -36,7 +36,7 @@ one of the following:
\image html image152.png \image html image152.png
\note All dialogs for quadratic element adding to the mesh \note All dialogs for adding quadratic element to the mesh
provide the possibility to automatically add an element provide the possibility to automatically add an element
to the specified group or to create the group anew using to the specified group or to create the group anew using
<b>Add to group</b> box, that allows choosing an existing group for <b>Add to group</b> box, that allows choosing an existing group for
@ -47,23 +47,29 @@ existing groups of the corresponding type becomes available. By
default, no group is selected. In this case, when the user presses default, no group is selected. In this case, when the user presses
<b>Apply</b> or <b>Apply & Close</b> button, the warning message box <b>Apply</b> or <b>Apply & Close</b> button, the warning message box
informs the user about the necessity to input a new group name. The informs the user about the necessity to input a new group name. The
combo box lists both \ref standalone_group "standalone groups" combo box lists groups of all the
and \ref group_on_geom "groups on geometry". If the user chooses a \ref grouping_elements_page "three types": both
group on geometry, he is warned and proposed to \ref standalone_group "standalone groups",
\ref convert_to_standalone "convert this group to standalone". \ref group_on_filter "groups on filter", and
\ref group_on_geom "groups on geometry". If the user chooses a
group on geometry or on filter, he is warned and proposed to
convert this group to standalone.
If the user rejects conversion operation, it is cancelled and If the user rejects conversion operation, it is cancelled and
a new quadratic element is not created. a new quadratic element is not created.
To create any <b>Quadratic Element</b> specify the nodes which will form your To create any <b>Quadratic Element</b> specify the nodes which will
element by selecting them in the 3D viewer with pressed Shift form your element by selecting them in the 3D viewer with pressed
button. Their numbers will appear in the dialog box as <b>Corner Nodes</b> Shift button and click \a Selection button to the right of
(alternatively you can just input numbers in this field without <b>Corner Nodes</b> label. Their numbers will appear in the dialog box
selection). The edges formed by the corner nodes will appear in the as <b>Corner Nodes</b> (alternatively you can just input numbers in
table. To define the middle nodes for each edge, double-click on the this field without selection; note that to use this way the mesh
respective field and input the number of the node (or pick the node in should be selected before invoking this operation). The edges formed
the viewer). For bi-quadratic and tri-quadratic elements, your also by the corner nodes will appear in the table. To define the middle
need to specify central nodes. nodes for each edge, double-click on the respective field and input
the number of the node (or pick the node in the viewer). For
bi-quadratic and tri-quadratic elements, your also need to specify
central nodes.
As soon as all needed nodes are specified, a preview of a new As soon as all needed nodes are specified, a preview of a new
quadratic element will be displayed in the 3D viewer. Then quadratic element will be displayed in the 3D viewer. Then
you will be able to click \b Apply or <b>Apply and Close</b> button to you will be able to click \b Apply or <b>Apply and Close</b> button to

View File

@ -13,7 +13,7 @@ The algorithm assures good shape of quadrangles by constructing Medial
Axis between sinuous borders of the face and using it to Axis between sinuous borders of the face and using it to
discretize the borders. discretize the borders.
\image html quad_from_ma_medial_axis.png "Media Axis between two blue sinuous borders" \image html quad_from_ma_medial_axis.png "Medial Axis between two blue sinuous borders"
The Medial Axis is used in two ways: The Medial Axis is used in two ways:
<ol> <ol>

View File

@ -66,6 +66,7 @@ module SMESH
ADD_QUADEDGE, ADD_QUADEDGE,
ADD_QUADTRIANGLE, ADD_QUADTRIANGLE,
ADD_QUADQUADRANGLE, ADD_QUADQUADRANGLE,
ADD_QUADPOLYGON,
ADD_QUADTETRAHEDRON, ADD_QUADTETRAHEDRON,
ADD_QUADPYRAMID, ADD_QUADPYRAMID,
ADD_QUADPENTAHEDRON, ADD_QUADPENTAHEDRON,
@ -775,7 +776,7 @@ module SMESH
long NbBiQuadQuadrangles() long NbBiQuadQuadrangles()
raises (SALOME::SALOME_Exception); raises (SALOME::SALOME_Exception);
long NbPolygons() long NbPolygons(in ElementOrder order)
raises (SALOME::SALOME_Exception); raises (SALOME::SALOME_Exception);
long NbVolumes() long NbVolumes()

View File

@ -143,6 +143,13 @@ module SMESH
long AddPolygonalFace(in long_array IdsOfNodes) raises (SALOME::SALOME_Exception); long AddPolygonalFace(in long_array IdsOfNodes) raises (SALOME::SALOME_Exception);
/*!
* Create a quadratic polygonal face
* \param IdsOfNodes - nodes of the polygon; corner nodes follow first
* \return long - ID of a new polygon
*/
long AddQuadPolygonalFace(in long_array IdsOfNodes) raises (SALOME::SALOME_Exception);
/*! /*!
* Create volume, either linear and quadratic (this is determed * Create volume, either linear and quadratic (this is determed
* by number of given nodes). * by number of given nodes).

View File

@ -170,6 +170,7 @@ SET(SMESH_RESOURCES_FILES
mesh_quad_edge.png mesh_quad_edge.png
mesh_quad_triangle.png mesh_quad_triangle.png
mesh_quad_quadrangle.png mesh_quad_quadrangle.png
mesh_quad_polygon.png
mesh_quad_tetrahedron.png mesh_quad_tetrahedron.png
mesh_quad_pyramid.png mesh_quad_pyramid.png
mesh_quad_pentahedron.png mesh_quad_pentahedron.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

View File

@ -68,7 +68,6 @@
#include <set> #include <set>
#include <limits> #include <limits>
#include <TopTools_MapOfShape.hxx>
/* /*
AUXILIARY METHODS AUXILIARY METHODS
@ -159,29 +158,6 @@ namespace {
} }
int aResult = std::max ( aResult0, aResult1 ); int aResult = std::max ( aResult0, aResult1 );
// TColStd_MapOfInteger aMap;
// SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator();
// if ( anIter != 0 ) {
// while( anIter->more() ) {
// const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
// if ( aNode == 0 )
// return 0;
// SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator();
// while( anElemIter->more() ) {
// const SMDS_MeshElement* anElem = anElemIter->next();
// if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) {
// int anId = anElem->GetID();
// if ( anIter->more() ) // i.e. first node
// aMap.Add( anId );
// else if ( aMap.Contains( anId ) )
// aResult++;
// }
// }
// }
// }
return aResult; return aResult;
} }
@ -257,6 +233,7 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
return false; return false;
theRes.reserve( anElem->NbNodes() ); theRes.reserve( anElem->NbNodes() );
theRes.setElement( anElem );
// Get nodes of the element // Get nodes of the element
SMDS_ElemIteratorPtr anIter; SMDS_ElemIteratorPtr anIter;
@ -273,7 +250,6 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
break; break;
default: default:
anIter = anElem->nodesIterator(); anIter = anElem->nodesIterator();
//return false;
} }
} }
else { else {
@ -281,9 +257,13 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
} }
if ( anIter ) { if ( anIter ) {
double xyz[3];
while( anIter->more() ) { while( anIter->more() ) {
if ( const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>( anIter->next() )) if ( const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>( anIter->next() ))
theRes.push_back( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) ); {
aNode->GetXYZ( xyz );
theRes.push_back( gp_XYZ( xyz[0], xyz[1], xyz[2] ));
}
} }
} }
@ -481,6 +461,27 @@ double MaxElementLength2D::GetValue( const TSequenceOfXYZ& P )
double D2 = getDistance(P( 3 ),P( 7 )); double D2 = getDistance(P( 3 ),P( 7 ));
aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2)); aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2));
} }
// Diagonals are undefined for concave polygons
// else if ( P.getElementEntity() == SMDSEntity_Quad_Polygon && P.size() > 2 ) // quad polygon
// {
// // sides
// aVal = getDistance( P( 1 ), P( P.size() )) + getDistance( P( P.size() ), P( P.size()-1 ));
// for ( size_t i = 1; i < P.size()-1; i += 2 )
// {
// double L = getDistance( P( i ), P( i+1 )) + getDistance( P( i+1 ), P( i+2 ));
// aVal = Max( aVal, L );
// }
// // diagonals
// for ( int i = P.size()-5; i > 0; i -= 2 )
// for ( int j = i + 4; j < P.size() + i - 2; i += 2 )
// {
// double D = getDistance( P( i ), P( j ));
// aVal = Max( aVal, D );
// }
// }
// { // polygons
// }
if( myPrecision >= 0 ) if( myPrecision >= 0 )
{ {
@ -699,7 +700,8 @@ double MinimumAngle::GetValue( const TSequenceOfXYZ& P )
aMin = getAngle(P( P.size() ), P( 1 ), P( 2 )); aMin = getAngle(P( P.size() ), P( 1 ), P( 2 ));
aMin = Min(aMin,getAngle(P( P.size()-1 ), P( P.size() ), P( 1 ))); aMin = Min(aMin,getAngle(P( P.size()-1 ), P( P.size() ), P( 1 )));
for (int i=2; i<P.size();i++){ for ( int i = 2; i < P.size(); i++ )
{
double A0 = getAngle( P( i-1 ), P( i ), P( i+1 ) ); double A0 = getAngle( P( i-1 ), P( i ), P( i+1 ) );
aMin = Min(aMin,A0); aMin = Min(aMin,A0);
} }
@ -1467,11 +1469,14 @@ SMDSAbs_ElementType Skew::GetType() const
double Area::GetValue( const TSequenceOfXYZ& P ) double Area::GetValue( const TSequenceOfXYZ& P )
{ {
double val = 0.0; double val = 0.0;
if ( P.size() > 2 ) { if ( P.size() > 2 )
{
gp_Vec aVec1( P(2) - P(1) ); gp_Vec aVec1( P(2) - P(1) );
gp_Vec aVec2( P(3) - P(1) ); gp_Vec aVec2( P(3) - P(1) );
gp_Vec SumVec = aVec1 ^ aVec2; gp_Vec SumVec = aVec1 ^ aVec2;
for (int i=4; i<=P.size(); i++) {
for (int i=4; i<=P.size(); i++)
{
gp_Vec aVec1( P(i-1) - P(1) ); gp_Vec aVec1( P(i-1) - P(1) );
gp_Vec aVec2( P(i) - P(1) ); gp_Vec aVec2( P(i) - P(1) );
gp_Vec tmp = aVec1 ^ aVec2; gp_Vec tmp = aVec1 ^ aVec2;
@ -1523,7 +1528,7 @@ SMDSAbs_ElementType Length::GetType() const
//================================================================================ //================================================================================
/* /*
Class : Length2D Class : Length2D
Description : Functor for calculating length of edge Description : Functor for calculating minimal length of edge
*/ */
//================================================================================ //================================================================================
@ -1531,63 +1536,59 @@ double Length2D::GetValue( long theElementId )
{ {
TSequenceOfXYZ P; TSequenceOfXYZ P;
//cout<<"Length2D::GetValue"<<endl; if ( GetPoints( theElementId, P ))
if (GetPoints(theElementId,P)){ {
//for(int jj=1; jj<=P.size(); jj++) double aVal = 0;
// cout<<"jj="<<jj<<" P("<<P(jj).X()<<","<<P(jj).Y()<<","<<P(jj).Z()<<")"<<endl;
double aVal;// = GetValue( P );
const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId );
SMDSAbs_ElementType aType = aElem->GetType();
int len = P.size(); int len = P.size();
SMDSAbs_EntityType aType = P.getElementEntity();
switch (aType) { switch (aType) {
case SMDSAbs_All: case SMDSEntity_Edge:
case SMDSAbs_Node: if (len == 2)
case SMDSAbs_Edge:
if (len == 2){
aVal = getDistance( P( 1 ), P( 2 ) ); aVal = getDistance( P( 1 ), P( 2 ) );
break; break;
} case SMDSEntity_Quad_Edge:
else if (len == 3){ // quadratic edge if (len == 3) // quadratic edge
aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 )); aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 ));
break; break;
} case SMDSEntity_Triangle:
case SMDSAbs_Face:
if (len == 3){ // triangles if (len == 3){ // triangles
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 = Min(L1,Min(L2,L3)); aVal = Min(L1,Min(L2,L3));
break;
} }
else if (len == 4){ // quadrangles break;
case SMDSEntity_Quadrangle:
if (len == 4){ // quadrangles
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( 4 )); double L3 = getDistance(P( 3 ),P( 4 ));
double L4 = getDistance(P( 4 ),P( 1 )); double L4 = getDistance(P( 4 ),P( 1 ));
aVal = Min(Min(L1,L2),Min(L3,L4)); aVal = Min(Min(L1,L2),Min(L3,L4));
break;
} }
if (len == 6){ // quadratic triangles break;
case SMDSEntity_Quad_Triangle:
case SMDSEntity_BiQuad_Triangle:
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 = Min(L1,Min(L2,L3)); aVal = Min(L1,Min(L2,L3));
//cout<<"L1="<<L1<<" L2="<<L2<<"L3="<<L3<<" aVal="<<aVal<<endl;
break;
} }
else if (len == 8){ // quadratic quadrangles break;
case SMDSEntity_Quad_Quadrangle:
case SMDSEntity_BiQuad_Quadrangle:
if (len >= 8){ // quadratic quadrangles
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( 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 = Min(Min(L1,L2),Min(L3,L4)); aVal = Min(Min(L1,L2),Min(L3,L4));
break;
} }
case SMDSAbs_Volume: break;
if (len == 4){ // tetraidrs case SMDSEntity_Tetra:
if (len == 4){ // tetrahedra
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 ));
@ -1595,9 +1596,10 @@ double Length2D::GetValue( long theElementId )
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 = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
break;
} }
else if (len == 5){ // piramids break;
case SMDSEntity_Pyramid:
if (len == 5){ // piramids
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( 4 )); double L3 = getDistance(P( 3 ),P( 4 ));
@ -1609,9 +1611,10 @@ double Length2D::GetValue( long theElementId )
aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Min(aVal,Min(L7,L8)); aVal = Min(aVal,Min(L7,L8));
break;
} }
else if (len == 6){ // pentaidres break;
case SMDSEntity_Penta:
if (len == 6) { // pentaidres
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 ));
@ -1624,9 +1627,10 @@ double Length2D::GetValue( long theElementId )
aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Min(aVal,Min(Min(L7,L8),L9)); aVal = Min(aVal,Min(Min(L7,L8),L9));
break;
} }
else if (len == 8){ // hexaider break;
case SMDSEntity_Hexa:
if (len == 8){ // hexahedron
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( 4 )); double L3 = getDistance(P( 3 ),P( 4 ));
@ -1643,10 +1647,9 @@ double Length2D::GetValue( long theElementId )
aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10))); aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10)));
aVal = Min(aVal,Min(L11,L12)); aVal = Min(aVal,Min(L11,L12));
break;
} }
break;
case SMDSEntity_Quad_Tetra:
if (len == 10){ // quadratic tetraidrs if (len == 10){ // quadratic tetraidrs
double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 )); double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 )); double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 ));
@ -1655,9 +1658,10 @@ double Length2D::GetValue( long theElementId )
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 = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
break;
} }
else if (len == 13){ // quadratic piramids break;
case SMDSEntity_Quad_Pyramid:
if (len == 13){ // quadratic piramids
double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 )); double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 )); double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 4 )); double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 4 ));
@ -1668,9 +1672,10 @@ double Length2D::GetValue( long theElementId )
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 = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Min(aVal,Min(L7,L8)); aVal = Min(aVal,Min(L7,L8));
break;
} }
else if (len == 15){ // quadratic pentaidres break;
case SMDSEntity_Quad_Penta:
if (len == 15){ // quadratic pentaidres
double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 )); double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 )); double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
@ -1682,9 +1687,11 @@ double Length2D::GetValue( long theElementId )
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 = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Min(aVal,Min(Min(L7,L8),L9)); aVal = Min(aVal,Min(Min(L7,L8),L9));
break;
} }
else if (len == 20){ // quadratic hexaider break;
case SMDSEntity_Quad_Hexa:
case SMDSEntity_TriQuad_Hexa:
if (len >= 20) { // quadratic hexaider
double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 )); double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 )); double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 )); double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 ));
@ -1700,11 +1707,55 @@ double Length2D::GetValue( long theElementId )
aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6)); aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10))); aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10)));
aVal = Min(aVal,Min(L11,L12)); aVal = Min(aVal,Min(L11,L12));
break;
} }
break;
case SMDSEntity_Polygon:
if ( len > 1 ) {
aVal = getDistance( P(1), P( P.size() ));
for ( size_t i = 1; i < P.size(); ++i )
aVal = Min( aVal, getDistance( P( i ), P( i+1 )));
}
break;
case SMDSEntity_Quad_Polygon:
if ( len > 2 ) {
aVal = getDistance( P(1), P( P.size() )) + getDistance( P(P.size()), P( P.size()-1 ));
for ( size_t i = 1; i < P.size()-1; i += 2 )
aVal = Min( aVal, getDistance( P( i ), P( i+1 )) + getDistance( P( i+1 ), P( i+2 )));
}
break;
case SMDSEntity_Hexagonal_Prism:
if (len == 12) { // hexagonal prism
double L1 = getDistance(P( 1 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 4 ));
double L4 = getDistance(P( 4 ),P( 5 ));
double L5 = getDistance(P( 5 ),P( 6 ));
double L6 = getDistance(P( 6 ),P( 1 ));
default: aVal=-1; double L7 = getDistance(P( 7 ), P( 8 ));
double L8 = getDistance(P( 8 ), P( 9 ));
double L9 = getDistance(P( 9 ), P( 10 ));
double L10= getDistance(P( 10 ),P( 11 ));
double L11= getDistance(P( 11 ),P( 12 ));
double L12= getDistance(P( 12 ),P( 7 ));
double L13 = getDistance(P( 1 ),P( 7 ));
double L14 = getDistance(P( 2 ),P( 8 ));
double L15 = getDistance(P( 3 ),P( 9 ));
double L16 = getDistance(P( 4 ),P( 10 ));
double L17 = getDistance(P( 5 ),P( 11 ));
double L18 = getDistance(P( 6 ),P( 12 ));
aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Min(aVal, Min(Min(Min(L7,L8),Min(L9,L10)),Min(L11,L12)));
aVal = Min(aVal, Min(Min(Min(L13,L14),Min(L15,L16)),Min(L17,L18)));
}
break;
case SMDSEntity_Polyhedra:
{
}
break;
default:
return 0;
} }
if (aVal < 0 ) { if (aVal < 0 ) {
@ -1743,14 +1794,16 @@ Length2D::Value::Value(double theLength,long thePntId1, long thePntId2):
} }
} }
bool Length2D::Value::operator<(const Length2D::Value& x) const{ bool Length2D::Value::operator<(const Length2D::Value& x) const
{
if(myPntId[0] < x.myPntId[0]) return true; if(myPntId[0] < x.myPntId[0]) return true;
if(myPntId[0] == x.myPntId[0]) if(myPntId[0] == x.myPntId[0])
if(myPntId[1] < x.myPntId[1]) return true; if(myPntId[1] < x.myPntId[1]) return true;
return false; return false;
} }
void Length2D::GetValues(TValues& theValues){ void Length2D::GetValues(TValues& theValues)
{
TValues aValues; TValues aValues;
SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
for(; anIter->more(); ){ for(; anIter->more(); ){
@ -1947,14 +2000,16 @@ MultiConnection2D::Value::Value(long thePntId1, long thePntId2)
} }
} }
bool MultiConnection2D::Value::operator<(const MultiConnection2D::Value& x) const{ bool MultiConnection2D::Value::operator<(const MultiConnection2D::Value& x) const
{
if(myPntId[0] < x.myPntId[0]) return true; if(myPntId[0] < x.myPntId[0]) return true;
if(myPntId[0] == x.myPntId[0]) if(myPntId[0] == x.myPntId[0])
if(myPntId[1] < x.myPntId[1]) return true; if(myPntId[1] < x.myPntId[1]) return true;
return false; return false;
} }
void MultiConnection2D::GetValues(MValues& theValues){ void MultiConnection2D::GetValues(MValues& theValues)
{
if ( !myMesh ) return; if ( !myMesh ) return;
SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
for(; anIter->more(); ){ for(; anIter->more(); ){
@ -2526,7 +2581,7 @@ bool FreeFaces::IsSatisfy( long theId )
int nbNode = aFace->NbNodes(); int nbNode = aFace->NbNodes();
// collect volumes check that number of volumss with count equal nbNode not less than 2 // collect volumes to check that number of volumes with count equal nbNode not less than 2
typedef map< SMDS_MeshElement*, int > TMapOfVolume; // map of volume counters typedef map< SMDS_MeshElement*, int > TMapOfVolume; // map of volume counters
typedef map< SMDS_MeshElement*, int >::iterator TItrMapOfVolume; // iterator typedef map< SMDS_MeshElement*, int >::iterator TItrMapOfVolume; // iterator
TMapOfVolume mapOfVol; TMapOfVolume mapOfVol;
@ -2629,7 +2684,6 @@ static bool isEqual( const Quantity_Color& theColor1,
fabs( theColor1.Blue() - theColor2.Blue() ) < tol ); fabs( theColor1.Blue() - theColor2.Blue() ) < tol );
} }
void GroupColor::SetMesh( const SMDS_Mesh* theMesh ) void GroupColor::SetMesh( const SMDS_Mesh* theMesh )
{ {
myIDs.clear(); myIDs.clear();
@ -4634,20 +4688,20 @@ bool LyingOnGeom::Contains( const SMESHDS_Mesh* theMeshDS,
return false; return false;
} }
TSequenceOfXYZ::TSequenceOfXYZ() TSequenceOfXYZ::TSequenceOfXYZ(): myElem(0)
{} {}
TSequenceOfXYZ::TSequenceOfXYZ(size_type n) : myArray(n) TSequenceOfXYZ::TSequenceOfXYZ(size_type n) : myArray(n), myElem(0)
{} {}
TSequenceOfXYZ::TSequenceOfXYZ(size_type n, const gp_XYZ& t) : myArray(n,t) TSequenceOfXYZ::TSequenceOfXYZ(size_type n, const gp_XYZ& t) : myArray(n,t), myElem(0)
{} {}
TSequenceOfXYZ::TSequenceOfXYZ(const TSequenceOfXYZ& theSequenceOfXYZ) : myArray(theSequenceOfXYZ.myArray) TSequenceOfXYZ::TSequenceOfXYZ(const TSequenceOfXYZ& theSequenceOfXYZ) : myArray(theSequenceOfXYZ.myArray), myElem(theSequenceOfXYZ.myElem)
{} {}
template <class InputIterator> template <class InputIterator>
TSequenceOfXYZ::TSequenceOfXYZ(InputIterator theBegin, InputIterator theEnd): myArray(theBegin,theEnd) TSequenceOfXYZ::TSequenceOfXYZ(InputIterator theBegin, InputIterator theEnd): myArray(theBegin,theEnd), myElem(0)
{} {}
TSequenceOfXYZ::~TSequenceOfXYZ() TSequenceOfXYZ::~TSequenceOfXYZ()
@ -4656,6 +4710,7 @@ TSequenceOfXYZ::~TSequenceOfXYZ()
TSequenceOfXYZ& TSequenceOfXYZ::operator=(const TSequenceOfXYZ& theSequenceOfXYZ) TSequenceOfXYZ& TSequenceOfXYZ::operator=(const TSequenceOfXYZ& theSequenceOfXYZ)
{ {
myArray = theSequenceOfXYZ.myArray; myArray = theSequenceOfXYZ.myArray;
myElem = theSequenceOfXYZ.myElem;
return *this; return *this;
} }
@ -4689,6 +4744,11 @@ TSequenceOfXYZ::size_type TSequenceOfXYZ::size() const
return myArray.size(); return myArray.size();
} }
SMDSAbs_EntityType TSequenceOfXYZ::getElementEntity() const
{
return myElem ? myElem->GetEntityType() : SMDSEntity_Last;
}
TMeshModifTracer::TMeshModifTracer(): TMeshModifTracer::TMeshModifTracer():
myMeshModifTime(0), myMesh(0) myMeshModifTime(0), myMesh(0)
{ {

View File

@ -67,7 +67,7 @@ namespace SMESH{
public: public:
TSequenceOfXYZ(); TSequenceOfXYZ();
TSequenceOfXYZ(size_type n); explicit TSequenceOfXYZ(size_type n);
TSequenceOfXYZ(size_type n, const gp_XYZ& t); TSequenceOfXYZ(size_type n, const gp_XYZ& t);
@ -92,8 +92,16 @@ namespace SMESH{
size_type size() const; size_type size() const;
void setElement(const SMDS_MeshElement* e) { myElem = e; }
const SMDS_MeshElement* getElement() const { return myElem; }
SMDSAbs_EntityType getElementEntity() const;
private: private:
std::vector<gp_XYZ> myArray; std::vector<gp_XYZ> myArray;
const SMDS_MeshElement* myElem;
}; };
/*! /*!

View File

@ -147,6 +147,7 @@ namespace
} }
{ {
cgTypes[SMDSEntity_Polygon] = CGNS_ENUMV( NGON_n ); cgTypes[SMDSEntity_Polygon] = CGNS_ENUMV( NGON_n );
cgTypes[SMDSEntity_Quad_Polygon] = CGNS_ENUMV( NGON_n );
cgTypes[SMDSEntity_Polyhedra] = CGNS_ENUMV( NFACE_n ); cgTypes[SMDSEntity_Polyhedra] = CGNS_ENUMV( NFACE_n );
cgTypes[SMDSEntity_Hexagonal_Prism] = CGNS_ENUMV( NFACE_n ); cgTypes[SMDSEntity_Hexagonal_Prism] = CGNS_ENUMV( NFACE_n );
} }
@ -370,6 +371,21 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
} }
while ( elem && elem->GetEntityType() == elemType ); while ( elem && elem->GetEntityType() == elemType );
else if ( elemType == SMDSEntity_Quad_Polygon ) // QUADRATIC POLYGONS
do // write as linear NGON_n
{
elemData.push_back( elem->NbNodes() );
interlace = & SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Quad_Polygon,
elem->NbNodes() )[0];
for ( int i = 0, nb = elem->NbNodes(); i < nb; ++i )
elemData.push_back( cgnsID( elem->GetNode( interlace[i] ), n2cgID ));
if ( elem->GetID() != cgID )
elem2cgID.insert( elem2cgID.end(), make_pair( elem, cgID ));
++cgID;
elem = elemIt->more() ? elemIt->next() : 0;
}
while ( elem && elem->GetEntityType() == elemType );
else if ( elemType == SMDSEntity_Polyhedra || else if ( elemType == SMDSEntity_Polyhedra ||
elemType == SMDSEntity_Hexagonal_Prism) // POLYHEDRA elemType == SMDSEntity_Hexagonal_Prism) // POLYHEDRA
{ {

View File

@ -25,20 +25,21 @@
// Module : SMESH // Module : SMESH
#include "DriverMED_R_SMESHDS_Mesh.h" #include "DriverMED_R_SMESHDS_Mesh.h"
#include "SMESHDS_Mesh.hxx"
#include "utilities.h"
#include "DriverMED_Family.h" #include "DriverMED_Family.h"
#include "SMESHDS_Group.hxx" #include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_Comment.hxx"
#include "MED_Factory.hxx"
#include "MED_CoordUtils.hxx" #include "MED_CoordUtils.hxx"
#include "MED_Factory.hxx"
#include "MED_Utilities.hxx" #include "MED_Utilities.hxx"
#include <NCollection_Map.hxx> #include <NCollection_Map.hxx>
#include <stdlib.h> #include "utilities.h"
//#include <stdlib.h>
#ifdef _DEBUG_ #ifdef _DEBUG_
static int MYDEBUG = 1; static int MYDEBUG = 1;
@ -70,28 +71,38 @@ namespace DriverMED
bool checkFamilyID(DriverMED_FamilyPtr & aFamily, bool checkFamilyID(DriverMED_FamilyPtr & aFamily,
int anID, int anID,
const TID2FamilyMap& myFamilies); const TID2FamilyMap& myFamilies);
}
void
DriverMED_R_SMESHDS_Mesh
::SetMeshName(string theMeshName)
{
myMeshName = theMeshName;
}
static const SMDS_MeshNode* const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, TInt theId)
FindNode(const SMDS_Mesh* theMesh, TInt theId)
{ {
const SMDS_MeshNode* aNode = theMesh->FindNode(theId); const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
if(aNode) return aNode; if(aNode) return aNode;
EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId); EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
} }
}
Driver_Mesh::Status //================================================================================
DriverMED_R_SMESHDS_Mesh /*!
::Perform() * \brief Stores a mesh name
*/
//================================================================================
void DriverMED_R_SMESHDS_Mesh::SetMeshName(string theMeshName)
{ {
myMeshName = theMeshName;
}
//================================================================================
/*!
* \brief Reads a med file
*/
//================================================================================
Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform()
{
using namespace DriverMED;
Status aResult = DRS_FAIL; Status aResult = DRS_FAIL;
bool isDescConn = false; // Mantis issue 0020483 bool isDescConn = false; // Mantis issue 0020483
#ifndef _DEXCEPT_ #ifndef _DEXCEPT_
@ -102,20 +113,17 @@ DriverMED_R_SMESHDS_Mesh
PWrapper aMed = CrWrapper(myFile,true); PWrapper aMed = CrWrapper(myFile,true);
aResult = DRS_EMPTY; aResult = DRS_EMPTY;
if(TInt aNbMeshes = aMed->GetNbMeshes()){ TInt aNbMeshes = aMed->GetNbMeshes();
for(int iMesh = 0; iMesh < aNbMeshes; iMesh++){ for (int iMesh = 0; iMesh < aNbMeshes; iMesh++)
{
// Reading the MED mesh // Reading the MED mesh
//--------------------- //---------------------
PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1); PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
string aMeshName; string aMeshName;
if (myMeshId != -1) { if (myMeshId != -1) aMeshName = SMESH_Comment( myMeshId );
ostringstream aMeshNameStr; else aMeshName = myMeshName;
aMeshNameStr<<myMeshId;
aMeshName = aMeshNameStr.str();
} else {
aMeshName = myMeshName;
}
if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName()); if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
if ( aMeshName != aMeshInfo->GetName() ) continue; if ( aMeshName != aMeshInfo->GetName() ) continue;
aResult = DRS_OK; aResult = DRS_OK;
@ -125,7 +133,8 @@ DriverMED_R_SMESHDS_Mesh
TErr anErr; TErr anErr;
TInt aNbFams = aMed->GetNbFamilies(aMeshInfo); TInt aNbFams = aMed->GetNbFamilies(aMeshInfo);
if(MYDEBUG) MESSAGE("Read " << aNbFams << " families"); if(MYDEBUG) MESSAGE("Read " << aNbFams << " families");
for (TInt iFam = 0; iFam < aNbFams; iFam++) { for (TInt iFam = 0; iFam < aNbFams; iFam++)
{
PFamilyInfo aFamilyInfo = aMed->GetPFamilyInfo(aMeshInfo,iFam+1,&anErr); PFamilyInfo aFamilyInfo = aMed->GetPFamilyInfo(aMeshInfo,iFam+1,&anErr);
if(anErr >= 0){ if(anErr >= 0){
TInt aFamId = aFamilyInfo->GetId(); TInt aFamId = aFamilyInfo->GetId();
@ -138,23 +147,23 @@ DriverMED_R_SMESHDS_Mesh
bool isAttrOk = false; bool isAttrOk = false;
if(aFamilyInfo->GetNbAttr() == aNbGrp) if(aFamilyInfo->GetNbAttr() == aNbGrp)
isAttrOk = true; isAttrOk = true;
for (TInt iGr = 0; iGr < aNbGrp; iGr++) { for (TInt iGr = 0; iGr < aNbGrp; iGr++)
{
string aGroupName = aFamilyInfo->GetGroupName(iGr); string aGroupName = aFamilyInfo->GetGroupName(iGr);
if ( isAttrOk ) { if ( isAttrOk ) {
TInt anAttrVal = aFamilyInfo->GetAttrVal(iGr); TInt anAttrVal = aFamilyInfo->GetAttrVal(iGr);
aFamily->SetGroupAttributVal(anAttrVal); aFamily->SetGroupAttributVal(anAttrVal);
} }
if(MYDEBUG) MESSAGE(aGroupName); if(MYDEBUG) MESSAGE(aGroupName);
aFamily->AddGroupName(aGroupName); aFamily->AddGroupName(aGroupName);
} }
aFamily->SetId( aFamId ); aFamily->SetId( aFamId );
myFamilies[aFamId] = aFamily; myFamilies[aFamId] = aFamily;
} }
} }
if (aMeshInfo->GetType() == MED::eSTRUCTURE){ if (aMeshInfo->GetType() == MED::eSTRUCTURE)
{
/*bool aRes = */DriverMED::buildMeshGrille(aMed,aMeshInfo,myMesh,myFamilies); /*bool aRes = */DriverMED::buildMeshGrille(aMed,aMeshInfo,myMesh,myFamilies);
continue; continue;
} }
@ -173,7 +182,8 @@ DriverMED_R_SMESHDS_Mesh
TInt aNbElems = aNodeInfo->GetNbElem(); TInt aNbElems = aNodeInfo->GetNbElem();
if(MYDEBUG) MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum); if(MYDEBUG) MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
DriverMED_FamilyPtr aFamily; DriverMED_FamilyPtr aFamily;
for(TInt iElem = 0; iElem < aNbElems; iElem++){ for ( TInt iElem = 0; iElem < aNbElems; iElem++ )
{
TCCoordSlice aCoordSlice = aNodeInfo->GetCoordSlice(iElem); TCCoordSlice aCoordSlice = aNodeInfo->GetCoordSlice(iElem);
double aCoords[3] = {0.0, 0.0, 0.0}; double aCoords[3] = {0.0, 0.0, 0.0};
for(TInt iDim = 0; iDim < 3; iDim++) for(TInt iDim = 0; iDim < 3; iDim++)
@ -182,7 +192,8 @@ DriverMED_R_SMESHDS_Mesh
if ( anIsNodeNum ) { if ( anIsNodeNum ) {
aNode = myMesh->AddNodeWithID aNode = myMesh->AddNodeWithID
(aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem)); (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
} else { }
else {
aNode = myMesh->AddNodeWithID aNode = myMesh->AddNodeWithID
(aCoords[0],aCoords[1],aCoords[2], iElem+1); (aCoords[0],aCoords[1],aCoords[2], iElem+1);
} }
@ -217,15 +228,19 @@ DriverMED_R_SMESHDS_Mesh
bool takeNumbers = true; // initially we trust the numbers from file bool takeNumbers = true; // initially we trust the numbers from file
MED::TEntityInfo aEntityInfo = aMed->GetEntityInfo(aMeshInfo, eNOD); MED::TEntityInfo aEntityInfo = aMed->GetEntityInfo(aMeshInfo, eNOD);
MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin(); MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
for (; anEntityIter != aEntityInfo.end(); anEntityIter++) {
for (; anEntityIter != aEntityInfo.end(); anEntityIter++)
{
const EEntiteMaillage& anEntity = anEntityIter->first; const EEntiteMaillage& anEntity = anEntityIter->first;
aDescendingEntitiesMap.Remove(anEntity); // Mantis issue 0020483 aDescendingEntitiesMap.Remove(anEntity); // Mantis issue 0020483
if (anEntity == eNOEUD) continue; if (anEntity == eNOEUD) continue;
// Reading MED cells to the corresponding SMDS structure // Reading MED cells to the corresponding SMDS structure
//------------------------------------------------------ //------------------------------------------------------
const MED::TGeom2Size& aGeom2Size = anEntityIter->second; const MED::TGeom2Size& aGeom2Size = anEntityIter->second;
MED::TGeom2Size::const_iterator aGeom2SizeIter = aGeom2Size.begin(); MED::TGeom2Size::const_iterator aGeom2SizeIter = aGeom2Size.begin();
for(; aGeom2SizeIter != aGeom2Size.end(); aGeom2SizeIter++){ for ( ; aGeom2SizeIter != aGeom2Size.end(); aGeom2SizeIter++)
{
const EGeometrieElement& aGeom = aGeom2SizeIter->first; const EGeometrieElement& aGeom = aGeom2SizeIter->first;
if ( anEntity == eSTRUCT_ELEMENT ) // MED_BALL (issue 0021459) if ( anEntity == eSTRUCT_ELEMENT ) // MED_BALL (issue 0021459)
@ -295,15 +310,31 @@ DriverMED_R_SMESHDS_Mesh
switch(aGeom) { switch(aGeom) {
// case ePOINT1: ## PAL16410 // case ePOINT1: ## PAL16410
// break; // break;
case ePOLYGONE: { case ePOLYGONE:
case ePOLYGON2:
{
PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom); PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom);
EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX; EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX;
TInt aNbElem = aPolygoneInfo->GetNbElem(); typedef SMDS_MeshFace* (SMESHDS_Mesh::* FAddPolyWithID)
for(TInt iElem = 0; iElem < aNbElem; iElem++){ (const std::vector<int> & nodes_ids, const int ID);
typedef SMDS_MeshFace* (SMESHDS_Mesh::* FAddPolygon)
(const std::vector<const SMDS_MeshNode*> & nodes);
FAddPolyWithID addPolyWithID = & SMESHDS_Mesh::AddPolygonalFaceWithID;
FAddPolygon addPolygon = & SMESHDS_Mesh::AddPolygonalFace;
if ( aGeom == ePOLYGON2 ) {
addPolyWithID = & SMESHDS_Mesh::AddQuadPolygonalFaceWithID;
addPolygon = & SMESHDS_Mesh::AddQuadPolygonalFace;
}
TNodeIds aNodeIds;
vector<const SMDS_MeshNode*> aNodes;
const TInt aNbElem = aPolygoneInfo->GetNbElem();
for ( TInt iElem = 0; iElem < aNbElem; iElem++ )
{
MED::TCConnSlice aConnSlice = aPolygoneInfo->GetConnSlice(iElem); MED::TCConnSlice aConnSlice = aPolygoneInfo->GetConnSlice(iElem);
TInt aNbConn = aPolygoneInfo->GetNbConn(iElem); TInt aNbConn = aPolygoneInfo->GetNbConn(iElem);
TNodeIds aNodeIds(aNbConn); aNodeIds.resize( aNbConn );
#ifdef _EDF_NODE_IDS_ #ifdef _EDF_NODE_IDS_
if(anIsNodeNum) if(anIsNodeNum)
for(TInt iConn = 0; iConn < aNbConn; iConn++) for(TInt iConn = 0; iConn < aNbConn; iConn++)
@ -318,19 +349,18 @@ DriverMED_R_SMESHDS_Mesh
bool isRenum = false; bool isRenum = false;
SMDS_MeshElement* anElement = NULL; SMDS_MeshElement* anElement = NULL;
TInt aFamNum = aPolygoneInfo->GetFamNum(iElem); TInt aFamNum = aPolygoneInfo->GetFamNum(iElem);
#ifndef _DEXCEPT_ #ifndef _DEXCEPT_
try { try {
#endif #endif
if ( anIsElemNum ) { if ( anIsElemNum ) {
TInt anElemId = aPolygoneInfo->GetElemNum( iElem ); TInt anElemId = aPolygoneInfo->GetElemNum( iElem );
anElement = myMesh->AddPolygonalFaceWithID(aNodeIds,anElemId); anElement = (myMesh->*addPolyWithID)( aNodeIds, anElemId );
} }
if ( !anElement ) { if ( !anElement ) {
vector<const SMDS_MeshNode*> aNodes(aNbConn); aNodes.resize( aNbConn );
for ( TInt iConn = 0; iConn < aNbConn; iConn++ ) for ( TInt iConn = 0; iConn < aNbConn; iConn++ )
aNodes[iConn] = FindNode( myMesh, aNodeIds[iConn] ); aNodes[iConn] = FindNode( myMesh, aNodeIds[iConn] );
anElement = myMesh->AddPolygonalFace(aNodes); anElement = (myMesh->*addPolygon)( aNodes );
isRenum = anIsElemNum; isRenum = anIsElemNum;
} }
#ifndef _DEXCEPT_ #ifndef _DEXCEPT_
@ -342,7 +372,8 @@ DriverMED_R_SMESHDS_Mesh
#endif #endif
if ( !anElement ) { if ( !anElement ) {
aResult = DRS_WARN_SKIP_ELEM; aResult = DRS_WARN_SKIP_ELEM;
}else{ }
else {
if ( isRenum ) { if ( isRenum ) {
anIsElemNum = eFAUX; anIsElemNum = eFAUX;
takeNumbers = false; takeNumbers = false;
@ -952,12 +983,15 @@ DriverMED_R_SMESHDS_Mesh
} }
if (aDescendingEntitiesMap.Extent()) isDescConn = true; // Mantis issue 0020483 if (aDescendingEntitiesMap.Extent()) isDescConn = true; // Mantis issue 0020483
} // for(int iMesh = 0; iMesh < aNbMeshes; iMesh++) } // for(int iMesh = 0; iMesh < aNbMeshes; iMesh++)
} // if aNbMeshes
#ifndef _DEXCEPT_ #ifndef _DEXCEPT_
}catch(const std::exception& exc){ }
catch(const std::exception& exc)
{
INFOS("The following exception was caught:\n\t"<<exc.what()); INFOS("The following exception was caught:\n\t"<<exc.what());
aResult = DRS_FAIL; aResult = DRS_FAIL;
}catch(...){ }
catch(...)
{
INFOS("Unknown exception was caught !!!"); INFOS("Unknown exception was caught !!!");
aResult = DRS_FAIL; aResult = DRS_FAIL;
} }

View File

@ -605,12 +605,21 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
if ( polyTypesSupported ) { if ( polyTypesSupported ) {
aTElemTypeDatas.push_back( TElemTypeData(anEntity, aTElemTypeDatas.push_back( TElemTypeData(anEntity,
ePOLYGONE, ePOLYGONE,
nbElemInfo.NbPolygons(), nbElemInfo.NbPolygons( ORDER_LINEAR ),
SMDSAbs_Face)); SMDSAbs_Face));
// we need one more loop on poly elements to count nb of their nodes // we need one more loop on poly elements to count nb of their nodes
aTElemTypeDatas.push_back( TElemTypeData(anEntity, aTElemTypeDatas.push_back( TElemTypeData(anEntity,
ePOLYGONE, ePOLYGONE,
nbElemInfo.NbPolygons(), nbElemInfo.NbPolygons( ORDER_LINEAR ),
SMDSAbs_Face));
aTElemTypeDatas.push_back( TElemTypeData(anEntity,
ePOLYGON2,
nbElemInfo.NbPolygons( ORDER_QUADRATIC ),
SMDSAbs_Face));
// we need one more loop on QUAD poly elements to count nb of their nodes
aTElemTypeDatas.push_back( TElemTypeData(anEntity,
ePOLYGON2,
nbElemInfo.NbPolygons( ORDER_QUADRATIC ),
SMDSAbs_Face)); SMDSAbs_Face));
} }
#ifdef _ELEMENTS_BY_DIM_ #ifdef _ELEMENTS_BY_DIM_
@ -706,9 +715,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
// Treat POLYGONs // Treat POLYGONs
// --------------- // ---------------
if ( aElemTypeData->_geomType == ePOLYGONE ) if ( aElemTypeData->_geomType == ePOLYGONE ||
aElemTypeData->_geomType == ePOLYGON2 )
{ {
elemIterator = myMesh->elementGeomIterator( SMDSGeom_POLYGON ); if ( aElemTypeData->_geomType == ePOLYGONE )
elemIterator = myMesh->elementEntityIterator( SMDSEntity_Polygon );
else
elemIterator = myMesh->elementEntityIterator( SMDSEntity_Quad_Polygon );
if ( nbPolygonNodes == 0 ) { if ( nbPolygonNodes == 0 ) {
// Count nb of nodes // Count nb of nodes
while ( elemIterator->more() ) { while ( elemIterator->more() ) {
@ -758,8 +772,9 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
break; break;
} }
myMed->SetPolygoneInfo(aPolygoneInfo); myMed->SetPolygoneInfo(aPolygoneInfo);
}
nbPolygonNodes = 0; // to treat next polygon type
}
} }
// Treat POLYEDREs // Treat POLYEDREs

View File

@ -71,7 +71,7 @@ namespace MED{
eQUAD4=204, eTRIA6=206, eTRIA7=207, eQUAD8=208, eQUAD9=209,eTETRA4=304, eQUAD4=204, eTRIA6=206, eTRIA7=207, eQUAD8=208, eQUAD9=209,eTETRA4=304,
ePYRA5=305, ePENTA6=306, eHEXA8=308, eOCTA12=312, eTETRA10=310, ePYRA5=305, ePENTA6=306, eHEXA8=308, eOCTA12=312, eTETRA10=310,
ePYRA13=313, ePENTA15=315, eHEXA20=320, eHEXA27=327, ePYRA13=313, ePENTA15=315, eHEXA20=320, eHEXA27=327,
ePOLYGONE=400, ePOLYEDRE=500, eNONE=0, ePOLYGONE=400, ePOLYGON2=420, ePOLYEDRE=500, eNONE=0,
eBALL=1101 /*no such a type in med.h, it's just a trick*/, eBALL=1101 /*no such a type in med.h, it's just a trick*/,
eAllGeoType=-1 } EGeometrieElement; eAllGeoType=-1 } EGeometrieElement;

View File

@ -79,6 +79,7 @@ bool InitEntity2GeomSet()
aGeomFACESet.insert(eQUAD8); aGeomFACESet.insert(eQUAD8);
aGeomFACESet.insert(eQUAD9); aGeomFACESet.insert(eQUAD9);
aGeomFACESet.insert(ePOLYGONE); aGeomFACESet.insert(ePOLYGONE);
aGeomFACESet.insert(ePOLYGON2);
TGeomSet& aGeomMAILLESet = Entity2GeomSet[eMAILLE]; TGeomSet& aGeomMAILLESet = Entity2GeomSet[eMAILLE];
aGeomMAILLESet.insert(ePOINT1); aGeomMAILLESet.insert(ePOINT1);

View File

@ -962,20 +962,17 @@ namespace MED
TValueHolder<TString, char > aMeshName(aMeshInfo.myName); TValueHolder<TString, char > aMeshName(aMeshInfo.myName);
TValueHolder<TElemNum, med_int > anIndex (theInfo.myIndex); TValueHolder<TElemNum, med_int > anIndex (theInfo.myIndex);
TInt aNbElem = (TInt)theInfo.myElemNum->size();
TValueHolder<TElemNum, med_int > aConn (theInfo.myConn); TValueHolder<TElemNum, med_int > aConn (theInfo.myConn);
TValueHolder<EEntiteMaillage, med_entity_type > anEntity (theInfo.myEntity); TValueHolder<EEntiteMaillage, med_entity_type > anEntity (theInfo.myEntity);
TValueHolder<EGeometrieElement, med_geometry_type> aGeom (theInfo.myGeom);
TValueHolder<EConnectivite, med_connectivity_mode> aConnMode(theInfo.myConnMode); TValueHolder<EConnectivite, med_connectivity_mode> aConnMode(theInfo.myConnMode);
TInt aNbElem = (TInt)theInfo.myElemNum->size();
TErr aRet; TErr aRet;
aRet = MEDmeshPolygonRd(myFile->Id(), aRet = MEDmeshPolygon2Rd(myFile->Id(), &aMeshName,
&aMeshName, MED_NO_DT, MED_NO_IT,
MED_NO_DT, anEntity, aGeom,
MED_NO_IT, aConnMode, &anIndex, &aConn);
anEntity,
aConnMode,
&anIndex,
&aConn);
if(theErr) if(theErr)
*theErr = aRet; *theErr = aRet;
@ -983,18 +980,18 @@ namespace MED
EXCEPTION(std::runtime_error,"GetPolygoneInfo - MEDmeshPolygonRd(...)"); EXCEPTION(std::runtime_error,"GetPolygoneInfo - MEDmeshPolygonRd(...)");
if(theInfo.myIsElemNames){ if(theInfo.myIsElemNames){
GetNames(theInfo,aNbElem,theInfo.myEntity,ePOLYGONE,&aRet); GetNames(theInfo,aNbElem,theInfo.myEntity,theInfo.myGeom,&aRet);
if(theErr) if(theErr)
*theErr = aRet; *theErr = aRet;
} }
if(theInfo.myIsElemNum){ if(theInfo.myIsElemNum){
GetNumeration(theInfo,aNbElem,theInfo.myEntity,ePOLYGONE,&aRet); GetNumeration(theInfo,aNbElem,theInfo.myEntity,theInfo.myGeom,&aRet);
if(theErr) if(theErr)
*theErr = aRet; *theErr = aRet;
} }
GetFamilies(theInfo,aNbElem,theInfo.myEntity,ePOLYGONE,&aRet); GetFamilies(theInfo,aNbElem,theInfo.myEntity,theInfo.myGeom,&aRet);
if(theErr) if(theErr)
*theErr = aRet; *theErr = aRet;
} }
@ -1027,33 +1024,28 @@ namespace MED
TValueHolder<TElemNum, med_int > anIndex (anInfo.myIndex); TValueHolder<TElemNum, med_int > anIndex (anInfo.myIndex);
TValueHolder<TElemNum, med_int > aConn (anInfo.myConn); TValueHolder<TElemNum, med_int > aConn (anInfo.myConn);
TValueHolder<EEntiteMaillage, med_entity_type > anEntity (anInfo.myEntity); TValueHolder<EEntiteMaillage, med_entity_type > anEntity (anInfo.myEntity);
TValueHolder<EGeometrieElement, med_geometry_type> aGeom (anInfo.myGeom);
TValueHolder<EConnectivite, med_connectivity_mode> aConnMode(anInfo.myConnMode); TValueHolder<EConnectivite, med_connectivity_mode> aConnMode(anInfo.myConnMode);
TErr aRet = MEDmeshPolygonWr(myFile->Id(), TErr aRet = MEDmeshPolygon2Wr(myFile->Id(), &aMeshName,
&aMeshName, MED_NO_DT, MED_NO_IT, MED_UNDEF_DT,
MED_NO_DT, anEntity, aGeom,
MED_NO_IT, aConnMode, anInfo.myNbElem + 1,
MED_UNDEF_DT, &anIndex, &aConn);
anEntity,
aConnMode,
anInfo.myNbElem + 1,
&anIndex,
&aConn);
if(theErr) if(theErr)
*theErr = aRet; *theErr = aRet;
else if(aRet < 0) else if(aRet < 0)
EXCEPTION(std::runtime_error,"SetPolygoneInfo - MEDmeshPolygonWr(...)"); EXCEPTION(std::runtime_error,"SetPolygoneInfo - MEDmeshPolygonWr(...)");
SetNames(anInfo,theInfo.myEntity,ePOLYGONE,&aRet); SetNames(anInfo,theInfo.myEntity,anInfo.myGeom,&aRet);
if(theErr) if(theErr)
*theErr = aRet; *theErr = aRet;
SetNumeration(anInfo,theInfo.myEntity,ePOLYGONE,&aRet); SetNumeration(anInfo,theInfo.myEntity,anInfo.myGeom,&aRet);
if(theErr) if(theErr)
*theErr = aRet; *theErr = aRet;
SetFamilies(anInfo,theInfo.myEntity,ePOLYGONE,&aRet); SetFamilies(anInfo,theInfo.myEntity,anInfo.myGeom,&aRet);
if(theErr) if(theErr)
*theErr = aRet; *theErr = aRet;
} }
@ -1094,7 +1086,7 @@ namespace MED
MED_NO_DT, MED_NO_DT,
MED_NO_IT, MED_NO_IT,
med_entity_type(theEntity), med_entity_type(theEntity),
MED_POLYGON, med_geometry_type(theGeom),
MED_CONNECTIVITY, MED_CONNECTIVITY,
med_connectivity_mode(theConnMode), med_connectivity_mode(theConnMode),
&chgt, &chgt,
@ -1433,9 +1425,7 @@ namespace MED
//----------------------------------------------------------------- //-----------------------------------------------------------------
TInt TInt TVWrapper::GetNbCells(const MED::TMeshInfo& theMeshInfo,
TVWrapper
::GetNbCells(const MED::TMeshInfo& theMeshInfo,
EEntiteMaillage theEntity, EEntiteMaillage theEntity,
EGeometrieElement theGeom, EGeometrieElement theGeom,
EConnectivite theConnMode, EConnectivite theConnMode,
@ -1449,42 +1439,44 @@ namespace MED
MED::TMeshInfo& aMeshInfo = const_cast<MED::TMeshInfo&>(theMeshInfo); MED::TMeshInfo& aMeshInfo = const_cast<MED::TMeshInfo&>(theMeshInfo);
TValueHolder<TString, char> aMeshName(aMeshInfo.myName); TValueHolder<TString, char> aMeshName(aMeshInfo.myName);
med_bool chgt,trsf; med_bool chgt,trsf;
if(theGeom!=MED::ePOLYGONE && theGeom!=MED::ePOLYEDRE && theGeom != MED::eBALL) switch ( theGeom )
{ {
return MEDmeshnEntity(myFile->Id(), case MED::ePOLYGONE:
&aMeshName, case MED::ePOLYGON2:
MED_NO_DT,
MED_NO_IT,
med_entity_type(theEntity),
med_geometry_type(theGeom),
MED_CONNECTIVITY,
med_connectivity_mode(theConnMode),
&chgt,
&trsf);
}
else if(theGeom==MED::ePOLYGONE)
{ {
return MEDmeshnEntity(myFile->Id(),&aMeshName,MED_NO_DT,MED_NO_IT,med_entity_type(theEntity), return MEDmeshnEntity(myFile->Id(),&aMeshName,
MED_POLYGON,MED_INDEX_NODE,med_connectivity_mode(theConnMode),&chgt,&trsf)-1; MED_NO_DT,MED_NO_IT,
med_entity_type(theEntity),med_geometry_type(theGeom),
MED_INDEX_NODE,med_connectivity_mode(theConnMode),
&chgt,&trsf)-1;
} }
else if ( theGeom==MED::ePOLYEDRE ) case MED::ePOLYEDRE:
{ {
return MEDmeshnEntity(myFile->Id(),&aMeshName,MED_NO_DT,MED_NO_IT,med_entity_type(theEntity), return MEDmeshnEntity(myFile->Id(),&aMeshName,
MED_POLYHEDRON,MED_INDEX_FACE,med_connectivity_mode(theConnMode),&chgt,&trsf)-1; MED_NO_DT,MED_NO_IT,
med_entity_type(theEntity),MED_POLYHEDRON,
MED_INDEX_FACE,med_connectivity_mode(theConnMode),
&chgt,&trsf)-1;
} }
else if ( theGeom==MED::eBALL ) case MED::eBALL:
{ {
return GetNbBalls( theMeshInfo ); return GetNbBalls( theMeshInfo );
} }
default:
{
return MEDmeshnEntity(myFile->Id(),&aMeshName,
MED_NO_DT,MED_NO_IT,
med_entity_type(theEntity),med_geometry_type(theGeom),
MED_CONNECTIVITY,med_connectivity_mode(theConnMode),
&chgt,&trsf);
}
}
return 0; return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void void TVWrapper::GetCellInfo(MED::TCellInfo& theInfo, TErr* theErr)
TVWrapper
::GetCellInfo(MED::TCellInfo& theInfo,
TErr* theErr)
{ {
TFileWrapper aFileWrapper(myFile,eLECTURE,theErr); TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);

View File

@ -222,10 +222,11 @@ SMESH_ActorDef::SMESH_ActorDef()
aFilter = my2DActor->GetExtractUnstructuredGrid(); aFilter = my2DActor->GetExtractUnstructuredGrid();
aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding); aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
aFilter->RegisterCellsWithType(VTK_TRIANGLE); aFilter->RegisterCellsWithType(VTK_TRIANGLE);
aFilter->RegisterCellsWithType(VTK_POLYGON);
aFilter->RegisterCellsWithType(VTK_QUAD); aFilter->RegisterCellsWithType(VTK_QUAD);
aFilter->RegisterCellsWithType(VTK_POLYGON);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD); aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE); aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
@ -245,10 +246,11 @@ SMESH_ActorDef::SMESH_ActorDef()
my2DExtActor->SetRepresentation(SMESH_DeviceActor::eInsideframe); my2DExtActor->SetRepresentation(SMESH_DeviceActor::eInsideframe);
aFilter = my2DExtActor->GetExtractUnstructuredGrid(); aFilter = my2DExtActor->GetExtractUnstructuredGrid();
aFilter->RegisterCellsWithType(VTK_TRIANGLE); aFilter->RegisterCellsWithType(VTK_TRIANGLE);
aFilter->RegisterCellsWithType(VTK_POLYGON);
aFilter->RegisterCellsWithType(VTK_QUAD); aFilter->RegisterCellsWithType(VTK_QUAD);
aFilter->RegisterCellsWithType(VTK_POLYGON);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD); aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE); aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
@ -275,10 +277,7 @@ SMESH_ActorDef::SMESH_ActorDef()
aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
//#ifdef VTK_HAVE_POLYHEDRON
MESSAGE("RegisterCellsWithType(VTK_POLYHEDRON)");
aFilter->RegisterCellsWithType(VTK_POLYHEDRON); aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
//#endif
my3DExtProp = vtkProperty::New(); my3DExtProp = vtkProperty::New();
my3DExtProp->DeepCopy(myNormalVProp); my3DExtProp->DeepCopy(myNormalVProp);
@ -1565,18 +1564,20 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
if (myEntityMode & eFaces) { if (myEntityMode & eFaces) {
if (MYDEBUG) MESSAGE("FACES"); if (MYDEBUG) MESSAGE("FACES");
aFilter->RegisterCellsWithType(VTK_TRIANGLE); aFilter->RegisterCellsWithType(VTK_TRIANGLE);
aFilter->RegisterCellsWithType(VTK_POLYGON);
aFilter->RegisterCellsWithType(VTK_QUAD); aFilter->RegisterCellsWithType(VTK_QUAD);
aFilter->RegisterCellsWithType(VTK_POLYGON);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD); aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE); aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
aHightFilter->RegisterCellsWithType(VTK_TRIANGLE); aHightFilter->RegisterCellsWithType(VTK_TRIANGLE);
aHightFilter->RegisterCellsWithType(VTK_POLYGON);
aHightFilter->RegisterCellsWithType(VTK_QUAD); aHightFilter->RegisterCellsWithType(VTK_QUAD);
aHightFilter->RegisterCellsWithType(VTK_POLYGON);
aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD); aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE); aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
} }
@ -1595,9 +1596,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
//#ifdef VTK_HAVE_POLYHEDRON
aFilter->RegisterCellsWithType(VTK_POLYHEDRON); aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
//#endif
aHightFilter->RegisterCellsWithType(VTK_TETRA); aHightFilter->RegisterCellsWithType(VTK_TETRA);
aHightFilter->RegisterCellsWithType(VTK_VOXEL); aHightFilter->RegisterCellsWithType(VTK_VOXEL);
@ -1611,9 +1610,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
aHightFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); aHightFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
//#ifdef VTK_HAVE_POLYHEDRON
aHightFilter->RegisterCellsWithType(VTK_POLYHEDRON); aHightFilter->RegisterCellsWithType(VTK_POLYHEDRON);
//#endif
} }
aFilter->Update(); aFilter->Update();
if (MYDEBUG) MESSAGE(aFilter->GetOutput()->GetNumberOfCells()); if (MYDEBUG) MESSAGE(aFilter->GetOutput()->GetNumberOfCells());

View File

@ -55,23 +55,24 @@ SMESH_ExtractGeometry::SMESH_ExtractGeometry()
{} {}
SMESH_ExtractGeometry::~SMESH_ExtractGeometry(){} SMESH_ExtractGeometry::~SMESH_ExtractGeometry()
{}
vtkIdType SMESH_ExtractGeometry::GetElemObjId(int theVtkID)
vtkIdType SMESH_ExtractGeometry::GetElemObjId(int theVtkID){ {
if( theVtkID < 0 || theVtkID >= myElemVTK2ObjIds.size()) return -1; if( theVtkID < 0 || theVtkID >= myElemVTK2ObjIds.size()) return -1;
return myElemVTK2ObjIds[theVtkID]; return myElemVTK2ObjIds[theVtkID];
} }
vtkIdType SMESH_ExtractGeometry::GetNodeObjId(int theVtkID){ vtkIdType SMESH_ExtractGeometry::GetNodeObjId(int theVtkID)
{
if ( theVtkID < 0 || theVtkID >= myNodeVTK2ObjIds.size()) return -1; if ( theVtkID < 0 || theVtkID >= myNodeVTK2ObjIds.size()) return -1;
return myNodeVTK2ObjIds[theVtkID]; return myNodeVTK2ObjIds[theVtkID];
} }
int SMESH_ExtractGeometry::RequestData( int SMESH_ExtractGeometry::RequestData(vtkInformation *vtkNotUsed(request),
vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector, vtkInformationVector **inputVector,
vtkInformationVector *outputVector) vtkInformationVector *outputVector)
{ {
@ -80,10 +81,10 @@ int SMESH_ExtractGeometry::RequestData(
vtkInformation *outInfo = outputVector->GetInformationObject(0); vtkInformation *outInfo = outputVector->GetInformationObject(0);
// get the input and ouptut // get the input and ouptut
vtkDataSet *input = vtkDataSet::SafeDownCast( vtkDataSet *input =
inInfo->Get(vtkDataObject::DATA_OBJECT())); vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast( vtkUnstructuredGrid *output =
outInfo->Get(vtkDataObject::DATA_OBJECT())); vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkIdType ptId, numPts, numCells, i, cellId, newCellId, newId, *pointMap; vtkIdType ptId, numPts, numCells, i, cellId, newCellId, newId, *pointMap;
vtkIdList *cellPts; vtkIdList *cellPts;

View File

@ -28,14 +28,16 @@
#include "SMESH_ObjectDef.h" #include "SMESH_ObjectDef.h"
#include "SMESH_ActorUtils.h" #include "SMESH_ActorUtils.h"
#include "SMDS_Mesh.hxx"
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
#include "SMDS_BallElement.hxx" #include "SMDS_BallElement.hxx"
#include "SMDS_Mesh.hxx"
#include "SMDS_MeshCell.hxx"
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
#include "SMESH_Actor.h" #include "SMESH_Actor.h"
#include "SMESH_ControlsDef.hxx" #include "SMESH_ControlsDef.hxx"
#include "SalomeApp_Application.h"
#include "VTKViewer_ExtractUnstructuredGrid.h" #include <SalomeApp_Application.h>
#include "VTKViewer_CellLocationsArray.h" #include <VTKViewer_ExtractUnstructuredGrid.h>
#include <VTKViewer_CellLocationsArray.h>
#include CORBA_SERVER_HEADER(SMESH_Gen) #include CORBA_SERVER_HEADER(SMESH_Gen)
#include CORBA_SERVER_HEADER(SALOME_Exception) #include CORBA_SERVER_HEADER(SALOME_Exception)
@ -82,48 +84,48 @@ static int MYDEBUGWITHFILES = 0;
// function : getCellType // function : getCellType
// purpose : Get type of VTK cell // purpose : Get type of VTK cell
//================================================================================= //=================================================================================
static inline vtkIdType getCellType( const SMDSAbs_ElementType theType, // static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
const bool thePoly, // const bool thePoly,
const int theNbNodes ) // const int theNbNodes )
{ // {
switch( theType ) // switch( theType )
{ // {
case SMDSAbs_0DElement: return VTK_VERTEX; // case SMDSAbs_0DElement: return VTK_VERTEX;
case SMDSAbs_Ball: return VTK_POLY_VERTEX; // case SMDSAbs_Ball: return VTK_POLY_VERTEX;
case SMDSAbs_Edge: // case SMDSAbs_Edge:
if( theNbNodes == 2 ) return VTK_LINE; // if( theNbNodes == 2 ) return VTK_LINE;
else if ( theNbNodes == 3 ) return VTK_QUADRATIC_EDGE; // else if ( theNbNodes == 3 ) return VTK_QUADRATIC_EDGE;
else return VTK_EMPTY_CELL; // else return VTK_EMPTY_CELL;
case SMDSAbs_Face : // case SMDSAbs_Face :
if (thePoly && theNbNodes>2 ) return VTK_POLYGON; // if (thePoly && theNbNodes>2 ) return VTK_POLYGON;
else if ( theNbNodes == 3 ) return VTK_TRIANGLE; // else if ( theNbNodes == 3 ) return VTK_TRIANGLE;
else if ( theNbNodes == 4 ) return VTK_QUAD; // else if ( theNbNodes == 4 ) return VTK_QUAD;
else if ( theNbNodes == 6 ) return VTK_QUADRATIC_TRIANGLE; // else if ( theNbNodes == 6 ) return VTK_QUADRATIC_TRIANGLE;
else if ( theNbNodes == 8 ) return VTK_QUADRATIC_QUAD; // else if ( theNbNodes == 8 ) return VTK_QUADRATIC_QUAD;
else if ( theNbNodes == 9 ) return VTK_BIQUADRATIC_QUAD; // else if ( theNbNodes == 9 ) return VTK_BIQUADRATIC_QUAD;
else if ( theNbNodes == 7 ) return VTK_BIQUADRATIC_TRIANGLE; // else if ( theNbNodes == 7 ) return VTK_BIQUADRATIC_TRIANGLE;
else return VTK_EMPTY_CELL; // else return VTK_EMPTY_CELL;
case SMDSAbs_Volume: // case SMDSAbs_Volume:
if (thePoly && theNbNodes>3 ) return VTK_POLYHEDRON; //VTK_CONVEX_POINT_SET; // if (thePoly && theNbNodes>3 ) return VTK_POLYHEDRON; //VTK_CONVEX_POINT_SET;
else if ( theNbNodes == 4 ) return VTK_TETRA; // else if ( theNbNodes == 4 ) return VTK_TETRA;
else if ( theNbNodes == 5 ) return VTK_PYRAMID; // else if ( theNbNodes == 5 ) return VTK_PYRAMID;
else if ( theNbNodes == 6 ) return VTK_WEDGE; // else if ( theNbNodes == 6 ) return VTK_WEDGE;
else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON; // else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON;
else if ( theNbNodes == 12 ) return VTK_HEXAGONAL_PRISM; // else if ( theNbNodes == 12 ) return VTK_HEXAGONAL_PRISM;
else if ( theNbNodes == 10 ) return VTK_QUADRATIC_TETRA; // else if ( theNbNodes == 10 ) return VTK_QUADRATIC_TETRA;
else if ( theNbNodes == 20 ) return VTK_QUADRATIC_HEXAHEDRON; // else if ( theNbNodes == 20 ) return VTK_QUADRATIC_HEXAHEDRON;
else if ( theNbNodes == 27 ) return VTK_TRIQUADRATIC_HEXAHEDRON; // else if ( theNbNodes == 27 ) return VTK_TRIQUADRATIC_HEXAHEDRON;
else if ( theNbNodes == 15 ) return VTK_QUADRATIC_WEDGE; // else if ( theNbNodes == 15 ) return VTK_QUADRATIC_WEDGE;
else if ( theNbNodes == 13 ) return VTK_QUADRATIC_PYRAMID; //VTK_CONVEX_POINT_SET; // else if ( theNbNodes == 13 ) return VTK_QUADRATIC_PYRAMID; //VTK_CONVEX_POINT_SET;
else return VTK_EMPTY_CELL; // else return VTK_EMPTY_CELL;
default: return VTK_EMPTY_CELL; // default: return VTK_EMPTY_CELL;
} // }
} // }
//================================================================================= //=================================================================================
// functions : SMESH_VisualObjDef // functions : SMESH_VisualObjDef
@ -448,7 +450,7 @@ void SMESH_VisualObjDef::buildElemPrs()
vtkIdType aNbNodes = anElem->NbNodes(); vtkIdType aNbNodes = anElem->NbNodes();
anIdList->SetNumberOfIds( aNbNodes ); anIdList->SetNumberOfIds( aNbNodes );
const vtkIdType vtkElemType = getCellType( aType, anElem->IsPoly(), aNbNodes ); const vtkIdType vtkElemType = SMDS_MeshCell::toVtkType( anElem->GetEntityType() );
int anId = anElem->GetID(); int anId = anElem->GetID();

View File

@ -143,12 +143,14 @@ SMESH_SVTKActor
{ {
if(aCell->GetCellType() == VTK_VERTEX ) { if(aCell->GetCellType() == VTK_VERTEX ) {
my0DGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds()); my0DGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds());
} else if(aCell->GetCellType() == VTK_POLY_VERTEX ) { }
else if(aCell->GetCellType() == VTK_POLY_VERTEX ) {
vtkIdType newCellId = myBallGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds()); vtkIdType newCellId = myBallGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds());
if(myVisualObj) { if(myVisualObj) {
outputCD->CopyData(cd, myVisualObj->GetElemVTKId(aPartId), newCellId); outputCD->CopyData(cd, myVisualObj->GetElemVTKId(aPartId), newCellId);
} }
} else { }
else {
myUnstructuredGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds()); myUnstructuredGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds());
} }
} }

View File

@ -1339,8 +1339,6 @@ SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
} }
else else
{ {
//#ifdef VTK_HAVE_POLYHEDRON
//MESSAGE("AddPolygonalFaceWithID vtk " << ID);
myNodeIds.resize( nodes.size() ); myNodeIds.resize( nodes.size() );
for ( size_t i = 0; i < nodes.size(); ++i ) for ( size_t i = 0; i < nodes.size(); ++i )
myNodeIds[i] = nodes[i]->getVtkId(); myNodeIds[i] = nodes[i]->getVtkId();
@ -1354,25 +1352,12 @@ SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
return 0; return 0;
} }
face = facevtk; face = facevtk;
//#else
// MESSAGE("AddPolygonalFaceWithID smds " << ID);
// for ( int i = 0; i < nodes.size(); ++i )
// if ( !nodes[ i ] ) return 0;
// face = new SMDS_PolygonalFaceOfNodes(nodes);
//#endif
adjustmyCellsCapacity(ID); adjustmyCellsCapacity(ID);
myCells[ID] = face; myCells[ID] = face;
myInfo.myNbPolygons++; myInfo.myNbPolygons++;
} }
//#ifndef VTK_HAVE_POLYHEDRON
// if (!registerElement(ID, face))
// {
// registerElement(myElementIDFactory->GetFreeID(), face);
// //RemoveElement(face, false);
// //face = NULL;
// }
//#endif
return face; return face;
} }
@ -1386,6 +1371,69 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector<const SMDS_MeshNode*> &
return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID()); return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
} }
///////////////////////////////////////////////////////////////////////////////
/// Add a quadratic polygon defined by its nodes IDs
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<int> & nodes_ids,
const int ID)
{
vector<const SMDS_MeshNode*> nodes( nodes_ids.size() );
for ( size_t i = 0; i < nodes.size(); i++) {
nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
if (!nodes[i]) return NULL;
}
return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
}
///////////////////////////////////////////////////////////////////////////////
/// Add a quadratic polygon defined by its nodes
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshFace*
SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
const int ID)
{
SMDS_MeshFace * face;
if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
if (hasConstructionEdges())
{
MESSAGE("Error : Not implemented");
return NULL;
}
else
{
myNodeIds.resize( nodes.size() );
for ( size_t i = 0; i < nodes.size(); ++i )
myNodeIds[i] = nodes[i]->getVtkId();
SMDS_VtkFace *facevtk = myFacePool->getNew();
facevtk->initQuadPoly(myNodeIds, this);
if (!this->registerElement(ID,facevtk))
{
this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
myFacePool->destroy(facevtk);
return 0;
}
face = facevtk;
adjustmyCellsCapacity(ID);
myCells[ID] = face;
myInfo.myNbQuadPolygons++;
}
return face;
}
///////////////////////////////////////////////////////////////////////////////
/// Add a quadratic polygon defined by its nodes.
/// An ID is automatically affected to the created face.
///////////////////////////////////////////////////////////////////////////////
SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
{
return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// Create a new polyhedral volume and add it to the mesh. /// Create a new polyhedral volume and add it to the mesh.
/// @param ID The ID of the new volume /// @param ID The ID of the new volume

View File

@ -576,6 +576,14 @@ public:
virtual SMDS_MeshFace* AddPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes); virtual SMDS_MeshFace* AddPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes);
virtual SMDS_MeshFace* AddQuadPolygonalFaceWithID(const std::vector<int> & nodes_ids,
const int ID);
virtual SMDS_MeshFace* AddQuadPolygonalFaceWithID(const std::vector<const SMDS_MeshNode*> & nodes,
const int ID);
virtual SMDS_MeshFace* AddQuadPolygonalFace(const std::vector<const SMDS_MeshNode*> & nodes);
virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
(const std::vector<int> & nodes_ids, (const std::vector<int> & nodes_ids,
const std::vector<int> & quantities, const std::vector<int> & quantities,

View File

@ -56,7 +56,7 @@ VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType)
vtkTypes[ SMDSEntity_Quad_Quadrangle ] = VTK_QUADRATIC_QUAD; vtkTypes[ SMDSEntity_Quad_Quadrangle ] = VTK_QUADRATIC_QUAD;
vtkTypes[ SMDSEntity_BiQuad_Quadrangle ] = VTK_BIQUADRATIC_QUAD; vtkTypes[ SMDSEntity_BiQuad_Quadrangle ] = VTK_BIQUADRATIC_QUAD;
vtkTypes[ SMDSEntity_Polygon ] = VTK_POLYGON; vtkTypes[ SMDSEntity_Polygon ] = VTK_POLYGON;
//vtkTypes[ SMDSEntity_Quad_Polygon ] = ; vtkTypes[ SMDSEntity_Quad_Polygon ] = VTK_QUADRATIC_POLYGON;
vtkTypes[ SMDSEntity_Tetra ] = VTK_TETRA; vtkTypes[ SMDSEntity_Tetra ] = VTK_TETRA;
vtkTypes[ SMDSEntity_Quad_Tetra ] = VTK_QUADRATIC_TETRA; vtkTypes[ SMDSEntity_Quad_Tetra ] = VTK_QUADRATIC_TETRA;
vtkTypes[ SMDSEntity_Pyramid ] = VTK_PYRAMID; vtkTypes[ SMDSEntity_Pyramid ] = VTK_PYRAMID;
@ -166,12 +166,14 @@ const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType)
//================================================================================ //================================================================================
/*! /*!
* \brief Return indices to reverse an SMDS cell of given type * \brief Return indices to reverse an SMDS cell of given type.
* nbNodes is useful for polygons
* Usage: reverseIDs[i] = forwardIDs[ indices[ i ]] * Usage: reverseIDs[i] = forwardIDs[ indices[ i ]]
*/ */
//================================================================================ //================================================================================
const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType) const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType,
const size_t nbNodes)
{ {
static std::vector< std::vector< int > > reverseInterlaces; static std::vector< std::vector< int > > reverseInterlaces;
if ( reverseInterlaces.empty() ) if ( reverseInterlaces.empty() )
@ -256,6 +258,31 @@ const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsT
reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 ); reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
} }
} }
if ( smdsType == SMDSEntity_Polygon )
{
if ( reverseInterlaces[ smdsType ].size() != nbNodes )
{
reverseInterlaces[ smdsType ].resize( nbNodes );
for ( size_t i = 0; i < nbNodes; ++i )
reverseInterlaces[ smdsType ][i] = nbNodes - i - 1;
}
}
else if ( smdsType == SMDSEntity_Quad_Polygon )
{
if ( reverseInterlaces[ smdsType ].size() != nbNodes )
{
// e.g. for 8 nodes: [ 0, 3,2,1, 7,6,5,4 ]
reverseInterlaces[ smdsType ].resize( nbNodes );
size_t pos = 0;
reverseInterlaces[ smdsType ][pos++] = 0;
for ( int i = nbNodes / 2 - 1; i > 0 ; --i ) // 3,2,1
reverseInterlaces[ smdsType ][pos++] = i;
for ( int i = nbNodes - 1; i >= nbNodes / 2; --i ) // 7,6,5,4
reverseInterlaces[ smdsType ][pos++] = i;
}
}
return reverseInterlaces[smdsType]; return reverseInterlaces[smdsType];
} }
@ -266,7 +293,8 @@ const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsT
*/ */
//================================================================================ //================================================================================
const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType) const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType,
const size_t nbNodes)
{ {
static std::vector< std::vector< int > > interlace; static std::vector< std::vector< int > > interlace;
if ( interlace.empty() ) if ( interlace.empty() )
@ -287,6 +315,19 @@ const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType sm
interlace[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 ); interlace[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
} }
} }
if ( smdsType == SMDSEntity_Quad_Polygon )
{
if ( interlace[smdsType].size() != nbNodes )
{
interlace[smdsType].resize( nbNodes );
for ( size_t i = 0; i < nbNodes / 2; ++i )
{
interlace[smdsType][i*2+0] = i;
interlace[smdsType][i*2+1] = i + nbNodes / 2;
}
}
}
return interlace[smdsType]; return interlace[smdsType];
} }

View File

@ -45,10 +45,12 @@ public:
static const std::vector<int>& fromVtkOrder(VTKCellType vtkType); static const std::vector<int>& fromVtkOrder(VTKCellType vtkType);
static const std::vector<int>& fromVtkOrder(SMDSAbs_EntityType smdsType); static const std::vector<int>& fromVtkOrder(SMDSAbs_EntityType smdsType);
static const std::vector<int>& reverseSmdsOrder(SMDSAbs_EntityType smdsType); static const std::vector<int>& reverseSmdsOrder(SMDSAbs_EntityType smdsType,
static const std::vector<int>& interlacedSmdsOrder(SMDSAbs_EntityType smdsType); const size_t nbNodes=0);
static const std::vector<int>& interlacedSmdsOrder(SMDSAbs_EntityType smdsType,
const size_t nbNodes=0);
template< class VECT > template< class VECT > // interlacedIDs[i] = smdsIDs[ indices[ i ]]
static void applyInterlace( const std::vector<int>& interlace, VECT & data) static void applyInterlace( const std::vector<int>& interlace, VECT & data)
{ {
if ( interlace.empty() ) return; if ( interlace.empty() ) return;
@ -57,6 +59,15 @@ public:
tmpData[i] = data[ interlace[i] ]; tmpData[i] = data[ interlace[i] ];
data.swap( tmpData ); data.swap( tmpData );
} }
template< class VECT > // interlacedIDs[ indices[ i ]] = smdsIDs[i]
static void applyInterlaceRev( const std::vector<int>& interlace, VECT & data)
{
if ( interlace.empty() ) return;
VECT tmpData( data.size() );
for ( size_t i = 0; i < data.size(); ++i )
tmpData[ interlace[i] ] = data[i];
data.swap( tmpData );
}
static int nbCells; static int nbCells;

View File

@ -56,7 +56,7 @@ public:
inline int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const; inline int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const;
int NbBiQuadTriangles() const { return myNbBiQuadTriangles; } int NbBiQuadTriangles() const { return myNbBiQuadTriangles; }
int NbBiQuadQuadrangles() const { return myNbBiQuadQuadrangles; } int NbBiQuadQuadrangles() const { return myNbBiQuadQuadrangles; }
int NbPolygons() const { return myNbPolygons; } inline int NbPolygons(SMDSAbs_ElementOrder order = ORDER_ANY) const;
inline int NbVolumes (SMDSAbs_ElementOrder order = ORDER_ANY) const; inline int NbVolumes (SMDSAbs_ElementOrder order = ORDER_ANY) const;
inline int NbTetras (SMDSAbs_ElementOrder order = ORDER_ANY) const; inline int NbTetras (SMDSAbs_ElementOrder order = ORDER_ANY) const;
@ -90,7 +90,7 @@ private:
int myNbEdges , myNbQuadEdges ; int myNbEdges , myNbQuadEdges ;
int myNbTriangles , myNbQuadTriangles, myNbBiQuadTriangles ; int myNbTriangles , myNbQuadTriangles, myNbBiQuadTriangles ;
int myNbQuadrangles, myNbQuadQuadrangles, myNbBiQuadQuadrangles; int myNbQuadrangles, myNbQuadQuadrangles, myNbBiQuadQuadrangles;
int myNbPolygons; int myNbPolygons , myNbQuadPolygons;
int myNbTetras , myNbQuadTetras ; int myNbTetras , myNbQuadTetras ;
int myNbHexas , myNbQuadHexas, myNbTriQuadHexas; int myNbHexas , myNbQuadHexas, myNbTriQuadHexas;
@ -110,7 +110,7 @@ inline SMDS_MeshInfo::SMDS_MeshInfo():
myNbEdges (0), myNbQuadEdges (0), myNbEdges (0), myNbQuadEdges (0),
myNbTriangles (0), myNbQuadTriangles (0), myNbBiQuadTriangles(0), myNbTriangles (0), myNbQuadTriangles (0), myNbBiQuadTriangles(0),
myNbQuadrangles(0), myNbQuadQuadrangles(0), myNbBiQuadQuadrangles(0), myNbQuadrangles(0), myNbQuadQuadrangles(0), myNbBiQuadQuadrangles(0),
myNbPolygons (0), myNbPolygons (0), myNbQuadPolygons (0),
myNbTetras (0), myNbQuadTetras (0), myNbTetras (0), myNbQuadTetras (0),
myNbHexas (0), myNbQuadHexas (0), myNbTriQuadHexas(0), myNbHexas (0), myNbQuadHexas (0), myNbTriQuadHexas(0),
myNbPyramids (0), myNbQuadPyramids(0), myNbPyramids (0), myNbQuadPyramids(0),
@ -194,6 +194,7 @@ inline SMDS_MeshInfo& // operator=
SMDS_MeshInfo::operator=(const SMDS_MeshInfo& other) SMDS_MeshInfo::operator=(const SMDS_MeshInfo& other)
{ for ( int i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=(*other.myNb[i]); { for ( int i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=(*other.myNb[i]);
myNbPolygons = other.myNbPolygons; myNbPolygons = other.myNbPolygons;
myNbQuadPolygons = other.myNbQuadPolygons;
myNbPolyhedrons = other.myNbPolyhedrons; myNbPolyhedrons = other.myNbPolyhedrons;
return *this; return *this;
} }
@ -201,7 +202,7 @@ SMDS_MeshInfo::operator=(const SMDS_MeshInfo& other)
inline void // Clear inline void // Clear
SMDS_MeshInfo::Clear() SMDS_MeshInfo::Clear()
{ for ( int i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=0; { for ( int i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=0;
myNbPolygons=myNbPolyhedrons=0; myNbPolygons=myNbQuadPolygons=myNbPolyhedrons=0;
} }
inline int // index inline int // index
@ -217,20 +218,26 @@ SMDS_MeshInfo::add(const SMDS_MeshElement* el)
{ ++(*myNb[ index(el->GetType(), el->NbNodes()) ]); } { ++(*myNb[ index(el->GetType(), el->NbNodes()) ]); }
inline void // addWithPoly inline void // addWithPoly
SMDS_MeshInfo::addWithPoly(const SMDS_MeshElement* el) SMDS_MeshInfo::addWithPoly(const SMDS_MeshElement* el) {
{ switch ( el->GetEntityType() ) {
if ( el->IsPoly() ) case SMDSEntity_Polygon: ++myNbPolygons; break;
++( el->GetType()==SMDSAbs_Face ? myNbPolygons : myNbPolyhedrons ); case SMDSEntity_Quad_Polygon: ++myNbQuadPolygons; break;
else case SMDSEntity_Polyhedra: ++myNbPolyhedrons; break;
add(el); default: add(el);
}
} }
inline void // RemoveEdge inline void // RemoveEdge
SMDS_MeshInfo::RemoveEdge(const SMDS_MeshElement* el) SMDS_MeshInfo::RemoveEdge(const SMDS_MeshElement* el)
{ if ( el->IsQuadratic() ) --myNbQuadEdges; else --myNbEdges; } { if ( el->IsQuadratic() ) --myNbQuadEdges; else --myNbEdges; }
inline void // RemoveFace inline void // RemoveFace
SMDS_MeshInfo::RemoveFace(const SMDS_MeshElement* el) SMDS_MeshInfo::RemoveFace(const SMDS_MeshElement* el) {
{ if ( el->IsPoly() ) --myNbPolygons; else remove( el ); } switch ( el->GetEntityType() ) {
case SMDSEntity_Polygon: --myNbPolygons; break;
case SMDSEntity_Quad_Polygon: --myNbQuadPolygons; break;
default: remove(el);
}
}
inline void // RemoveVolume inline void // RemoveVolume
SMDS_MeshInfo::RemoveVolume(const SMDS_MeshElement* el) SMDS_MeshInfo::RemoveVolume(const SMDS_MeshElement* el)
@ -242,7 +249,7 @@ SMDS_MeshInfo::NbEdges (SMDSAbs_ElementOrder order) const
inline int // NbFaces inline int // NbFaces
SMDS_MeshInfo::NbFaces (SMDSAbs_ElementOrder order) const SMDS_MeshInfo::NbFaces (SMDSAbs_ElementOrder order) const
{ return NbTriangles(order)+NbQuadrangles(order)+(order == ORDER_QUADRATIC ? 0 : myNbPolygons); } { return NbTriangles(order)+NbQuadrangles(order)+(order == ORDER_ANY ? myNbPolygons+myNbQuadPolygons : order == ORDER_LINEAR ? myNbPolygons : myNbQuadPolygons ); }
inline int // NbTriangles inline int // NbTriangles
SMDS_MeshInfo::NbTriangles (SMDSAbs_ElementOrder order) const SMDS_MeshInfo::NbTriangles (SMDSAbs_ElementOrder order) const
@ -252,6 +259,10 @@ inline int // NbQuadrangles
SMDS_MeshInfo::NbQuadrangles(SMDSAbs_ElementOrder order) const SMDS_MeshInfo::NbQuadrangles(SMDSAbs_ElementOrder order) const
{ return order == ORDER_ANY ? myNbQuadrangles+myNbQuadQuadrangles+myNbBiQuadQuadrangles : order == ORDER_LINEAR ? myNbQuadrangles : myNbQuadQuadrangles+myNbBiQuadQuadrangles; } { return order == ORDER_ANY ? myNbQuadrangles+myNbQuadQuadrangles+myNbBiQuadQuadrangles : order == ORDER_LINEAR ? myNbQuadrangles : myNbQuadQuadrangles+myNbBiQuadQuadrangles; }
inline int // NbPolygons
SMDS_MeshInfo::NbPolygons(SMDSAbs_ElementOrder order) const
{ return order == ORDER_ANY ? myNbPolygons+myNbQuadPolygons : order == ORDER_LINEAR ? myNbPolygons : myNbQuadPolygons; }
inline int // NbVolumes inline int // NbVolumes
SMDS_MeshInfo::NbVolumes (SMDSAbs_ElementOrder order) const SMDS_MeshInfo::NbVolumes (SMDSAbs_ElementOrder order) const
{ return NbTetras(order) + NbHexas(order) + NbPyramids(order) + NbPrisms(order) + NbHexPrisms(order) + (order == ORDER_QUADRATIC ? 0 : myNbPolyhedrons); } { return NbTetras(order) + NbHexas(order) + NbPyramids(order) + NbPrisms(order) + NbHexPrisms(order) + (order == ORDER_QUADRATIC ? 0 : myNbPolyhedrons); }
@ -283,7 +294,7 @@ SMDS_MeshInfo::NbElements(SMDSAbs_ElementType type) const
switch (type) { switch (type) {
case SMDSAbs_All: case SMDSAbs_All:
for ( int i=1+index( SMDSAbs_Node,1 ); i<myNb.size(); ++i ) if ( myNb[i] ) nb += *myNb[i]; for ( int i=1+index( SMDSAbs_Node,1 ); i<myNb.size(); ++i ) if ( myNb[i] ) nb += *myNb[i];
nb += myNbPolygons + myNbPolyhedrons; nb += myNbPolygons + myNbQuadPolygons + myNbPolyhedrons;
break; break;
case SMDSAbs_Volume: case SMDSAbs_Volume:
nb = ( myNbTetras+ myNbPyramids+ myNbPrisms+ myNbHexas+ myNbHexPrism+ nb = ( myNbTetras+ myNbPyramids+ myNbPrisms+ myNbHexas+ myNbHexPrism+
@ -293,7 +304,7 @@ SMDS_MeshInfo::NbElements(SMDSAbs_ElementType type) const
case SMDSAbs_Face: case SMDSAbs_Face:
nb = ( myNbTriangles+ myNbQuadrangles+ nb = ( myNbTriangles+ myNbQuadrangles+
myNbQuadTriangles+ myNbBiQuadTriangles+ myNbQuadTriangles+ myNbBiQuadTriangles+
myNbQuadQuadrangles+ myNbBiQuadQuadrangles+ myNbPolygons ); myNbQuadQuadrangles+ myNbBiQuadQuadrangles+ myNbPolygons+ myNbQuadPolygons );
break; break;
case SMDSAbs_Edge: case SMDSAbs_Edge:
nb = myNbEdges + myNbQuadEdges; nb = myNbEdges + myNbQuadEdges;
@ -339,7 +350,7 @@ SMDS_MeshInfo::NbEntities(SMDSAbs_EntityType type) const
case SMDSEntity_Polyhedra: return myNbPolyhedrons; case SMDSEntity_Polyhedra: return myNbPolyhedrons;
case SMDSEntity_0D: return myNb0DElements; case SMDSEntity_0D: return myNb0DElements;
case SMDSEntity_Ball: return myNbBalls; case SMDSEntity_Ball: return myNbBalls;
case SMDSEntity_Quad_Polygon: case SMDSEntity_Quad_Polygon: return myNbQuadPolygons;
case SMDSEntity_Quad_Polyhedra: case SMDSEntity_Quad_Polyhedra:
break; break;
} }
@ -362,7 +373,7 @@ SMDS_MeshInfo::NbElementsOfGeom(SMDSAbs_GeometryType geom) const
case SMDSGeom_QUADRANGLE: return (myNbQuadrangles + case SMDSGeom_QUADRANGLE: return (myNbQuadrangles +
myNbQuadQuadrangles + myNbQuadQuadrangles +
myNbBiQuadQuadrangles ); myNbBiQuadQuadrangles );
case SMDSGeom_POLYGON: return myNbPolygons; case SMDSGeom_POLYGON: return (myNbPolygons + myNbQuadPolygons );
// 3D: // 3D:
case SMDSGeom_TETRA: return (myNbTetras + case SMDSGeom_TETRA: return (myNbTetras +
myNbQuadTetras); myNbQuadTetras);
@ -411,7 +422,7 @@ SMDS_MeshInfo::setNb(const SMDSAbs_EntityType geomType, const int nb)
case SMDSEntity_Tetra: myNbTetras = nb; break; case SMDSEntity_Tetra: myNbTetras = nb; break;
case SMDSEntity_TriQuad_Hexa: myNbTriQuadHexas = nb; break; case SMDSEntity_TriQuad_Hexa: myNbTriQuadHexas = nb; break;
case SMDSEntity_Triangle: myNbTriangles = nb; break; case SMDSEntity_Triangle: myNbTriangles = nb; break;
case SMDSEntity_Quad_Polygon: case SMDSEntity_Quad_Polygon: myNbQuadPolygons = nb; break;
case SMDSEntity_Quad_Polyhedra: case SMDSEntity_Quad_Polyhedra:
break; break;
} }

View File

@ -43,6 +43,8 @@
using namespace std; using namespace std;
namespace
{
// ====================================================== // ======================================================
// Node indices in faces depending on volume orientation // Node indices in faces depending on volume orientation
// making most faces normals external // making most faces normals external
@ -349,8 +351,6 @@ static int TriQuadHexa_nbN [] = { 9, 9, 9, 9, 9, 9 };
// ======================================================== // ========================================================
// to perform some calculations without linkage to CASCADE // to perform some calculations without linkage to CASCADE
// ======================================================== // ========================================================
namespace
{
struct XYZ { struct XYZ {
double x; double x;
double y; double y;
@ -1498,6 +1498,7 @@ double SMDS_VolumeTool::MaxLinearSize2() const
//================================================================================ //================================================================================
/*! /*!
* \brief fast check that only one volume is build on the face nodes * \brief fast check that only one volume is build on the face nodes
* This check is valid for conformal meshes only
*/ */
//================================================================================ //================================================================================
@ -1511,18 +1512,29 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherV
const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex ); const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
const int di = myVolume->IsQuadratic() ? 2 : 1; const int di = myVolume->IsQuadratic() ? 2 : 1;
const SMDS_MeshNode* n1 = nodes[di*0]; const int nbN = ( myFaceNbNodes/di <= 4 && !IsPoly()) ? 3 : myFaceNbNodes/di; // nb nodes to check
const SMDS_MeshNode* n2 = nodes[di*1];
const SMDS_MeshNode* n3 = nodes[di*2];
SMDS_ElemIteratorPtr eIt = n1->GetInverseElementIterator( SMDSAbs_Volume ); SMDS_ElemIteratorPtr eIt = nodes[0]->GetInverseElementIterator( SMDSAbs_Volume );
SMDS_ElemIteratorPtr nIt; while ( eIt->more() )
while ( eIt->more() ) {
const SMDS_MeshElement* vol = eIt->next();
if ( vol != myVolume &&
vol->GetNodeIndex( n2 ) >= 0 &&
vol->GetNodeIndex( n3 ) >= 0 )
{ {
const SMDS_MeshElement* vol = eIt->next();
if ( vol == myVolume )
continue;
int iN;
for ( iN = 1; iN < nbN; ++iN )
if ( vol->GetNodeIndex( nodes[ iN*di ]) < 0 )
break;
if ( iN == nbN ) // nbN nodes are shared with vol
{
// if ( vol->IsPoly() || vol->NbFaces() > 6 ) // vol is polyhed or hex prism
// {
// int nb = myFaceNbNodes;
// if ( myVolume->GetEntityType() != vol->GetEntityType() )
// nb -= ( GetCenterNodeIndex(0) > 0 );
// set<const SMDS_MeshNode*> faceNodes( nodes, nodes + nb );
// if ( SMDS_VolumeTool( vol ).GetFaceIndex( faceNodes ) < 0 )
// continue;
// }
if ( otherVol ) *otherVol = vol; if ( otherVol ) *otherVol = vol;
return !isFree; return !isFree;
} }

View File

@ -71,7 +71,7 @@ SMDS_VtkCellIteratorToUNV::SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCel
vtkUnstructuredGrid* grid = _mesh->getGrid(); vtkUnstructuredGrid* grid = _mesh->getGrid();
grid->GetCellPoints((vtkIdType)_cellId, (vtkIdType&)_nbNodes, pts); grid->GetCellPoints((vtkIdType)_cellId, (vtkIdType&)_nbNodes, pts);
_vtkIdList->SetNumberOfIds(_nbNodes); _vtkIdList->SetNumberOfIds(_nbNodes);
int *ids = 0; const int *ids = 0;
switch (_type) switch (_type)
{ {
case SMDSEntity_Quad_Edge: case SMDSEntity_Quad_Edge:
@ -133,13 +133,11 @@ SMDS_VtkCellIteratorToUNV::SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCel
case SMDSEntity_Polyhedra: case SMDSEntity_Polyhedra:
case SMDSEntity_Quad_Polyhedra: case SMDSEntity_Quad_Polyhedra:
default: default:
{ const std::vector<int>& i = SMDS_MeshCell::interlacedSmdsOrder(aType, _nbNodes);
// static int id[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, if ( !i.empty() )
// 25, 26, 27, 28, 29 }; ids = & i[0];
// ids = id;
// break;
}
} }
if ( ids ) if ( ids )
for (int i = 0; i < _nbNodes; i++) for (int i = 0; i < _nbNodes; i++)
_vtkIdList->SetId(i, pts[ids[i]]); _vtkIdList->SetId(i, pts[ids[i]]);

View File

@ -85,6 +85,15 @@ void SMDS_VtkFace::initPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* me
mesh->setMyModified(); mesh->setMyModified();
} }
void SMDS_VtkFace::initQuadPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
{
SMDS_MeshFace::init();
vtkUnstructuredGrid* grid = mesh->getGrid();
myMeshId = mesh->getMeshId();
myVtkID = grid->InsertNextLinkedCell(VTK_QUADRATIC_POLYGON, nodeIds.size(), (vtkIdType*) &nodeIds[0]);
mesh->setMyModified();
}
bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
{ {
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
@ -111,7 +120,6 @@ void SMDS_VtkFace::Print(std::ostream & OS) const
int SMDS_VtkFace::NbEdges() const int SMDS_VtkFace::NbEdges() const
{ {
// TODO quadratic polygons ?
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
vtkIdType aVtkType = grid->GetCellType(this->myVtkID); vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
int nbEdges = 3; int nbEdges = 3;
@ -127,6 +135,9 @@ int SMDS_VtkFace::NbEdges() const
case VTK_BIQUADRATIC_QUAD: case VTK_BIQUADRATIC_QUAD:
nbEdges = 4; nbEdges = 4;
break; break;
case VTK_QUADRATIC_POLYGON:
nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints() / 2;
break;
case VTK_POLYGON: case VTK_POLYGON:
default: default:
nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints(); nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints();
@ -186,6 +197,7 @@ bool SMDS_VtkFace::IsQuadratic() const
{ {
case VTK_QUADRATIC_TRIANGLE: case VTK_QUADRATIC_TRIANGLE:
case VTK_QUADRATIC_QUAD: case VTK_QUADRATIC_QUAD:
case VTK_QUADRATIC_POLYGON:
case VTK_BIQUADRATIC_QUAD: case VTK_BIQUADRATIC_QUAD:
case VTK_BIQUADRATIC_TRIANGLE: case VTK_BIQUADRATIC_TRIANGLE:
return true; return true;
@ -199,7 +211,7 @@ bool SMDS_VtkFace::IsPoly() const
{ {
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
vtkIdType aVtkType = grid->GetCellType(this->myVtkID); vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
return (aVtkType == VTK_POLYGON); return ( aVtkType == VTK_POLYGON || aVtkType == VTK_QUADRATIC_POLYGON );
} }
bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
@ -217,6 +229,9 @@ bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
case VTK_BIQUADRATIC_QUAD: case VTK_BIQUADRATIC_QUAD:
rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7 rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7
break; break;
case VTK_QUADRATIC_POLYGON:
rankFirstMedium = grid->GetCell(myVtkID)->GetNumberOfPoints() / 2;
break;
default: default:
//MESSAGE("wrong element type " << aVtkType); //MESSAGE("wrong element type " << aVtkType);
return false; return false;
@ -248,8 +263,17 @@ int SMDS_VtkFace::NbCornerNodes() const
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints(); int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
vtkIdType aVtkType = grid->GetCellType(myVtkID); vtkIdType aVtkType = grid->GetCellType(myVtkID);
if ( aVtkType != VTK_POLYGON ) switch ( aVtkType )
return nbPoints <= 4 ? nbPoints : nbPoints / 2; {
case VTK_POLYGON:
break;
case VTK_QUADRATIC_POLYGON:
nbPoints /= 2;
break;
default:
if ( nbPoints > 4 )
nbPoints /= 2;
}
return nbPoints; return nbPoints;
} }
@ -273,7 +297,8 @@ SMDSAbs_GeometryType SMDS_VtkFace::GetGeomType() const
case VTK_QUADRATIC_QUAD: case VTK_QUADRATIC_QUAD:
case VTK_BIQUADRATIC_QUAD: return SMDSGeom_QUADRANGLE; case VTK_BIQUADRATIC_QUAD: return SMDSGeom_QUADRANGLE;
case VTK_POLYGON: return SMDSGeom_POLYGON; case VTK_POLYGON:
case VTK_QUADRATIC_POLYGON: return SMDSGeom_POLYGON;
default:; default:;
} }
return SMDSGeom_NONE; return SMDSGeom_NONE;

View File

@ -34,6 +34,7 @@ public:
~SMDS_VtkFace(); ~SMDS_VtkFace();
void init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh); void init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
void initPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh); void initPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
void initQuadPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
void ChangeApex(SMDS_MeshNode* node); // to use only for tmp triangles void ChangeApex(SMDS_MeshNode* node); // to use only for tmp triangles

View File

@ -1783,10 +1783,10 @@ int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception)
*/ */
//================================================================================ //================================================================================
int SMESH_Mesh::NbPolygons() const throw(SALOME_Exception) int SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
{ {
Unexpect aCatch(SalomeException); Unexpect aCatch(SalomeException);
return _myMeshDS->GetMeshInfo().NbPolygons(); return _myMeshDS->GetMeshInfo().NbPolygons(order);
} }
//================================================================================ //================================================================================

View File

@ -283,7 +283,7 @@ class SMESH_EXPORT SMESH_Mesh
int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
int NbBiQuadQuadrangles() const throw(SALOME_Exception); int NbBiQuadQuadrangles() const throw(SALOME_Exception);
int NbBiQuadTriangles() const throw(SALOME_Exception); int NbBiQuadTriangles() const throw(SALOME_Exception);
int NbPolygons() const throw(SALOME_Exception); int NbPolygons(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
int NbVolumes(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); int NbVolumes(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
int NbTetras(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); int NbTetras(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);

File diff suppressed because it is too large Load Diff

View File

@ -73,21 +73,49 @@ public:
void ClearLastCreated(); void ClearLastCreated();
SMESH_ComputeErrorPtr & GetError() { return myError; } SMESH_ComputeErrorPtr & GetError() { return myError; }
// --------------------------------------------------------------------------------
struct ElemFeatures //!< Features of element to create
{
SMDSAbs_ElementType myType;
bool myIsPoly, myIsQuad;
int myID;
double myBallDiameter;
std::vector<int> myPolyhedQuantities;
ElemFeatures( SMDSAbs_ElementType type=SMDSAbs_All, bool isPoly=false, bool isQuad=false )
:myType( type ), myIsPoly(isPoly), myIsQuad(isQuad), myID(-1), myBallDiameter(0) {}
ElemFeatures& Init( SMDSAbs_ElementType type, bool isPoly=false, bool isQuad=false )
{ myType = type; myIsPoly = isPoly; myIsQuad = isQuad; return *this; }
ElemFeatures& Init( const SMDS_MeshElement* elem, bool basicOnly=true );
ElemFeatures& Init( double diameter )
{ myType = SMDSAbs_Ball; myBallDiameter = diameter; return *this; }
ElemFeatures& Init( vector<int>& quanities, bool isQuad=false )
{ myType = SMDSAbs_Volume; myIsPoly = 1; myIsQuad = isQuad;
myPolyhedQuantities.swap( quanities ); return *this; }
ElemFeatures& Init( const vector<int>& quanities, bool isQuad=false )
{ myType = SMDSAbs_Volume; myIsPoly = 1; myIsQuad = isQuad;
myPolyhedQuantities = quanities; return *this; }
ElemFeatures& SetPoly(bool isPoly) { myIsPoly = isPoly; return *this; }
ElemFeatures& SetQuad(bool isQuad) { myIsQuad = isQuad; return *this; }
ElemFeatures& SetID (int ID) { myID = ID; return *this; }
};
/*! /*!
* \brief Add element * \brief Add element
*/ */
SMDS_MeshElement* AddElement(const std::vector<const SMDS_MeshNode*> & nodes, SMDS_MeshElement* AddElement(const std::vector<const SMDS_MeshNode*> & nodes,
const SMDSAbs_ElementType type, const ElemFeatures& features);
const bool isPoly,
const int ID = -1,
const double ballDiameter=0.);
/*! /*!
* \brief Add element * \brief Add element
*/ */
SMDS_MeshElement* AddElement(const std::vector<int> & nodeIDs, SMDS_MeshElement* AddElement(const std::vector<int> & nodeIDs,
const SMDSAbs_ElementType type, const ElemFeatures& features);
const bool isPoly,
const int ID = -1);
int Remove (const std::list< int >& theElemIDs, const bool isNodes); int Remove (const std::list< int >& theElemIDs, const bool isNodes);
// Remove a node or an element. // Remove a node or an element.
@ -744,7 +772,7 @@ public:
bool doubleNodes( SMESHDS_Mesh* theMeshDS, bool doubleNodes( SMESHDS_Mesh* theMeshDS,
const TIDSortedElemSet& theElems, const TIDSortedElemSet& theElems,
const TIDSortedElemSet& theNodesNot, const TIDSortedElemSet& theNodesNot,
std::map< const SMDS_MeshNode*, const SMDS_MeshNode* >& theNodeNodeMap, TNodeNodeMap& theNodeNodeMap,
const bool theIsDoubleElem ); const bool theIsDoubleElem );
void copyPosition( const SMDS_MeshNode* from, void copyPosition( const SMDS_MeshNode* from,

View File

@ -1996,26 +1996,28 @@ SMDS_MeshFace* SMESH_MesherHelper::AddPolygonalFace (const vector<const SMDS_Mes
SMESHDS_Mesh * meshDS = GetMeshDS(); SMESHDS_Mesh * meshDS = GetMeshDS();
SMDS_MeshFace* elem = 0; SMDS_MeshFace* elem = 0;
if(!myCreateQuadratic) { if(!myCreateQuadratic)
{
if(id) if(id)
elem = meshDS->AddPolygonalFaceWithID(nodes, id); elem = meshDS->AddPolygonalFaceWithID(nodes, id);
else else
elem = meshDS->AddPolygonalFace(nodes); elem = meshDS->AddPolygonalFace(nodes);
} }
else { else
vector<const SMDS_MeshNode*> newNodes; {
vector<const SMDS_MeshNode*> newNodes( nodes.size() * 2 );
newNodes = nodes;
for ( int i = 0; i < nodes.size(); ++i ) for ( int i = 0; i < nodes.size(); ++i )
{ {
const SMDS_MeshNode* n1 = nodes[i]; const SMDS_MeshNode* n1 = nodes[i];
const SMDS_MeshNode* n2 = nodes[(i+1)%nodes.size()]; const SMDS_MeshNode* n2 = nodes[(i+1)%nodes.size()];
const SMDS_MeshNode* n12 = GetMediumNode( n1, n2, force3d, TopAbs_FACE ); const SMDS_MeshNode* n12 = GetMediumNode( n1, n2, force3d, TopAbs_FACE );
newNodes.push_back( n1 );
newNodes.push_back( n12 ); newNodes.push_back( n12 );
} }
if(id) if(id)
elem = meshDS->AddPolygonalFaceWithID(newNodes, id); elem = meshDS->AddQuadPolygonalFaceWithID(newNodes, id);
else else
elem = meshDS->AddPolygonalFace(newNodes); elem = meshDS->AddQuadPolygonalFace(newNodes);
} }
if ( mySetElemOnShape && myShapeID > 0 ) if ( mySetElemOnShape && myShapeID > 0 )
meshDS->SetMeshElementOnShape( elem, myShapeID ); meshDS->SetMeshElementOnShape( elem, myShapeID );

View File

@ -244,6 +244,33 @@ namespace
} }
//=======================================================================
//function : AddQaudPolygonsWithID
//=======================================================================
inline void AddQuadPolygonsWithID(SMDS_Mesh* theMesh,
SMESH::log_array_var& theSeq,
CORBA::Long theId)
{
const SMESH::long_array& anIndexes = theSeq[theId].indexes;
CORBA::Long anIndexId = 0, aNbElems = theSeq[theId].number;
for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) {
int aFaceId = anIndexes[anIndexId++];
int aNbNodes = anIndexes[anIndexId++];
std::vector<int> nodes_ids (aNbNodes);
for (int i = 0; i < aNbNodes; i++) {
nodes_ids[i] = anIndexes[anIndexId++];
}
SMDS_MeshElement* anElem = theMesh->AddQuadPolygonalFaceWithID(nodes_ids, aFaceId);
if (!anElem)
EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddQaudPolygonalFaceWithID for ID = "
<< anElemId);
}
}
//======================================================================= //=======================================================================
//function : AddTetrasWithID //function : AddTetrasWithID
//======================================================================= //=======================================================================
@ -903,6 +930,7 @@ SMESH_Client::Update(bool theIsClear)
case SMESH::ADD_QUADEDGE : AddQuadEdgesWithID ( mySMDSMesh, aSeq, anId ); break; case SMESH::ADD_QUADEDGE : AddQuadEdgesWithID ( mySMDSMesh, aSeq, anId ); break;
case SMESH::ADD_QUADTRIANGLE : AddQuadTriasWithID ( mySMDSMesh, aSeq, anId ); break; case SMESH::ADD_QUADTRIANGLE : AddQuadTriasWithID ( mySMDSMesh, aSeq, anId ); break;
case SMESH::ADD_QUADQUADRANGLE : AddQuadQuadsWithID ( mySMDSMesh, aSeq, anId ); break; case SMESH::ADD_QUADQUADRANGLE : AddQuadQuadsWithID ( mySMDSMesh, aSeq, anId ); break;
case SMESH::ADD_QUADPOLYGON : AddQuadPolygonsWithID( mySMDSMesh, aSeq, anId ); break;
case SMESH::ADD_QUADTETRAHEDRON : AddQuadTetrasWithID ( mySMDSMesh, aSeq, anId ); break; case SMESH::ADD_QUADTETRAHEDRON : AddQuadTetrasWithID ( mySMDSMesh, aSeq, anId ); break;
case SMESH::ADD_QUADPYRAMID : AddQuadPiramidsWithID( mySMDSMesh, aSeq, anId ); break; case SMESH::ADD_QUADPYRAMID : AddQuadPiramidsWithID( mySMDSMesh, aSeq, anId ); break;
case SMESH::ADD_QUADPENTAHEDRON : AddQuadPentasWithID ( mySMDSMesh, aSeq, anId ); break; case SMESH::ADD_QUADPENTAHEDRON : AddQuadPentasWithID ( mySMDSMesh, aSeq, anId ); break;

View File

@ -295,6 +295,28 @@ void SMESHDS_Command::AddPolygonalFace (const int ElementID,
myNumber++; myNumber++;
} }
//=======================================================================
//function : AddQuadPolygonalFace
//purpose :
//=======================================================================
void SMESHDS_Command::AddQuadPolygonalFace (const int ElementID,
const std::vector<int>& nodes_ids)
{
if ( myType != SMESHDS_AddQuadPolygon) {
MESSAGE("SMESHDS_Command::AddQuadraticPolygonalFace : Bad Type");
return;
}
myIntegers.push_back(ElementID);
int i, nbNodes = nodes_ids.size();
myIntegers.push_back(nbNodes);
for (i = 0; i < nbNodes; i++) {
myIntegers.push_back(nodes_ids[i]);
}
myNumber++;
}
//======================================================================= //=======================================================================
//function : AddPolyhedralVolume //function : AddPolyhedralVolume
//purpose : //purpose :

View File

@ -57,6 +57,8 @@ class SMESHDS_EXPORT SMESHDS_Command
int idnode9, int idnode10, int idnode11, int idnode12); int idnode9, int idnode10, int idnode11, int idnode12);
void AddPolygonalFace (const int ElementID, void AddPolygonalFace (const int ElementID,
const std::vector<int>& nodes_ids); const std::vector<int>& nodes_ids);
void AddQuadPolygonalFace (const int ElementID,
const std::vector<int>& nodes_ids);
void AddPolyhedralVolume (const int ElementID, void AddPolyhedralVolume (const int ElementID,
const std::vector<int>& nodes_ids, const std::vector<int>& nodes_ids,
const std::vector<int>& quantities); const std::vector<int>& quantities);

View File

@ -49,6 +49,7 @@ enum SMESHDS_CommandType {
SMESHDS_AddQuadEdge, SMESHDS_AddQuadEdge,
SMESHDS_AddQuadTriangle, SMESHDS_AddQuadTriangle,
SMESHDS_AddQuadQuadrangle, SMESHDS_AddQuadQuadrangle,
SMESHDS_AddQuadPolygon,
SMESHDS_AddQuadTetrahedron, SMESHDS_AddQuadTetrahedron,
SMESHDS_AddQuadPyramid, SMESHDS_AddQuadPyramid,
SMESHDS_AddQuadPentahedron, SMESHDS_AddQuadPentahedron,

View File

@ -213,7 +213,7 @@ void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z
//======================================================================= //=======================================================================
//function : ChangeElementNodes //function : ChangeElementNodes
//purpose : //purpose : Changed nodes of an element provided that nb of nodes does not change
//======================================================================= //=======================================================================
bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
@ -708,8 +708,8 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<int>& nod
return anElem; return anElem;
} }
SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID SMDS_MeshFace*
(const std::vector<const SMDS_MeshNode*>& nodes, SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*>& nodes,
const int ID) const int ID)
{ {
SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
@ -724,8 +724,8 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
return anElem; return anElem;
} }
SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace SMDS_MeshFace*
(const std::vector<const SMDS_MeshNode*>& nodes) SMESHDS_Mesh::AddPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes)
{ {
SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes); SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
if (anElem) { if (anElem) {
@ -739,6 +739,53 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
return anElem; return anElem;
} }
//=======================================================================
//function : AddQuadPolygonalFace
//purpose :
//=======================================================================
SMDS_MeshFace* SMESHDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<int>& nodes_ids,
const int ID)
{
SMDS_MeshFace *anElem = SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes_ids, ID);
if (anElem) {
myScript->AddQuadPolygonalFace(ID, nodes_ids);
}
return anElem;
}
SMDS_MeshFace*
SMESHDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*>& nodes,
const int ID)
{
SMDS_MeshFace *anElem = SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
if (anElem) {
int i, len = nodes.size();
std::vector<int> nodes_ids (len);
for (i = 0; i < len; i++) {
nodes_ids[i] = nodes[i]->GetID();
}
myScript->AddQuadPolygonalFace(ID, nodes_ids);
}
return anElem;
}
SMDS_MeshFace*
SMESHDS_Mesh::AddQuadPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes)
{
SMDS_MeshFace *anElem = SMDS_Mesh::AddQuadPolygonalFace(nodes);
if (anElem) {
int i, len = nodes.size();
std::vector<int> nodes_ids (len);
for (i = 0; i < len; i++) {
nodes_ids[i] = nodes[i]->GetID();
}
myScript->AddQuadPolygonalFace(anElem->GetID(), nodes_ids);
}
return anElem;
}
//======================================================================= //=======================================================================
//function : AddPolyhedralVolume //function : AddPolyhedralVolume
//purpose : //purpose :

View File

@ -511,6 +511,14 @@ public:
virtual SMDS_MeshFace* AddPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes); virtual SMDS_MeshFace* AddPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes);
virtual SMDS_MeshFace* AddQuadPolygonalFaceWithID(const std::vector<int> & nodes_ids,
const int ID);
virtual SMDS_MeshFace* AddQuadPolygonalFaceWithID(const std::vector<const SMDS_MeshNode*> & nodes,
const int ID);
virtual SMDS_MeshFace* AddQuadPolygonalFace(const std::vector<const SMDS_MeshNode*> & nodes);
virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
(const std::vector<int>& nodes_ids, (const std::vector<int>& nodes_ids,
const std::vector<int>& quantities, const std::vector<int>& quantities,

View File

@ -255,6 +255,19 @@ void SMESHDS_Script::AddPolygonalFace (int NewFaceID, const std::vector<int>& no
getCommand(SMESHDS_AddPolygon)->AddPolygonalFace(NewFaceID, nodes_ids); getCommand(SMESHDS_AddPolygon)->AddPolygonalFace(NewFaceID, nodes_ids);
} }
//=======================================================================
//function : AddQuadPolygonalFace
//purpose :
//=======================================================================
void SMESHDS_Script::AddQuadPolygonalFace(int NewFaceID, const std::vector<int>& nodes_ids)
{
if(myIsEmbeddedMode){
myIsModified = true;
return;
}
getCommand(SMESHDS_AddQuadPolygon)->AddQuadPolygonalFace(NewFaceID, nodes_ids);
}
//======================================================================= //=======================================================================
//function : AddPolyhedralVolume //function : AddPolyhedralVolume
//purpose : //purpose :

View File

@ -64,6 +64,8 @@ class SMESHDS_EXPORT SMESHDS_Script
void AddPolygonalFace (const int NewFaceID, void AddPolygonalFace (const int NewFaceID,
const std::vector<int>& nodes_ids); const std::vector<int>& nodes_ids);
void AddQuadPolygonalFace (const int NewFaceID,
const std::vector<int>& nodes_ids);
void AddPolyhedralVolume (const int NewVolID, void AddPolyhedralVolume (const int NewVolID,
const std::vector<int>& nodes_ids, const std::vector<int>& nodes_ids,
const std::vector<int>& quantities); const std::vector<int>& quantities);

View File

@ -532,7 +532,6 @@ namespace
{ {
format = "CGNS"; format = "CGNS";
notSupportedElemTypes.push_back( SMESH::Entity_Ball ); notSupportedElemTypes.push_back( SMESH::Entity_Ball );
notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Triangle );
} }
else if ( isSAUV ) else if ( isSAUV )
{ {
@ -543,6 +542,7 @@ namespace
notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa ); notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa );
notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism ); notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
notSupportedElemTypes.push_back( SMESH::Entity_Polygon ); notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra ); notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
} }
else if ( isGMF ) else if ( isGMF )
@ -2079,7 +2079,7 @@ bool SMESHGUI::automaticUpdate( SMESH::SMESH_IDSource_ptr theMesh,
long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge]; long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
long nbFaces = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle] + long nbFaces = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle] +
info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle] +
info[SMDSEntity_Polygon]; info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
long nbVolumes = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra] + long nbVolumes = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra] +
info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] + info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] +
info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid] +
@ -3274,6 +3274,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
case SMESHOp::OpBiQuadraticTriangle: case SMESHOp::OpBiQuadraticTriangle:
case SMESHOp::OpQuadraticQuadrangle: case SMESHOp::OpQuadraticQuadrangle:
case SMESHOp::OpBiQuadraticQuadrangle: case SMESHOp::OpBiQuadraticQuadrangle:
case SMESHOp::OpQuadraticPolygon:
case SMESHOp::OpQuadraticTetrahedron: case SMESHOp::OpQuadraticTetrahedron:
case SMESHOp::OpQuadraticPyramid: case SMESHOp::OpQuadraticPyramid:
case SMESHOp::OpQuadraticPentahedron: case SMESHOp::OpQuadraticPentahedron:
@ -3291,6 +3292,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
case SMESHOp::OpBiQuadraticTriangle: type = SMDSEntity_BiQuad_Triangle; break; case SMESHOp::OpBiQuadraticTriangle: type = SMDSEntity_BiQuad_Triangle; break;
case SMESHOp::OpQuadraticQuadrangle: type = SMDSEntity_Quad_Quadrangle; break; case SMESHOp::OpQuadraticQuadrangle: type = SMDSEntity_Quad_Quadrangle; break;
case SMESHOp::OpBiQuadraticQuadrangle: type = SMDSEntity_BiQuad_Quadrangle; break; case SMESHOp::OpBiQuadraticQuadrangle: type = SMDSEntity_BiQuad_Quadrangle; break;
case SMESHOp::OpQuadraticPolygon: type = SMDSEntity_Quad_Polygon; break;
case SMESHOp::OpQuadraticTetrahedron: type = SMDSEntity_Quad_Tetra; break; case SMESHOp::OpQuadraticTetrahedron: type = SMDSEntity_Quad_Tetra; break;
case SMESHOp::OpQuadraticPyramid: type = SMDSEntity_Quad_Pyramid; break; case SMESHOp::OpQuadraticPyramid: type = SMDSEntity_Quad_Pyramid; break;
case SMESHOp::OpQuadraticPentahedron: type = SMDSEntity_Quad_Penta; break; case SMESHOp::OpQuadraticPentahedron: type = SMDSEntity_Quad_Penta; break;
@ -3909,6 +3911,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createSMESHAction( SMESHOp::OpBiQuadraticTriangle, "BIQUADRATIC_TRIANGLE", "ICON_DLG_BIQUADRATIC_TRIANGLE" ); createSMESHAction( SMESHOp::OpBiQuadraticTriangle, "BIQUADRATIC_TRIANGLE", "ICON_DLG_BIQUADRATIC_TRIANGLE" );
createSMESHAction( SMESHOp::OpQuadraticQuadrangle, "QUADRATIC_QUADRANGLE", "ICON_DLG_QUADRATIC_QUADRANGLE" ); createSMESHAction( SMESHOp::OpQuadraticQuadrangle, "QUADRATIC_QUADRANGLE", "ICON_DLG_QUADRATIC_QUADRANGLE" );
createSMESHAction( SMESHOp::OpBiQuadraticQuadrangle, "BIQUADRATIC_QUADRANGLE", "ICON_DLG_BIQUADRATIC_QUADRANGLE" ); createSMESHAction( SMESHOp::OpBiQuadraticQuadrangle, "BIQUADRATIC_QUADRANGLE", "ICON_DLG_BIQUADRATIC_QUADRANGLE" );
createSMESHAction( SMESHOp::OpQuadraticPolygon, "QUADRATIC_POLYGON", "ICON_DLG_QUADRATIC_POLYGON" );
createSMESHAction( SMESHOp::OpQuadraticTetrahedron, "QUADRATIC_TETRAHEDRON", "ICON_DLG_QUADRATIC_TETRAHEDRON" ); createSMESHAction( SMESHOp::OpQuadraticTetrahedron, "QUADRATIC_TETRAHEDRON", "ICON_DLG_QUADRATIC_TETRAHEDRON" );
createSMESHAction( SMESHOp::OpQuadraticPyramid, "QUADRATIC_PYRAMID", "ICON_DLG_QUADRATIC_PYRAMID" ); createSMESHAction( SMESHOp::OpQuadraticPyramid, "QUADRATIC_PYRAMID", "ICON_DLG_QUADRATIC_PYRAMID" );
createSMESHAction( SMESHOp::OpQuadraticPentahedron, "QUADRATIC_PENTAHEDRON", "ICON_DLG_QUADRATIC_PENTAHEDRON" ); createSMESHAction( SMESHOp::OpQuadraticPentahedron, "QUADRATIC_PENTAHEDRON", "ICON_DLG_QUADRATIC_PENTAHEDRON" );
@ -4139,6 +4142,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createMenu( SMESHOp::OpBiQuadraticTriangle , addId, -1 ); createMenu( SMESHOp::OpBiQuadraticTriangle , addId, -1 );
createMenu( SMESHOp::OpQuadraticQuadrangle, addId, -1 ); createMenu( SMESHOp::OpQuadraticQuadrangle, addId, -1 );
createMenu( SMESHOp::OpBiQuadraticQuadrangle, addId, -1 ); createMenu( SMESHOp::OpBiQuadraticQuadrangle, addId, -1 );
createMenu( SMESHOp::OpQuadraticPolygon, addId, -1 );
createMenu( SMESHOp::OpQuadraticTetrahedron, addId, -1 ); createMenu( SMESHOp::OpQuadraticTetrahedron, addId, -1 );
createMenu( SMESHOp::OpQuadraticPyramid, addId, -1 ); createMenu( SMESHOp::OpQuadraticPyramid, addId, -1 );
createMenu( SMESHOp::OpQuadraticPentahedron, addId, -1 ); createMenu( SMESHOp::OpQuadraticPentahedron, addId, -1 );
@ -4276,6 +4280,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createTool( SMESHOp::OpBiQuadraticTriangle, addNonElemTb ); createTool( SMESHOp::OpBiQuadraticTriangle, addNonElemTb );
createTool( SMESHOp::OpQuadraticQuadrangle, addNonElemTb ); createTool( SMESHOp::OpQuadraticQuadrangle, addNonElemTb );
createTool( SMESHOp::OpBiQuadraticQuadrangle, addNonElemTb ); createTool( SMESHOp::OpBiQuadraticQuadrangle, addNonElemTb );
createTool( SMESHOp::OpQuadraticPolygon, addNonElemTb );
createTool( SMESHOp::OpQuadraticTetrahedron, addNonElemTb ); createTool( SMESHOp::OpQuadraticTetrahedron, addNonElemTb );
createTool( SMESHOp::OpQuadraticPyramid, addNonElemTb ); createTool( SMESHOp::OpQuadraticPyramid, addNonElemTb );
createTool( SMESHOp::OpQuadraticPentahedron, addNonElemTb ); createTool( SMESHOp::OpQuadraticPentahedron, addNonElemTb );

View File

@ -214,7 +214,8 @@ namespace SMESH
SetVisibility(true, theActor->GetFacesOriented(), false); SetVisibility(true, theActor->GetFacesOriented(), false);
} }
void SetBallPosition(SMESH_Actor* theActor,TVTKIds& theIds, double theDiameter) { void SetBallPosition(SMESH_Actor* theActor,TVTKIds& theIds, double theDiameter)
{
vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid(); vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
myBallPolyData->Reset(); myBallPolyData->Reset();
myBallPolyData->DeleteCells(); myBallPolyData->DeleteCells();
@ -582,6 +583,13 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
if ( res == 1 ) return; if ( res == 1 ) return;
} }
SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( myGroups[idx-1] );
if ( !aFilterGroup->_is_nil() ) {
int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
tr( "MESH_FILTER_GRP_CHOSEN" ).arg( aGroupName ),
tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
if ( res == 1 ) return;
}
aGroup = myGroups[idx-1]; aGroup = myGroups[idx-1];
} }
} }
@ -590,16 +598,19 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
SMESH::long_array_var anIdList = new SMESH::long_array; SMESH::long_array_var anIdList = new SMESH::long_array;
anIdList->length( 1 ); anIdList->length( 1 );
anIdList[0] = -1; anIdList[0] = -1;
const bool onlyNodesInMesh = ( myMesh->NbElements() == 0 ); //const bool onlyNodesInMesh = ( myMesh->NbElements() == 0 );
int nbElemsBefore = 0;
switch (myElementType) { switch (myElementType) {
case SMDSAbs_0DElement: case SMDSAbs_0DElement:
nbElemsBefore = myMesh->Nb0DElements();
anIdList->length( anArrayOfIndices->length() ); anIdList->length( anArrayOfIndices->length() );
for ( size_t i = 0; i < anArrayOfIndices->length(); ++i ) for ( size_t i = 0; i < anArrayOfIndices->length(); ++i )
anIdList[i] = aMeshEditor->Add0DElement(anArrayOfIndices[i]); anIdList[i] = aMeshEditor->Add0DElement(anArrayOfIndices[i]);
break; break;
case SMDSAbs_Ball: case SMDSAbs_Ball:
if ( myGeomType == SMDSEntity_Ball ) { if ( myGeomType == SMDSEntity_Ball ) {
nbElemsBefore = myMesh->NbBalls();
anIdList->length( anArrayOfIndices->length() ); anIdList->length( anArrayOfIndices->length() );
for ( size_t i = 0; i < anArrayOfIndices->length(); ++i ) for ( size_t i = 0; i < anArrayOfIndices->length(); ++i )
anIdList[i] = aMeshEditor->AddBall(anArrayOfIndices[i], anIdList[i] = aMeshEditor->AddBall(anArrayOfIndices[i],
@ -607,14 +618,17 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
} }
break; break;
case SMDSAbs_Edge: case SMDSAbs_Edge:
nbElemsBefore = myMesh->NbEdges();
anIdList[0] = aMeshEditor->AddEdge(anArrayOfIndices.inout()); break; anIdList[0] = aMeshEditor->AddEdge(anArrayOfIndices.inout()); break;
case SMDSAbs_Face: case SMDSAbs_Face:
nbElemsBefore = myMesh->NbFaces();
if ( myIsPoly ) if ( myIsPoly )
anIdList[0] = aMeshEditor->AddPolygonalFace(anArrayOfIndices.inout()); anIdList[0] = aMeshEditor->AddPolygonalFace(anArrayOfIndices.inout());
else else
anIdList[0] = aMeshEditor->AddFace(anArrayOfIndices.inout()); anIdList[0] = aMeshEditor->AddFace(anArrayOfIndices.inout());
break; break;
default: default:
nbElemsBefore = myMesh->NbVolumes();
anIdList[0] = aMeshEditor->AddVolume(anArrayOfIndices.inout()); break; anIdList[0] = aMeshEditor->AddVolume(anArrayOfIndices.inout()); break;
} }
@ -630,6 +644,7 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
} }
else { else {
SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup ); SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGroup );
if ( !aGeomGroup->_is_nil() ) { if ( !aGeomGroup->_is_nil() ) {
aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
if ( !aGroupUsed->_is_nil() && idx > 0 ) { if ( !aGroupUsed->_is_nil() && idx > 0 ) {
@ -637,6 +652,13 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
} }
} }
else if ( !aFilterGroup->_is_nil() ) {
aGroupUsed = myMesh->ConvertToStandalone( aFilterGroup );
if ( !aGroupUsed->_is_nil() && idx > 0 ) {
myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
}
}
else else
aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
} }
@ -650,8 +672,24 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
mySelectionMgr->setSelectedObjects( aList, false ); mySelectionMgr->setSelectedObjects( aList, false );
mySimulation->SetVisibility(false); mySimulation->SetVisibility(false);
if ( onlyNodesInMesh ) // if ( onlyNodesInMesh )
myActor->SetRepresentation( SMESH_Actor::eEdge ); // wireframe // myActor->SetRepresentation( SMESH_Actor::eEdge ); // wireframe
if ( nbElemsBefore == 0 )
{
// 1st element of the type has been added, update actor to show this entity
unsigned int aMode = myActor->GetEntityMode();
switch ( myElementType ) {
case SMDSAbs_Edge:
myActor->SetRepresentation(SMESH_Actor::eEdge);
myActor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
case SMDSAbs_Face:
myActor->SetRepresentation(SMESH_Actor::eSurface);
myActor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
case SMDSAbs_Volume:
myActor->SetRepresentation(SMESH_Actor::eSurface);
myActor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
}
}
SMESH::UpdateView(); SMESH::UpdateView();
buttonOk->setEnabled(false); buttonOk->setEnabled(false);

View File

@ -95,13 +95,39 @@
namespace namespace
{ {
// Define the sequences of ids
static int FirstEdgeIds[] = {0};
static int LastEdgeIds[] = {1};
static int FirstTriangleIds[] = {0,1,2};
static int LastTriangleIds[] = {1,2,0};
static int FirstQuadrangleIds[] = {0,1,2,3};
static int LastQuadrangleIds[] = {1,2,3,0};
static int FirstTetrahedronIds[] = {0,1,2,3,3,3};
static int LastTetrahedronIds[] = {1,2,0,0,1,2};
static int FirstPyramidIds[] = {0,1,2,3,4,4,4,4};
static int LastPyramidIds[] = {1,2,3,0,0,1,2,3};
static int FirstPentahedronIds[] = {0,1,2,3,4,5,0,1,2};
static int LastPentahedronIds[] = {1,2,0,4,5,3,3,4,5};
static int FirstHexahedronIds[] = {0,1,2,3,4,5,6,7,0,1,2,3};
static int LastHexahedronIds[] = {1,2,3,0,5,6,7,4,4,5,6,7};
static vector<int> FirstPolygonIds;
static vector<int> LastPolygonIds;
void ReverseConnectivity( std::vector<vtkIdType> & ids, SMDSAbs_EntityType type, void ReverseConnectivity( std::vector<vtkIdType> & ids, SMDSAbs_EntityType type,
bool toReverse, // inverse element bool toReverse, // inverse element
bool toVtkOrder ) // smds connectivity to vtk one bool toVtkOrder ) // smds connectivity to vtk one
{ {
if ( toReverse ) // first reverse smds order if ( toReverse ) // first reverse smds order
{ {
const std::vector<int>& index = SMDS_MeshCell::reverseSmdsOrder(type); const std::vector<int>& index = SMDS_MeshCell::reverseSmdsOrder(type, ids.size());
SMDS_MeshCell::applyInterlace( index, ids ); SMDS_MeshCell::applyInterlace( index, ids );
} }
if ( toVtkOrder ) // from smds to vtk connectivity if ( toVtkOrder ) // from smds to vtk connectivity
@ -113,7 +139,8 @@ namespace
} }
namespace SMESH namespace SMESH
{ {
class TElementSimulationQuad { class TElementSimulationQuad
{
SalomeApp_Application* myApplication; SalomeApp_Application* myApplication;
SUIT_ViewWindow* myViewWindow; SUIT_ViewWindow* myViewWindow;
SVTK_ViewWindow* myVTKViewWindow; SVTK_ViewWindow* myVTKViewWindow;
@ -255,29 +282,6 @@ namespace SMESH
}; };
} }
// Define the sequences of ids
static int FirstEdgeIds[] = {0};
static int LastEdgeIds[] = {1};
static int FirstTriangleIds[] = {0,1,2};
static int LastTriangleIds[] = {1,2,0};
static int FirstQuadrangleIds[] = {0,1,2,3};
static int LastQuadrangleIds[] = {1,2,3,0};
static int FirstTetrahedronIds[] = {0,1,2,3,3,3};
static int LastTetrahedronIds[] = {1,2,0,0,1,2};
static int FirstPyramidIds[] = {0,1,2,3,4,4,4,4};
static int LastPyramidIds[] = {1,2,3,0,0,1,2,3};
static int FirstPentahedronIds[] = {0,1,2,3,4,5,0,1,2};
static int LastPentahedronIds[] = {1,2,0,4,5,3,3,4,5};
static int FirstHexahedronIds[] = {0,1,2,3,4,5,6,7,0,1,2,3};
static int LastHexahedronIds[] = {1,2,3,0,5,6,7,4,4,5,6,7};
/*! /*!
\class BusyLocker \class BusyLocker
\brief Simple 'busy state' flag locker. \brief Simple 'busy state' flag locker.
@ -335,7 +339,6 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
mySMESHGUI( theModule ), mySMESHGUI( theModule ),
mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
myGeomType( theType ), myGeomType( theType ),
//myType( theType ),
myBusy( false ) myBusy( false )
{ {
setModal( false ); setModal( false );
@ -359,6 +362,9 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
case SMDSEntity_Quad_Quadrangle: case SMDSEntity_Quad_Quadrangle:
anElementName = QString("QUADRATIC_QUADRANGLE"); anElementName = QString("QUADRATIC_QUADRANGLE");
break; break;
case SMDSEntity_Quad_Polygon:
anElementName = QString("QUADRATIC_POLYGON");
break;
case SMDSEntity_BiQuad_Quadrangle: case SMDSEntity_BiQuad_Quadrangle:
anElementName = QString("BIQUADRATIC_QUADRANGLE"); anElementName = QString("BIQUADRATIC_QUADRANGLE");
break; break;
@ -561,6 +567,11 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
myNbCenterNodes = 1; myNbCenterNodes = 1;
myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
break; break;
case SMDSEntity_Quad_Polygon:
aNumRows = 5;
myNbCorners = 0; // no limit
myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_polygons
break;
case SMDSEntity_Quad_Tetra: case SMDSEntity_Quad_Tetra:
aNumRows = 6; aNumRows = 6;
myNbCorners = 4; myNbCorners = 4;
@ -689,6 +700,7 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
break; break;
case SMDSEntity_Quad_Triangle: case SMDSEntity_Quad_Triangle:
case SMDSEntity_Quad_Quadrangle: case SMDSEntity_Quad_Quadrangle:
case SMDSEntity_Quad_Polygon:
case SMDSEntity_BiQuad_Triangle: case SMDSEntity_BiQuad_Triangle:
case SMDSEntity_BiQuad_Quadrangle: case SMDSEntity_BiQuad_Quadrangle:
case SMDSEntity_Quad_Tetra: case SMDSEntity_Quad_Tetra:
@ -739,7 +751,14 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] ); SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
if ( !aGeomGroup->_is_nil() ) { if ( !aGeomGroup->_is_nil() ) {
int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ), int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ), tr( "MESH_GEOM_GRP_CHOSEN" ).arg( aGroupName ),
tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
if ( res == 1 ) return false;
}
SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( myGroups[idx-1] );
if ( !aFilterGroup->_is_nil() ) {
int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
tr( "MESH_FILTER_GRP_CHOSEN" ).arg( aGroupName ),
tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
if ( res == 1 ) return false; if ( res == 1 ) return false;
} }
@ -748,24 +767,31 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
} }
SMESH::ElementType anElementType; SMESH::ElementType anElementType;
long anElemId = -1; long anElemId = -1, nbElemsBefore = 0;
SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
switch (myGeomType) { switch (myGeomType) {
case SMDSEntity_Quad_Edge: case SMDSEntity_Quad_Edge:
anElementType = SMESH::EDGE; anElementType = SMESH::EDGE;
nbElemsBefore = myMesh->NbEdges();
anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break; anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
case SMDSEntity_Quad_Triangle: case SMDSEntity_Quad_Triangle:
case SMDSEntity_Quad_Quadrangle: case SMDSEntity_Quad_Quadrangle:
case SMDSEntity_BiQuad_Triangle: case SMDSEntity_BiQuad_Triangle:
case SMDSEntity_BiQuad_Quadrangle: case SMDSEntity_BiQuad_Quadrangle:
anElementType = SMESH::FACE; anElementType = SMESH::FACE;
nbElemsBefore = myMesh->NbFaces();
anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break; anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
case SMDSEntity_Quad_Polygon:
anElementType = SMESH::FACE;
nbElemsBefore = myMesh->NbFaces();
anElemId = aMeshEditor->AddQuadPolygonalFace(anArrayOfIdeces.inout()); break;
case SMDSEntity_Quad_Tetra: case SMDSEntity_Quad_Tetra:
case SMDSEntity_Quad_Pyramid: case SMDSEntity_Quad_Pyramid:
case SMDSEntity_Quad_Penta: case SMDSEntity_Quad_Penta:
case SMDSEntity_Quad_Hexa: case SMDSEntity_Quad_Hexa:
case SMDSEntity_TriQuad_Hexa: case SMDSEntity_TriQuad_Hexa:
anElementType = SMESH::VOLUME; anElementType = SMESH::VOLUME;
nbElemsBefore = myMesh->NbVolumes();
anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break; anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
default: break; default: break;
} }
@ -782,6 +808,7 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
} }
else { else {
SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup ); SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGroup );
if ( !aGeomGroup->_is_nil() ) { if ( !aGeomGroup->_is_nil() ) {
aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
if ( !aGroupUsed->_is_nil() && idx > 0 ) { if ( !aGroupUsed->_is_nil() && idx > 0 ) {
@ -789,6 +816,13 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
} }
} }
else if ( !aFilterGroup->_is_nil() ) {
aGroupUsed = myMesh->ConvertToStandalone( aFilterGroup );
if ( !aGroupUsed->_is_nil() && idx > 0 ) {
myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
}
}
else else
aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
} }
@ -801,6 +835,23 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
} }
} }
if ( nbElemsBefore == 0 )
{
// 1st element of the type has been added, update actor to show this entity
unsigned int aMode = myActor->GetEntityMode();
switch ( anElementType ) {
case SMESH::EDGE:
myActor->SetRepresentation(SMESH_Actor::eEdge);
myActor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
case SMESH::FACE:
myActor->SetRepresentation(SMESH_Actor::eSurface);
myActor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
case SMESH::VOLUME:
myActor->SetRepresentation(SMESH_Actor::eSurface);
myActor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
}
}
SALOME_ListIO aList; aList.Append( myActor->getIO() ); SALOME_ListIO aList; aList.Append( myActor->getIO() );
mySelector->ClearIndex(); mySelector->ClearIndex();
mySelectionMgr->setSelectedObjects( aList, false ); mySelectionMgr->setSelectedObjects( aList, false );
@ -1007,6 +1058,7 @@ void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
anElementType = SMESH::EDGE; break; anElementType = SMESH::EDGE; break;
case SMDSEntity_Quad_Triangle: case SMDSEntity_Quad_Triangle:
case SMDSEntity_Quad_Quadrangle: case SMDSEntity_Quad_Quadrangle:
case SMDSEntity_Quad_Polygon:
case SMDSEntity_BiQuad_Triangle: case SMDSEntity_BiQuad_Triangle:
case SMDSEntity_BiQuad_Quadrangle: case SMDSEntity_BiQuad_Quadrangle:
anElementType = SMESH::FACE; break; anElementType = SMESH::FACE; break;
@ -1269,6 +1321,44 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
{ {
QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts); QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
if ( myGeomType == SMDSEntity_Quad_Polygon ) // POLYGON
{
if ( aListCorners.count() < 3 )
theConersValidity = false;
if ( aListCorners.count() != myTable->rowCount() && theConersValidity )
{
// adjust nb of rows for the polygon
int oldNbRows = myTable->rowCount();
myTable->setRowCount( aListCorners.count() );
for ( int row = oldNbRows; row < myTable->rowCount(); row++ )
{
myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
myTable->item( row, 0 )->setFlags(0);
IdEditItem* anEditItem = new IdEditItem( "" );
anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
myTable->setItem(row, 1, anEditItem);
myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
myTable->item( row, 2 )->setFlags(0);
}
myNbCorners = aListCorners.count();
// fill FirstPolygonIds and LastPolygonIds
FirstPolygonIds.resize( aListCorners.count() );
LastPolygonIds .resize( aListCorners.count() );
for ( int i = 0; i < aListCorners.count(); ++i )
{
FirstPolygonIds[i] = i;
LastPolygonIds [i] = i+1;
}
LastPolygonIds.back() = 0;
myNbCorners = aListCorners.count();
}
}
if ( aListCorners.count() == myNbCorners && theConersValidity ) if ( aListCorners.count() == myNbCorners && theConersValidity )
{ {
myTable->setEnabled( true ); myTable->setEnabled( true );
@ -1295,6 +1385,10 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
aFirstColIds = FirstQuadrangleIds; aFirstColIds = FirstQuadrangleIds;
aLastColIds = LastQuadrangleIds; aLastColIds = LastQuadrangleIds;
break; break;
case SMDSEntity_Quad_Polygon:
aFirstColIds = & FirstPolygonIds[0];
aLastColIds = & LastPolygonIds[0];
break;
case SMDSEntity_Quad_Tetra: case SMDSEntity_Quad_Tetra:
aFirstColIds = FirstTetrahedronIds; aFirstColIds = FirstTetrahedronIds;
aLastColIds = LastTetrahedronIds; aLastColIds = LastTetrahedronIds;

View File

@ -1740,7 +1740,7 @@ static QList<int> entityTypes( const int theType )
typeIds.append( SMDSEntity_Quad_Quadrangle ); typeIds.append( SMDSEntity_Quad_Quadrangle );
typeIds.append( SMDSEntity_BiQuad_Quadrangle ); typeIds.append( SMDSEntity_BiQuad_Quadrangle );
typeIds.append( SMDSEntity_Polygon ); typeIds.append( SMDSEntity_Polygon );
//typeIds.append( SMDSEntity_Quad_Polygon ); typeIds.append( SMDSEntity_Quad_Polygon );
break; break;
case SMESH::VOLUME: case SMESH::VOLUME:
typeIds.append( SMDSEntity_Tetra ); typeIds.append( SMDSEntity_Tetra );

View File

@ -306,11 +306,13 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
QLabel* a2DQuaBiQuad = createField(); QLabel* a2DQuaBiQuad = createField();
QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this ); QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this );
QLabel* a2DPolTotal = createField(); QLabel* a2DPolTotal = createField();
QLabel* a2DPolLin = createField();
QLabel* a2DPolQuad = createField();
myWidgets[ index++ ] << a2DLine; myWidgets[ index++ ] << a2DLine;
myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad; myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad;
myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad; myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad; myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
myWidgets[ index++ ] << a2DPolLab << a2DPolTotal; myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad;
// ... 3D elements // ... 3D elements
QWidget* a3DLine = createLine(); QWidget* a3DLine = createLine();
@ -414,6 +416,8 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
l->addWidget( a2DQuaBiQuad, 17, 4 ); l->addWidget( a2DQuaBiQuad, 17, 4 );
l->addWidget( a2DPolLab, 18, 0 ); l->addWidget( a2DPolLab, 18, 0 );
l->addWidget( a2DPolTotal, 18, 1 ); l->addWidget( a2DPolTotal, 18, 1 );
l->addWidget( a2DPolLin, 18, 2 );
l->addWidget( a2DPolQuad, 18, 3 );
l->addWidget( a3DLine, 19, 1, 1, 4 ); l->addWidget( a3DLine, 19, 1, 1, 4 );
l->addWidget( a3DLab, 20, 0 ); l->addWidget( a3DLab, 20, 0 );
l->addWidget( a3DTotal, 20, 1 ); l->addWidget( a3DTotal, 20, 1 );
@ -503,8 +507,9 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) ); myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) );
long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle]; long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_BiQuad_Triangle];
long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle]; long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
long nb2DPolygons = info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon]; long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle]; long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon];
long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle]; long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic; long nb2DTotal = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
@ -520,7 +525,9 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) ); myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) );
myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) ); myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) );
myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ) ); myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ) );
myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) ); myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( nb2DPolygons ));
myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Polygon] ) );
long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra]; long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra];
long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa]; long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid]; long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
@ -583,6 +590,8 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" ); myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" );
myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" ); myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" ); myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
myWidgets[i2DPolygons][iLinear] ->setProperty( "text", "?" );
myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", "?" );
myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" ); myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
myWidgets[iNb][iTotal] ->setProperty( "text", "?" ); myWidgets[iNb][iTotal] ->setProperty( "text", "?" );
myWidgets[iNb][iLinear] ->setProperty( "text", "?" ); myWidgets[iNb][iLinear] ->setProperty( "text", "?" );
@ -712,6 +721,8 @@ void SMESHGUI_MeshInfo::clear()
myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ) ); myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ) );
myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) ); myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) ); myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
myWidgets[i2DPolygons][iLinear] ->setProperty( "text", QString::number( 0 ) );
myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ) ); myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ) );
myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ) ); myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ) );
myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ) ); myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ) );
@ -836,6 +847,8 @@ void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" ) ).toString() << "\n"; out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n"; out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" ) << "\n";
out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" ) ).toString() << "\n"; out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" ) ).toString() << "\n";
out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" ) ).toString() << "\n";
out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" ) ).toString() << "\n";
out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n"; out << QString( SPACING_INFO, ' ' ) << tr( "3D_LAB" ) << "\n";
out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" ) ).toString() << "\n"; out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" ) << ": " << ( myWidgets[i3D][iTotal]->property( "text" ) ).toString() << "\n";
out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" ) ).toString() << "\n"; out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" ) << ": " << ( myWidgets[i3D][iLinear]->property( "text" ) ).toString() << "\n";

View File

@ -145,6 +145,7 @@ namespace SMESHOp {
OpQuadraticPentahedron = 4107, // MENU MODIFICATION - ADD - QUADRATIC PENTAHEDRON OpQuadraticPentahedron = 4107, // MENU MODIFICATION - ADD - QUADRATIC PENTAHEDRON
OpQuadraticHexahedron = 4108, // MENU MODIFICATION - ADD - QUADRATIC HEXAHEDRON OpQuadraticHexahedron = 4108, // MENU MODIFICATION - ADD - QUADRATIC HEXAHEDRON
OpTriQuadraticHexahedron = 4109, // MENU MODIFICATION - ADD - TRIQUADRATIC HEXAHEDRON OpTriQuadraticHexahedron = 4109, // MENU MODIFICATION - ADD - TRIQUADRATIC HEXAHEDRON
OpQuadraticPolygon = 4110, // MENU MODIFICATION - ADD - QUADRATIC POLYGON
OpRemoveNodes = 4200, // MENU MODIFICATION - REMOVE - NODE OpRemoveNodes = 4200, // MENU MODIFICATION - REMOVE - NODE
OpRemoveElements = 4201, // MENU MODIFICATION - REMOVE - ELEMENTS OpRemoveElements = 4201, // MENU MODIFICATION - REMOVE - ELEMENTS
OpRemoveOrphanNodes = 4202, // MENU MODIFICATION - REMOVE - ORPHAN NODES OpRemoveOrphanNodes = 4202, // MENU MODIFICATION - REMOVE - ORPHAN NODES

View File

@ -219,6 +219,10 @@
<source>ICON_DLG_BIQUADRATIC_QUADRANGLE</source> <source>ICON_DLG_BIQUADRATIC_QUADRANGLE</source>
<translation>mesh_biquad_quadrangle.png</translation> <translation>mesh_biquad_quadrangle.png</translation>
</message> </message>
<message>
<source>ICON_DLG_QUADRATIC_POLYGON</source>
<translation>mesh_quad_polygon.png</translation>
</message>
<message> <message>
<source>ICON_DLG_QUADRATIC_TETRAHEDRON</source> <source>ICON_DLG_QUADRATIC_TETRAHEDRON</source>
<translation>mesh_quad_tetrahedron.png</translation> <translation>mesh_quad_tetrahedron.png</translation>

View File

@ -792,6 +792,10 @@
<source>MEN_POLYGON</source> <source>MEN_POLYGON</source>
<translation>Polygon</translation> <translation>Polygon</translation>
</message> </message>
<message>
<source>MEN_QUADRATIC_POLYGON</source>
<translation>Quadratic Polygon</translation>
</message>
<message> <message>
<source>MEN_POLYHEDRON</source> <source>MEN_POLYHEDRON</source>
<translation>Polyhedron</translation> <translation>Polyhedron</translation>
@ -1127,8 +1131,13 @@ Please, select a mesh and try again</translation>
Please enter a name of new group to be created or choose an existing one.</translation> Please enter a name of new group to be created or choose an existing one.</translation>
</message> </message>
<message> <message>
<source>MESH_STANDALONE_GRP_CHOSEN</source> <source>MESH_GEOM_GRP_CHOSEN</source>
<translation>Group on geometry is chosen: %1. <translation>Group on geometry is chosen: %1.
Do you want to convert it to the standalone group?</translation>
</message>
<message>
<source>MESH_FILTER_GRP_CHOSEN</source>
<translation>Group on filter is chosen: %1.
Do you want to convert it to the standalone group?</translation> Do you want to convert it to the standalone group?</translation>
</message> </message>
<message> <message>
@ -1225,6 +1234,14 @@ Please enter correct values and try again</translation>
<source>SMESH_ADD_POLYGON_TITLE</source> <source>SMESH_ADD_POLYGON_TITLE</source>
<translation>Add Polygon</translation> <translation>Add Polygon</translation>
</message> </message>
<message>
<source>SMESH_ADD_QUADRATIC_POLYGON</source>
<translation>Add Quadratic polygon</translation>
</message>
<message>
<source>SMESH_ADD_QUADRATIC_POLYGON_TITLE</source>
<translation>Add Quadratic Polygon</translation>
</message>
<message> <message>
<source>SMESH_ADD_PENTA</source> <source>SMESH_ADD_PENTA</source>
<translation>Add pentahedron</translation> <translation>Add pentahedron</translation>
@ -3224,6 +3241,10 @@ Use Display Entity menu command to show them.
<source>STB_POLYGON</source> <source>STB_POLYGON</source>
<translation>Polygon</translation> <translation>Polygon</translation>
</message> </message>
<message>
<source>STB_QUADRATIC_POLYGON</source>
<translation>Quadratic Polygon</translation>
</message>
<message> <message>
<source>STB_POLYHEDRON</source> <source>STB_POLYHEDRON</source>
<translation>Polyhedron</translation> <translation>Polyhedron</translation>
@ -3880,6 +3901,10 @@ Use Display Entity menu command to show them.
<source>TOP_POLYGON</source> <source>TOP_POLYGON</source>
<translation>Polygon</translation> <translation>Polygon</translation>
</message> </message>
<message>
<source>TOP_QUADRATIC_POLYGON</source>
<translation>Quadratic Polygon</translation>
</message>
<message> <message>
<source>TOP_POLYHEDRON</source> <source>TOP_POLYHEDRON</source>
<translation>Polyhedron</translation> <translation>Polyhedron</translation>

View File

@ -859,7 +859,7 @@ namespace
} }
// associate branchIDs and the input branch vector (arg) // associate branchIDs and the input branch vector (arg)
vector< const SMESH_MAT2d::Branch* > branchByID( branchEdges.size() ); vector< const SMESH_MAT2d::Branch* > branchByID( branchEdges.size(), 0 );
int nbBranches = 0; int nbBranches = 0;
for ( size_t i = 0; i < branchEdges.size(); ++i ) for ( size_t i = 0; i < branchEdges.size(); ++i )
{ {
@ -912,28 +912,24 @@ namespace
{ {
edgeInd += dInd; edgeInd += dInd;
if ( edgeInd < 0 || if (( edgeInd < 0 ||
edgeInd >= (int) branchEdges[ brID ].size() || edgeInd >= (int) branchEdges[ brID ].size() ) ||
branchEdges[ brID ][ edgeInd ] != bndSegs[ i ]._edge ) ( branchEdges[ brID ][ edgeInd ] != bndSegs[ i ]._edge &&
branchEdges[ brID ][ edgeInd ]->twin() != bndSegs[ i ]._edge ))
{ {
if ( bndSegs[ i ]._branchID < 0 && if ( bndSegs[ i ]._branchID < 0 )
branchEdges[ brID ].back() == bndSegs[ i ]._edge )
{ {
edgeInd = branchEdges[ brID ].size() - 1;
dInd = -1; dInd = -1;
for ( edgeInd = branchEdges[ brID ].size() - 1; edgeInd > 0; --edgeInd )
if ( branchEdges[ brID ][ edgeInd ]->twin() == bndSegs[ i ]._edge )
break;
} }
else if ( bndSegs[ i ]._branchID > 0 && else // bndSegs[ i ]._branchID > 0
branchEdges[ brID ].front() == bndSegs[ i ]._edge )
{ {
edgeInd = 0;
dInd = +1; dInd = +1;
}
else
{
for ( edgeInd = 0; edgeInd < branchEdges[ brID ].size(); ++edgeInd ) for ( edgeInd = 0; edgeInd < branchEdges[ brID ].size(); ++edgeInd )
if ( branchEdges[ brID ][ edgeInd ] == bndSegs[ i ]._edge ) if ( branchEdges[ brID ][ edgeInd ] == bndSegs[ i ]._edge )
break; break;
dInd = bndSegs[ i ]._branchID > 0 ? +1 : -1;
} }
} }
} }
@ -942,7 +938,7 @@ namespace
// no MA edge, bndSeg corresponds to an end point of a branch // no MA edge, bndSeg corresponds to an end point of a branch
if ( bndPoints._maEdges.empty() ) if ( bndPoints._maEdges.empty() )
{ {
// should not get here according to algo design // should not get here according to algo design???
edgeInd = 0; edgeInd = 0;
} }
else else
@ -1037,7 +1033,7 @@ void SMESH_MAT2d::MedialAxis::getPoints( const Branch& branch,
//================================================================================ //================================================================================
/*! /*!
* \brief Returns a BranchPoint corresponding to a given point on a geom EDGE * \brief Returns a BranchPoint corresponding to a given point on a geom EDGE
* \param [in] iGeomEdge - index of geom EDGE within a vector passed at construction * \param [in] iGeomEdge - index of geom EDGE within a vector passed at MA construction
* \param [in] u - parameter of the point on EDGE curve * \param [in] u - parameter of the point on EDGE curve
* \param [out] p - the found BranchPoint * \param [out] p - the found BranchPoint
* \return bool - is OK * \return bool - is OK
@ -1071,13 +1067,29 @@ bool SMESH_MAT2d::Boundary::getBranchPoint( const std::size_t iEdge,
while ( points._params[i ] > u ) --i; while ( points._params[i ] > u ) --i;
while ( points._params[i+1] < u ) ++i; while ( points._params[i+1] < u ) ++i;
} }
double edgeParam = ( u - points._params[i] ) / ( points._params[i+1] - points._params[i] ); double edgeParam = ( u - points._params[i] ) / ( points._params[i+1] - points._params[i] );
if ( !points._maEdges[ i ].second ) // no branch at the EDGE end
{
if ( i < points._maEdges.size() / 2 ) // near 1st point
{
while ( i < points._maEdges.size()-1 && !points._maEdges[ i ].second )
++i;
edgeParam = edgeReverse;
}
else // near last point
{
while ( i > 0 && !points._maEdges[ i ].second )
--i;
edgeParam = !edgeReverse;
}
}
const std::pair< const Branch*, int >& maE = points._maEdges[ i ]; const std::pair< const Branch*, int >& maE = points._maEdges[ i ];
bool maReverse = ( maE.second < 0 ); bool maReverse = ( maE.second < 0 );
p._branch = maE.first; p._branch = maE.first;
p._iEdge = maE.second - 1; // countered from 1 to store sign p._iEdge = ( maReverse ? -maE.second : maE.second ) - 1; // countered from 1 to store sign
p._edgeParam = maReverse ? ( 1. - edgeParam ) : edgeParam; p._edgeParam = maReverse ? ( 1. - edgeParam ) : edgeParam;
return true; return true;
@ -1244,6 +1256,8 @@ bool SMESH_MAT2d::Branch::getBoundaryPoints(std::size_t iMAEdge,
{ {
if ( iMAEdge > _maEdges.size() ) if ( iMAEdge > _maEdges.size() )
return false; return false;
if ( iMAEdge == _maEdges.size() )
iMAEdge = _maEdges.size() - 1;
size_t iGeom1 = getGeomEdge( _maEdges[ iMAEdge ] ); size_t iGeom1 = getGeomEdge( _maEdges[ iMAEdge ] );
size_t iGeom2 = getGeomEdge( _maEdges[ iMAEdge ]->twin() ); size_t iGeom2 = getGeomEdge( _maEdges[ iMAEdge ]->twin() );
@ -1277,6 +1291,8 @@ bool SMESH_MAT2d::Branch::getParameter(const BranchPoint & p, double & u ) const
{ {
if ( p._iEdge > _params.size()-1 ) if ( p._iEdge > _params.size()-1 )
return false; return false;
if ( p._iEdge == _params.size()-1 )
return u = 1.;
u = ( _params[ p._iEdge ] * ( 1 - p._edgeParam ) + u = ( _params[ p._iEdge ] * ( 1 - p._edgeParam ) +
_params[ p._iEdge+1 ] * p._edgeParam ); _params[ p._iEdge+1 ] * p._edgeParam );

View File

@ -2422,6 +2422,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
::SMESH_MeshEditor aNewEditor(&aLocMesh); ::SMESH_MeshEditor aNewEditor(&aLocMesh);
SMESH::ListOfGroups_var aListOfGroups; SMESH::ListOfGroups_var aListOfGroups;
::SMESH_MeshEditor::ElemFeatures elemType;
std::vector<const SMDS_MeshNode*> aNodesArray; std::vector<const SMDS_MeshNode*> aNodesArray;
// loop on sub-meshes // loop on sub-meshes
@ -2476,31 +2477,12 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
} }
// creates a corresponding element on existent nodes in new mesh // creates a corresponding element on existent nodes in new mesh
if ( anElem->GetType() == SMDSAbs_Node )
aNewElem = 0; aNewElem = 0;
switch ( anElem->GetEntityType() ) else
{ aNewElem =
case SMDSEntity_Polyhedra: aNewEditor.AddElement( aNodesArray, elemType.Init( anElem, /*basicOnly=*/false ));
if ( const SMDS_VtkVolume* aVolume =
dynamic_cast<const SMDS_VtkVolume*> (anElem))
{
aNewElem = aNewMeshDS->AddPolyhedralVolume( aNodesArray,
aVolume->GetQuantities() );
}
break;
case SMDSEntity_Ball:
if ( const SMDS_BallElement* aBall =
dynamic_cast<const SMDS_BallElement*> (anElem))
{
aNewElem = aNewEditor.AddElement( aNodesArray, SMDSAbs_Ball,
/*isPoly=*/false, /*id=*/0,
aBall->GetDiameter() );
}
break;
case SMDSEntity_Node:
break;
default:
aNewElem = aNewEditor.AddElement( aNodesArray, anElem->GetType(), anElem->IsPoly() );
}
if ( aNewElem ) if ( aNewElem )
elemsMap.insert( make_pair( anElem, aNewElem )); elemsMap.insert( make_pair( anElem, aNewElem ));
@ -2737,6 +2719,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
} }
SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS(); SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS();
::SMESH_MeshEditor editor( &newMesh_i->GetImpl() ); ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() );
::SMESH_MeshEditor::ElemFeatures elemType;
// 3. Get elements to copy // 3. Get elements to copy
@ -2808,31 +2791,13 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
// add elements // add elements
if ( elem->GetType() != SMDSAbs_Node ) if ( elem->GetType() != SMDSAbs_Node )
{ {
int ID = toKeepIDs ? elem->GetID() : 0; elemType.Init( elem, /*basicOnly=*/false );
const SMDS_MeshElement * newElem; if ( toKeepIDs ) elemType.SetID( elem->GetID() );
switch ( elem->GetEntityType() ) {
case SMDSEntity_Polyhedra:
if ( toKeepIDs )
newElem = editor.GetMeshDS()->
AddPolyhedralVolumeWithID( nodes,
static_cast<const SMDS_VtkVolume*>(elem)->GetQuantities(),
ID);
else
newElem = editor.GetMeshDS()->
AddPolyhedralVolume( nodes,
static_cast<const SMDS_VtkVolume*>(elem)->GetQuantities());
break;
case SMDSEntity_Ball:
newElem = editor.AddElement( nodes, SMDSAbs_Ball, false, ID,
static_cast<const SMDS_BallElement*>(elem)->GetDiameter());
break;
default:
newElem = editor.AddElement( nodes,elem->GetType(),elem->IsPoly(),ID);
const SMDS_MeshElement * newElem = editor.AddElement( nodes, elemType );
if ( toCopyGroups && !toKeepIDs ) if ( toCopyGroups && !toKeepIDs )
e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem )); e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem ));
} }
}
} // while ( srcElemIt->more() ) } // while ( srcElemIt->more() )
// 4(b). Copy free nodes // 4(b). Copy free nodes

View File

@ -154,20 +154,11 @@ namespace MeshEditor_I {
} }
// creates a corresponding element on copied nodes // creates a corresponding element on copied nodes
SMDS_MeshElement* anElemCopy = 0; ::SMESH_MeshEditor::ElemFeatures elemType;
if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume ) elemType.Init( anElem, /*basicOnly=*/false );
{ elemType.SetID( anElem->GetID() );
const SMDS_VtkVolume* ph = SMDS_MeshElement* anElemCopy =
dynamic_cast<const SMDS_VtkVolume*> (anElem); ::SMESH_MeshEditor(this).AddElement( anElemNodesID, elemType );
if ( ph )
anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
(anElemNodesID, ph->GetQuantities(),anElem->GetID());
}
else {
anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
anElem->GetType(),
anElem->IsPoly() );
}
return anElemCopy; return anElemCopy;
} }
//!< Copy a node //!< Copy a node
@ -577,7 +568,10 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
while ( itMeshElems->more() ) { while ( itMeshElems->more() ) {
const SMDS_MeshElement* aMeshElem = itMeshElems->next(); const SMDS_MeshElement* aMeshElem = itMeshElems->next();
SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator(); SMDS_NodeIteratorPtr itElemNodes =
(( aMeshElem->GetEntityType() == SMDSEntity_Quad_Polygon ) ?
aMeshElem->interlacedNodesIterator() :
aMeshElem->nodeIterator() );
while ( itElemNodes->more() ) { while ( itElemNodes->more() ) {
const SMDS_MeshNode* aMeshNode = itElemNodes->next(); const SMDS_MeshNode* aMeshNode = itElemNodes->next();
int aNodeID = aMeshNode->GetID(); int aNodeID = aMeshNode->GetID();
@ -1059,6 +1053,7 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
* AddPolygonalFace * AddPolygonalFace
*/ */
//============================================================================= //=============================================================================
CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes) CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
throw (SALOME::SALOME_Exception) throw (SALOME::SALOME_Exception)
{ {
@ -1082,6 +1077,35 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO
return 0; return 0;
} }
//=============================================================================
/*!
* AddQuadPolygonalFace
*/
//=============================================================================
CORBA::Long SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::long_array & IDsOfNodes)
throw (SALOME::SALOME_Exception)
{
SMESH_TRY;
initData();
int NbNodes = IDsOfNodes.length();
std::vector<const SMDS_MeshNode*> nodes (NbNodes);
for (int i = 0; i < NbNodes; i++)
nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes);
// Update Python script
TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
declareMeshModified( /*isReComputeSafe=*/false );
return elem ? elem->GetID() : 0;
SMESH_CATCH( SMESH::throwCorbaException );
return 0;
}
//============================================================================= //=============================================================================
/*! /*!
* Create volume, either linear and quadratic (this is determed * Create volume, either linear and quadratic (this is determed

View File

@ -117,6 +117,8 @@ public:
throw (SALOME::SALOME_Exception); throw (SALOME::SALOME_Exception);
CORBA::Long AddPolygonalFace(const SMESH::long_array & IDsOfNodes) CORBA::Long AddPolygonalFace(const SMESH::long_array & IDsOfNodes)
throw (SALOME::SALOME_Exception); throw (SALOME::SALOME_Exception);
CORBA::Long AddQuadPolygonalFace(const SMESH::long_array & IDsOfNodes)
throw (SALOME::SALOME_Exception);
CORBA::Long AddVolume(const SMESH::long_array & IDsOfNodes) CORBA::Long AddVolume(const SMESH::long_array & IDsOfNodes)
throw (SALOME::SALOME_Exception); throw (SALOME::SALOME_Exception);
CORBA::Long AddPolyhedralVolume(const SMESH::long_array & IDsOfNodes, CORBA::Long AddPolyhedralVolume(const SMESH::long_array & IDsOfNodes,

View File

@ -3765,13 +3765,13 @@ CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
return _impl->NbBiQuadQuadrangles(); return _impl->NbBiQuadQuadrangles();
} }
CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception) CORBA::Long SMESH_Mesh_i::NbPolygons(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
{ {
Unexpect aCatch(SALOME_SalomeException); Unexpect aCatch(SALOME_SalomeException);
if ( _preMeshInfo ) if ( _preMeshInfo )
return _preMeshInfo->NbPolygons(); return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
return _impl->NbPolygons(); return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
} }
CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order) CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
@ -4851,6 +4851,7 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM ); THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups; SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
::SMESH_MeshEditor::ElemFeatures elemType;
// submesh by subshape id // submesh by subshape id
if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1; if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
@ -4883,7 +4884,7 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
if ( elem ) if ( elem )
{ {
::SMESH_MeshEditor editor( _impl ); ::SMESH_MeshEditor editor( _impl );
elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() ); elem = editor.AddElement( nodes, elemType.Init( elem ));
} }
} }
if ( elem ) if ( elem )

View File

@ -315,7 +315,7 @@ public:
CORBA::Long NbBiQuadQuadrangles() CORBA::Long NbBiQuadQuadrangles()
throw (SALOME::SALOME_Exception); throw (SALOME::SALOME_Exception);
CORBA::Long NbPolygons() CORBA::Long NbPolygons(SMESH::ElementOrder order=SMESH::ORDER_ANY)
throw (SALOME::SALOME_Exception); throw (SALOME::SALOME_Exception);
CORBA::Long NbVolumes() CORBA::Long NbVolumes()

View File

@ -2242,11 +2242,11 @@ class Mesh:
def NbBiQuadQuadrangles(self): def NbBiQuadQuadrangles(self):
return self.mesh.NbBiQuadQuadrangles() return self.mesh.NbBiQuadQuadrangles()
## Returns the number of polygons in the mesh ## Returns the number of polygons of given order in the mesh
# @return an integer value # @return an integer value
# @ingroup l1_meshinfo # @ingroup l1_meshinfo
def NbPolygons(self): def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
return self.mesh.NbPolygons() return self.mesh.NbPolygons(elementOrder)
## Returns the number of volumes in the mesh ## Returns the number of volumes in the mesh
# @return an integer value # @return an integer value
@ -2367,7 +2367,7 @@ class Mesh:
## Returns the type of mesh element ## Returns the type of mesh element
# @return the value from SMESH::ElementType enumeration # @return the value from SMESH::ElementType enumeration
# @ingroup l1_meshinfo # @ingroup l1_meshinfo
def GetElementType(self, id, iselem): def GetElementType(self, id, iselem=True):
return self.mesh.GetElementType(id, iselem) return self.mesh.GetElementType(id, iselem)
## Returns the geometric type of mesh element ## Returns the geometric type of mesh element
@ -2455,24 +2455,22 @@ class Mesh:
def GetElementPosition(self,ElemID): def GetElementPosition(self,ElemID):
return self.mesh.GetElementPosition(ElemID) return self.mesh.GetElementPosition(ElemID)
## If the given element is a node, returns the ID of shape ## Returns the ID of the shape, on which the given node was generated.
# \n If there is no node for the given ID - returns -1 # @return an integer value > 0 or -1 if there is no node for the given
# @return an integer value # ID or the node is not assigned to any geometry
# @ingroup l1_meshinfo # @ingroup l1_meshinfo
def GetShapeID(self, id): def GetShapeID(self, id):
return self.mesh.GetShapeID(id) return self.mesh.GetShapeID(id)
## Returns the ID of the result shape after ## Returns the ID of the shape, on which the given element was generated.
# FindShape() from SMESH_MeshEditor for the given element # @return an integer value > 0 or -1 if there is no element for the given
# \n If there is no element for the given ID - returns -1 # ID or the element is not assigned to any geometry
# @return an integer value
# @ingroup l1_meshinfo # @ingroup l1_meshinfo
def GetShapeIDForElem(self,id): def GetShapeIDForElem(self,id):
return self.mesh.GetShapeIDForElem(id) return self.mesh.GetShapeIDForElem(id)
## Returns the number of nodes for the given element ## Returns the number of nodes of the given element
# \n If there is no element for the given ID - returns -1 # @return an integer value > 0 or -1 if there is no element for the given ID
# @return an integer value
# @ingroup l1_meshinfo # @ingroup l1_meshinfo
def GetElemNbNodes(self, id): def GetElemNbNodes(self, id):
return self.mesh.GetElemNbNodes(id) return self.mesh.GetElemNbNodes(id)
@ -2498,7 +2496,7 @@ class Mesh:
## Returns true if the given node is the medium node in one of quadratic elements ## Returns true if the given node is the medium node in one of quadratic elements
# @ingroup l1_meshinfo # @ingroup l1_meshinfo
def IsMediumNodeOfAnyElem(self, nodeID, elementType): def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType) return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
## Returns the number of edges for the given element ## Returns the number of edges for the given element
@ -2756,6 +2754,14 @@ class Mesh:
def AddPolygonalFace(self, IdsOfNodes): def AddPolygonalFace(self, IdsOfNodes):
return self.editor.AddPolygonalFace(IdsOfNodes) return self.editor.AddPolygonalFace(IdsOfNodes)
## Adds a quadratic polygonal face to the mesh by the list of node IDs
# @param IdsOfNodes the list of node IDs for creation of the element;
# corner nodes follow first.
# @return the Id of the new face
# @ingroup l2_modif_add
def AddQuadPolygonalFace(self, IdsOfNodes):
return self.editor.AddQuadPolygonalFace(IdsOfNodes)
## Creates both simple and quadratic volume (this is determined ## Creates both simple and quadratic volume (this is determined
# by the number of given nodes). # by the number of given nodes).
# @param IDsOfNodes the list of node IDs for creation of the element. # @param IDsOfNodes the list of node IDs for creation of the element.
@ -3990,7 +3996,7 @@ class Mesh:
## Creates a symmetrical copy of mesh elements ## Creates a symmetrical copy of mesh elements
# @param IDsOfElements list of elements ids # @param IDsOfElements list of elements ids
# @param Mirror is AxisStruct or geom object(point, line, plane) # @param Mirror is AxisStruct or geom object(point, line, plane)
# @param theMirrorType is POINT, AXIS or PLANE # @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
# If the Mirror is a geom object this parameter is unnecessary # If the Mirror is a geom object this parameter is unnecessary
# @param Copy allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0) # @param Copy allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
# @param MakeGroups forces the generation of new groups from existing ones (if Copy) # @param MakeGroups forces the generation of new groups from existing ones (if Copy)
@ -4012,7 +4018,7 @@ class Mesh:
## Creates a new mesh by a symmetrical copy of mesh elements ## Creates a new mesh by a symmetrical copy of mesh elements
# @param IDsOfElements the list of elements ids # @param IDsOfElements the list of elements ids
# @param Mirror is AxisStruct or geom object (point, line, plane) # @param Mirror is AxisStruct or geom object (point, line, plane)
# @param theMirrorType is POINT, AXIS or PLANE # @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
# If the Mirror is a geom object this parameter is unnecessary # If the Mirror is a geom object this parameter is unnecessary
# @param MakeGroups to generate new groups from existing ones # @param MakeGroups to generate new groups from existing ones
# @param NewMeshName a name of the new mesh to create # @param NewMeshName a name of the new mesh to create
@ -4033,7 +4039,7 @@ class Mesh:
## Creates a symmetrical copy of the object ## Creates a symmetrical copy of the object
# @param theObject mesh, submesh or group # @param theObject mesh, submesh or group
# @param Mirror AxisStruct or geom object (point, line, plane) # @param Mirror AxisStruct or geom object (point, line, plane)
# @param theMirrorType is POINT, AXIS or PLANE # @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
# If the Mirror is a geom object this parameter is unnecessary # If the Mirror is a geom object this parameter is unnecessary
# @param Copy allows copying the element (Copy is 1) or replacing it with its mirror (Copy is 0) # @param Copy allows copying the element (Copy is 1) or replacing it with its mirror (Copy is 0)
# @param MakeGroups forces the generation of new groups from existing ones (if Copy) # @param MakeGroups forces the generation of new groups from existing ones (if Copy)
@ -4055,7 +4061,7 @@ class Mesh:
## Creates a new mesh by a symmetrical copy of the object ## Creates a new mesh by a symmetrical copy of the object
# @param theObject mesh, submesh or group # @param theObject mesh, submesh or group
# @param Mirror AxisStruct or geom object (point, line, plane) # @param Mirror AxisStruct or geom object (point, line, plane)
# @param theMirrorType POINT, AXIS or PLANE # @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
# If the Mirror is a geom object this parameter is unnecessary # If the Mirror is a geom object this parameter is unnecessary
# @param MakeGroups forces the generation of new groups from existing ones # @param MakeGroups forces the generation of new groups from existing ones
# @param NewMeshName the name of the new mesh to create # @param NewMeshName the name of the new mesh to create
@ -4420,7 +4426,8 @@ class Mesh:
## Creates Duplicates given elements, i.e. creates new elements based on the ## Creates Duplicates given elements, i.e. creates new elements based on the
# same nodes as the given ones. # same nodes as the given ones.
# @param theElements - container of elements to duplicate. It can be a Mesh, # @param theElements - container of elements to duplicate. It can be a Mesh,
# sub-mesh, group, filter or a list of element IDs. # sub-mesh, group, filter or a list of element IDs. If \a theElements is
# a Mesh, elements of highest dimension are duplicated
# @param theGroupName - a name of group to contain the generated elements. # @param theGroupName - a name of group to contain the generated elements.
# If a group with such a name already exists, the new elements # If a group with such a name already exists, the new elements
# are added to the existng group, else a new group is created. # are added to the existng group, else a new group is created.

View File

@ -841,6 +841,7 @@ void StdMeshers_Import_1D::importMesh(const SMESH_Mesh* srcMesh,
// 1. Copy mesh // 1. Copy mesh
SMESH_MeshEditor::ElemFeatures elemType;
vector<const SMDS_MeshNode*> newNodes; vector<const SMDS_MeshNode*> newNodes;
const SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS(); const SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
SMDS_ElemIteratorPtr eIt = srcMeshDS->elementsIterator(); SMDS_ElemIteratorPtr eIt = srcMeshDS->elementsIterator();
@ -865,7 +866,7 @@ void StdMeshers_Import_1D::importMesh(const SMESH_Mesh* srcMesh,
tgtMeshDS->FindElement( newNodes, elem->GetType(), /*noMedium=*/false ); tgtMeshDS->FindElement( newNodes, elem->GetType(), /*noMedium=*/false );
if ( !newElem ) if ( !newElem )
{ {
newElem = additor.AddElement( newNodes, elem->GetType(), elem->IsPoly()); newElem = additor.AddElement( newNodes, elemType.Init( elem, /*basicOnly=*/false ));
tgtSubMesh->AddElement( newElem ); tgtSubMesh->AddElement( newElem );
} }
if ( toCopyGroups ) if ( toCopyGroups )

View File

@ -454,7 +454,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
if ( geomNorm * meshNorm < 0 ) if ( geomNorm * meshNorm < 0 )
SMDS_MeshCell::applyInterlace SMDS_MeshCell::applyInterlace
( SMDS_MeshCell::reverseSmdsOrder( face->GetEntityType() ), newNodes ); ( SMDS_MeshCell::reverseSmdsOrder( face->GetEntityType(), newNodes.size() ), newNodes );
} }
// make a new face // make a new face

View File

@ -29,6 +29,7 @@
#include "SMESH_Gen.hxx" #include "SMESH_Gen.hxx"
#include "SMESH_MAT2d.hxx" #include "SMESH_MAT2d.hxx"
#include "SMESH_Mesh.hxx" #include "SMESH_Mesh.hxx"
#include "SMESH_MeshEditor.hxx"
#include "SMESH_MesherHelper.hxx" #include "SMESH_MesherHelper.hxx"
#include "SMESH_ProxyMesh.hxx" #include "SMESH_ProxyMesh.hxx"
#include "SMESH_subMesh.hxx" #include "SMESH_subMesh.hxx"
@ -124,6 +125,34 @@ bool StdMeshers_QuadFromMedialAxis_1D2D::CheckHypothesis(SMESH_Mesh& aMe
namespace namespace
{ {
typedef map< const SMDS_MeshNode*, list< const SMDS_MeshNode* > > TMergeMap;
//================================================================================
/*!
* \brief Sinuous face
*/
struct SinuousFace
{
FaceQuadStruct::Ptr _quad;
vector< TopoDS_Edge > _edges;
vector< TopoDS_Edge > _sinuSide[2], _shortSide[2];
vector< TopoDS_Edge > _sinuEdges;
int _nbWires;
list< int > _nbEdgesInWire;
TMergeMap _nodesToMerge;
SinuousFace( const TopoDS_Face& f ): _quad( new FaceQuadStruct )
{
list< TopoDS_Edge > edges;
_nbWires = SMESH_Block::GetOrderedEdges (f, edges, _nbEdgesInWire);
_edges.assign( edges.begin(), edges.end() );
_quad->side.resize( 4 );
_quad->face = f;
}
const TopoDS_Face& Face() const { return _quad->face; }
};
//================================================================================ //================================================================================
/*! /*!
* \brief Temporary mesh * \brief Temporary mesh
@ -136,6 +165,18 @@ namespace
} }
}; };
//================================================================================
/*!
* \brief Return a member of a std::pair
*/
//================================================================================
template< typename T >
T& get( std::pair< T, T >& thePair, bool is2nd )
{
return is2nd ? thePair.second : thePair.first;
}
//================================================================================ //================================================================================
/*! /*!
* \brief Select two EDGEs from a map, either mapped to least values or to max values * \brief Select two EDGEs from a map, either mapped to least values or to max values
@ -331,36 +372,42 @@ namespace
//================================================================================ //================================================================================
/*! /*!
* \brief Find EDGEs to discretize using projection from MA * \brief Find EDGEs to discretize using projection from MA
* \param [in] theFace - the FACE to be meshed * \param [in,out] theSinuFace - the FACE to be meshed
* \param [in] theWire - ordered EDGEs of the FACE
* \param [out] theSinuEdges - the EDGEs to discretize using projection from MA
* \param [out] theShortEdges - other EDGEs
* \return bool - OK or not * \return bool - OK or not
* *
* Is separate all EDGEs into four sides of a quadrangle connected in the order: * It separates all EDGEs into four sides of a quadrangle connected in the order:
* theSinuEdges[0], theShortEdges[0], theSinuEdges[1], theShortEdges[1] * theSinuEdges[0], theShortEdges[0], theSinuEdges[1], theShortEdges[1]
*/ */
//================================================================================ //================================================================================
bool getSinuousEdges( SMESH_MesherHelper& theHelper, bool getSinuousEdges( SMESH_MesherHelper& theHelper,
const TopoDS_Face& theFace, SinuousFace& theSinuFace)
list<TopoDS_Edge>& theWire,
vector<TopoDS_Edge> theSinuEdges[2],
vector<TopoDS_Edge> theShortEdges[2])
{ {
vector<TopoDS_Edge> * theSinuEdges = & theSinuFace._sinuSide [0];
vector<TopoDS_Edge> * theShortEdges = & theSinuFace._shortSide[0];
theSinuEdges[0].clear(); theSinuEdges[0].clear();
theSinuEdges[1].clear(); theSinuEdges[1].clear();
theShortEdges[0].clear(); theShortEdges[0].clear();
theShortEdges[1].clear(); theShortEdges[1].clear();
vector<TopoDS_Edge> allEdges( theWire.begin(), theWire.end() ); vector<TopoDS_Edge> & allEdges = theSinuFace._edges;
const size_t nbEdges = allEdges.size(); const size_t nbEdges = allEdges.size();
if ( nbEdges < 4 ) if ( nbEdges < 4 && theSinuFace._nbWires == 1 )
return false;
if ( theSinuFace._nbWires == 2 ) // ring
{
size_t nbOutEdges = theSinuFace._nbEdgesInWire.front();
theSinuEdges[0].assign ( allEdges.begin(), allEdges.begin() + nbOutEdges );
theSinuEdges[1].assign ( allEdges.begin() + nbOutEdges, allEdges.end() );
return true;
}
if ( theSinuFace._nbWires > 2 )
return false; return false;
// create MedialAxis to find short edges by analyzing MA branches // create MedialAxis to find short edges by analyzing MA branches
double minSegLen = getMinSegLen( theHelper, allEdges ); double minSegLen = getMinSegLen( theHelper, allEdges );
SMESH_MAT2d::MedialAxis ma( theFace, allEdges, minSegLen ); SMESH_MAT2d::MedialAxis ma( theSinuFace.Face(), allEdges, minSegLen * 3 );
// in an initial request case, theFace represents a part of a river with almost parallel banks // in an initial request case, theFace represents a part of a river with almost parallel banks
// so there should be two branch points // so there should be two branch points
@ -430,6 +477,10 @@ namespace
!vCommon.IsSame( theHelper.IthVertex( 1, theSinuEdges[0].back() ))) !vCommon.IsSame( theHelper.IthVertex( 1, theSinuEdges[0].back() )))
theShortEdges[0].swap( theShortEdges[1] ); theShortEdges[0].swap( theShortEdges[1] );
theSinuFace._sinuEdges = theSinuEdges[0];
theSinuFace._sinuEdges.insert( theSinuFace._sinuEdges.end(),
theSinuEdges[1].begin(), theSinuEdges[1].end() );
return ( theShortEdges[0].size() > 0 && theShortEdges[1].size() > 0 && return ( theShortEdges[0].size() > 0 && theShortEdges[1].size() > 0 &&
theSinuEdges [0].size() > 0 && theSinuEdges [1].size() > 0 ); theSinuEdges [0].size() > 0 && theSinuEdges [1].size() > 0 );
@ -604,21 +655,21 @@ namespace
bool divideMA( SMESH_MesherHelper& theHelper, bool divideMA( SMESH_MesherHelper& theHelper,
const SMESH_MAT2d::MedialAxis& theMA, const SMESH_MAT2d::MedialAxis& theMA,
const vector<TopoDS_Edge>& theSinuEdges, const SinuousFace& theSinuFace,
const size_t theSinuSide0Size,
SMESH_Algo* the1dAlgo, SMESH_Algo* the1dAlgo,
vector<double>& theMAParams ) vector<double>& theMAParams )
{ {
// check if all EDGEs of one size are meshed, then MA discretization is not needed // check if all EDGEs of one size are meshed, then MA discretization is not needed
SMESH_Mesh* mesh = theHelper.GetMesh(); SMESH_Mesh* mesh = theHelper.GetMesh();
size_t nbComputedEdges[2] = { 0, 0 }; size_t nbComputedEdges[2] = { 0, 0 };
for ( size_t i = 1; i < theSinuEdges.size(); ++i ) for ( size_t iS = 0; iS < 2; ++iS )
for ( size_t i = 0; i < theSinuFace._sinuSide[iS].size(); ++i )
{ {
bool isComputed = ( ! mesh->GetSubMesh( theSinuEdges[i] )->IsEmpty() ); bool isComputed = ( ! mesh->GetSubMesh( theSinuFace._sinuSide[iS][i] )->IsEmpty() );
nbComputedEdges[ i < theSinuSide0Size ] += isComputed; nbComputedEdges[ iS ] += isComputed;
} }
if ( nbComputedEdges[0] == theSinuSide0Size || if ( nbComputedEdges[0] == theSinuFace._sinuSide[0].size() ||
nbComputedEdges[1] == theSinuEdges.size() - theSinuSide0Size ) nbComputedEdges[1] == theSinuFace._sinuSide[1].size() )
return true; // discretization is not needed return true; // discretization is not needed
@ -631,13 +682,13 @@ namespace
// cout << "Write " << file << endl; // cout << "Write " << file << endl;
// look for a most local hyps assigned to theSinuEdges // look for a most local hyps assigned to theSinuEdges
TopoDS_Edge edge = theSinuEdges[0]; TopoDS_Edge edge = theSinuFace._sinuEdges[0];
int mostSimpleShape = (int) getHypShape( mesh, edge ); int mostSimpleShape = (int) getHypShape( mesh, edge );
for ( size_t i = 1; i < theSinuEdges.size(); ++i ) for ( size_t i = 1; i < theSinuFace._sinuEdges.size(); ++i )
{ {
int shapeType = (int) getHypShape( mesh, theSinuEdges[i] ); int shapeType = (int) getHypShape( mesh, theSinuFace._sinuEdges[i] );
if ( shapeType > mostSimpleShape ) if ( shapeType > mostSimpleShape )
edge = theSinuEdges[i]; edge = theSinuFace._sinuEdges[i];
} }
SMESH_Algo* algo = the1dAlgo; SMESH_Algo* algo = the1dAlgo;
@ -664,14 +715,13 @@ namespace
//================================================================================ //================================================================================
/*! /*!
* \brief Modifies division parameters on MA to make them coincide with projections * \brief Select division parameters on MA and make them coincide at ends with
* of VERTEXes to MA for a given pair of opposite EDGEs * projections of VERTEXes to MA for a given pair of opposite EDGEs
* \param [in] theEdgePairInd - index of the EDGE pair * \param [in] theEdgePairInd - index of the EDGE pair
* \param [in] theDivPoints - the BranchPoint's dividing MA into parts each * \param [in] theDivPoints - the BranchPoint's dividing MA into parts each
* corresponding to a unique pair of opposite EDGEs * corresponding to a unique pair of opposite EDGEs
* \param [in,out] theMAParams - the MA division parameters to modify * \param [in] theMAParams - the MA division parameters
* \param [in,out] theParBeg - index of the 1st division point for the given EDGE pair * \param [out] theSelectedMAParams - the selected MA parameters
* \param [in,out] theParEnd - index of the last division point for the given EDGE pair
* \return bool - is OK * \return bool - is OK
*/ */
//================================================================================ //================================================================================
@ -686,11 +736,49 @@ namespace
theSelectedMAParams = theMAParams; theSelectedMAParams = theMAParams;
return true; return true;
} }
if ( theEdgePairInd > theDivPoints.size() ) if ( theEdgePairInd > theDivPoints.size() || theMAParams.empty() )
return false; return false;
// TODO // find a range of params to copy
return false;
double par1 = 0;
size_t iPar1 = 0;
if ( theEdgePairInd > 0 )
{
const SMESH_MAT2d::BranchPoint& bp = theDivPoints[ theEdgePairInd-1 ];
bp._branch->getParameter( bp, par1 );
while ( theMAParams[ iPar1 ] < par1 ) ++iPar1;
if ( par1 - theMAParams[ iPar1-1 ] < theMAParams[ iPar1 ] - par1 )
--iPar1;
}
double par2 = 1;
size_t iPar2 = theMAParams.size() - 1;
if ( theEdgePairInd < theDivPoints.size() )
{
const SMESH_MAT2d::BranchPoint& bp = theDivPoints[ theEdgePairInd ];
bp._branch->getParameter( bp, par2 );
iPar2 = iPar1;
while ( theMAParams[ iPar2 ] < par2 ) ++iPar2;
if ( par2 - theMAParams[ iPar2-1 ] < theMAParams[ iPar2 ] - par2 )
--iPar2;
}
theSelectedMAParams.assign( theMAParams.begin() + iPar1,
theMAParams.begin() + iPar2 + 1 );
// adjust theSelectedMAParams to fit between par1 and par2
double d = par1 - theSelectedMAParams[0];
double f = ( par2 - par1 ) / ( theSelectedMAParams.back() - theSelectedMAParams[0] );
for ( size_t i = 0; i < theSelectedMAParams.size(); ++i )
{
theSelectedMAParams[i] += d;
theSelectedMAParams[i] = par1 + ( theSelectedMAParams[i] - par1 ) * f;
}
return true;
} }
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
@ -701,9 +789,14 @@ namespace
double _u; double _u;
int _edgeInd; // index in theSinuEdges vector int _edgeInd; // index in theSinuEdges vector
NodePoint(const SMDS_MeshNode* n=0 ): _node(n), _u(0), _edgeInd(-1) {} NodePoint(): _node(0), _u(0), _edgeInd(-1) {}
NodePoint(const SMDS_MeshNode* n, double u, size_t iEdge ): _node(n), _u(u), _edgeInd(iEdge) {}
NodePoint(double u, size_t iEdge) : _node(0), _u(u), _edgeInd(iEdge) {} NodePoint(double u, size_t iEdge) : _node(0), _u(u), _edgeInd(iEdge) {}
NodePoint(const SMESH_MAT2d::BoundaryPoint& p) : _node(0), _u(p._param), _edgeInd(p._edgeIndex) {} NodePoint(const SMESH_MAT2d::BoundaryPoint& p) : _node(0), _u(p._param), _edgeInd(p._edgeIndex) {}
gp_Pnt Point(const vector< Handle(Geom_Curve) >& curves) const
{
return curves[ _edgeInd ]->Value( _u );
}
}; };
//================================================================================ //================================================================================
@ -726,11 +819,12 @@ namespace
double f,l; double f,l;
BRep_Tool::Range( theSinuEdges[ theNodePnt._edgeInd ], f,l ); BRep_Tool::Range( theSinuEdges[ theNodePnt._edgeInd ], f,l );
const double tol = 1e-3 * ( l - f );
TopoDS_Vertex V; TopoDS_Vertex V;
if ( Abs( f - theNodePnt._u )) if ( Abs( f - theNodePnt._u ) < tol )
V = SMESH_MesherHelper::IthVertex( 0, theSinuEdges[ theNodePnt._edgeInd ], /*CumOri=*/false); V = SMESH_MesherHelper::IthVertex( 0, theSinuEdges[ theNodePnt._edgeInd ], /*CumOri=*/false);
else if ( Abs( l - theNodePnt._u )) else if ( Abs( l - theNodePnt._u ) < tol )
V = SMESH_MesherHelper::IthVertex( 1, theSinuEdges[ theNodePnt._edgeInd ], /*CumOri=*/false); V = SMESH_MesherHelper::IthVertex( 1, theSinuEdges[ theNodePnt._edgeInd ], /*CumOri=*/false);
if ( !V.IsNull() ) if ( !V.IsNull() )
@ -752,21 +846,25 @@ namespace
* \brief Add to the map of NodePoint's those on VERTEXes * \brief Add to the map of NodePoint's those on VERTEXes
* \param [in,out] theHelper - the helper * \param [in,out] theHelper - the helper
* \param [in] theMA - Medial Axis * \param [in] theMA - Medial Axis
* \param [in] theMinSegLen - minimal segment length
* \param [in] theDivPoints - projections of VERTEXes to MA * \param [in] theDivPoints - projections of VERTEXes to MA
* \param [in] theSinuEdges - the sinuous EDGEs * \param [in] theSinuEdges - the sinuous EDGEs
* \param [in] theSideEdgeIDs - indices of sinuous EDGEs per side * \param [in] theSideEdgeIDs - indices of sinuous EDGEs per side
* \param [in] theIsEdgeComputed - is sinuous EGDE is meshed * \param [in] theIsEdgeComputed - is sinuous EGDE is meshed
* \param [in,out] thePointsOnE - the map to fill * \param [in,out] thePointsOnE - the map to fill
* \param [out] theNodes2Merge - the map of nodes to merge
*/ */
//================================================================================ //================================================================================
bool projectVertices( SMESH_MesherHelper& theHelper, bool projectVertices( SMESH_MesherHelper& theHelper,
//const double theMinSegLen,
const SMESH_MAT2d::MedialAxis& theMA, const SMESH_MAT2d::MedialAxis& theMA,
const vector< SMESH_MAT2d::BranchPoint >& theDivPoints, const vector< SMESH_MAT2d::BranchPoint >& theDivPoints,
const vector<TopoDS_Edge>& theSinuEdges, const vector<TopoDS_Edge>& theSinuEdges,
//const vector< int > theSideEdgeIDs[2], const vector< Handle(Geom_Curve) >& theCurves,
const vector< bool >& theIsEdgeComputed, const vector< bool >& theIsEdgeComputed,
map< double, pair< NodePoint, NodePoint > > & thePointsOnE) map< double, pair< NodePoint, NodePoint > > & thePointsOnE,
TMergeMap& theNodes2Merge)
{ {
if ( theDivPoints.empty() ) if ( theDivPoints.empty() )
return true; return true;
@ -792,21 +890,77 @@ namespace
map< double, pair< NodePoint, NodePoint > >::iterator u2NP = map< double, pair< NodePoint, NodePoint > >::iterator u2NP =
thePointsOnE.insert( make_pair( uMA, make_pair( np[0], np[1]))).first; thePointsOnE.insert( make_pair( uMA, make_pair( np[0], np[1]))).first;
if ( !isVertex[0] && !isVertex[1] ) return false; // error
if ( isVertex[0] && isVertex[1] ) if ( isVertex[0] && isVertex[1] )
continue; continue;
const size_t iVertex = isVertex[0] ? 0 : 1;
const size_t iNode = 1 - iVertex;
bool isOppComputed = theIsEdgeComputed[ np[ isVertex[0] ]._edgeInd ]; bool isOppComputed = theIsEdgeComputed[ np[ iNode ]._edgeInd ];
if ( !isOppComputed ) if ( !isOppComputed )
continue; continue;
// a VERTEX is projected on a meshed EDGE; there are two options: // a VERTEX is projected on a meshed EDGE; there are two options:
// - a projected point is joined with a closet node if a strip between this and neighbor // 1) a projected point is joined with a closet node if a strip between this and neighbor
// projection is wide enough; joining is done by setting the same node to the BoundaryPoint // projection is WIDE enough; joining is done by creating a node coincident with the
// - a neighbor projection is merged this this one if it too close; a node of deleted // existing node which will be merged together after all;
// 2) a neighbor projection is merged with this one if it is TOO CLOSE; a node of deleted
// projection is set to the BoundaryPoint of this projection // projection is set to the BoundaryPoint of this projection
// evaluate distance to neighbor projections
const double rShort = 0.2;
bool isShortPrev[2], isShortNext[2];
map< double, pair< NodePoint, NodePoint > >::iterator u2NPPrev = u2NP, u2NPNext = u2NP;
--u2NPPrev; ++u2NPNext;
for ( int iS = 0; iS < 2; ++iS ) // side with Vertex and side with Nodes
{
NodePoint np = get( u2NP->second, iS );
NodePoint npPrev = get( u2NPPrev->second, iS );
NodePoint npNext = get( u2NPNext->second, iS );
gp_Pnt p = np .Point( theCurves );
gp_Pnt pPrev = npPrev.Point( theCurves );
gp_Pnt pNext = npNext.Point( theCurves );
double distPrev = p.Distance( pPrev );
double distNext = p.Distance( pNext );
double r = distPrev / ( distPrev + distNext );
isShortPrev[iS] = ( r < rShort );
isShortNext[iS] = (( 1 - r ) > ( 1 - rShort ));
}
map< double, pair< NodePoint, NodePoint > >::iterator u2NPClose;
if (( isShortPrev[0] && isShortPrev[1] ) || // option 2) -> remove a too close projection
( isShortNext[0] && isShortNext[1] ))
{
u2NPClose = isShortPrev[0] ? u2NPPrev : u2NPNext;
NodePoint& npProj = get( u2NP->second, iNode ); // NP of VERTEX projection
NodePoint npCloseN = get( u2NPClose->second, iNode); // NP close to npProj
NodePoint npCloseV = get( u2NPClose->second, iVertex); // NP close to VERTEX
if ( !npCloseV._node )
{
npProj = npCloseN;
thePointsOnE.erase( isShortPrev[0] ? u2NPPrev : u2NPNext );
continue;
}
else
{
// can't remove the neighbor projection as it is also from VERTEX, -> option 1)
}
}
// else option 1) - wide enough -> "duplicate" existing node
{
u2NPClose = isShortPrev[ iNode ] ? u2NPPrev : u2NPNext;
NodePoint& npProj = get( u2NP->second, iNode ); // NP of VERTEX projection
NodePoint& npCloseN = get( u2NPClose->second, iNode ); // NP close to npProj
// npProj._edgeInd = npCloseN._edgeInd;
// npProj._u = npCloseN._u + 1e-3 * Abs( get( u2NPPrev->second, iNode )._u -
// get( u2NPNext->second, iNode )._u );
gp_Pnt p = npProj.Point( theCurves );
npProj._node = meshDS->AddNode( p.X(), p.Y(), p.Z() );
meshDS->SetNodeOnEdge( npProj._node, theSinuEdges[ npProj._edgeInd ], npProj._u );
theNodes2Merge[ npCloseN._node ].push_back( npProj._node );
}
} }
return true; return true;
} }
@ -816,6 +970,7 @@ namespace
* \brief Divide the sinuous EDGEs by projecting the division point of Medial * \brief Divide the sinuous EDGEs by projecting the division point of Medial
* Axis to the EGDEs * Axis to the EGDEs
* \param [in] theHelper - the helper * \param [in] theHelper - the helper
* \param [in] theMinSegLen - minimal segment length
* \param [in] theMA - the Medial Axis * \param [in] theMA - the Medial Axis
* \param [in] theMAParams - parameters of division points of \a theMA * \param [in] theMAParams - parameters of division points of \a theMA
* \param [in] theSinuEdges - the EDGEs to make nodes on * \param [in] theSinuEdges - the EDGEs to make nodes on
@ -825,10 +980,10 @@ namespace
//================================================================================ //================================================================================
bool computeSinuEdges( SMESH_MesherHelper& theHelper, bool computeSinuEdges( SMESH_MesherHelper& theHelper,
double /*theMinSegLen*/,
SMESH_MAT2d::MedialAxis& theMA, SMESH_MAT2d::MedialAxis& theMA,
vector<double>& theMAParams, vector<double>& theMAParams,
const vector<TopoDS_Edge>& theSinuEdges, SinuousFace& theSinuFace)
const size_t theSinuSide0Size)
{ {
if ( theMA.getBranches().size() != 1 ) if ( theMA.getBranches().size() != 1 )
return false; return false;
@ -842,6 +997,7 @@ namespace
SMESHDS_Mesh* meshDS = theHelper.GetMeshDS(); SMESHDS_Mesh* meshDS = theHelper.GetMeshDS();
double f,l; double f,l;
const vector< TopoDS_Edge >& theSinuEdges = theSinuFace._sinuEdges;
vector< Handle(Geom_Curve) > curves ( theSinuEdges.size() ); vector< Handle(Geom_Curve) > curves ( theSinuEdges.size() );
vector< int > edgeIDs( theSinuEdges.size() ); vector< int > edgeIDs( theSinuEdges.size() );
vector< bool > isComputed( theSinuEdges.size() ); vector< bool > isComputed( theSinuEdges.size() );
@ -854,8 +1010,23 @@ namespace
SMESH_subMesh* sm = mesh->GetSubMesh( theSinuEdges[i] ); SMESH_subMesh* sm = mesh->GetSubMesh( theSinuEdges[i] );
edgeIDs [i] = sm->GetId(); edgeIDs [i] = sm->GetId();
isComputed[i] = ( !sm->IsEmpty() ); isComputed[i] = ( !sm->IsEmpty() );
// if ( isComputed[i] ) if ( isComputed[i] )
// hasComputed = true; {
TopAbs_ShapeEnum shape = getHypShape( mesh, theSinuEdges[i] );
if ( shape == TopAbs_SHAPE || shape <= TopAbs_FACE )
{
// EDGE computed using global hypothesis -> clear it
bool hasComputedFace = false;
PShapeIteratorPtr faceIt = theHelper.GetAncestors( theSinuEdges[i], *mesh, TopAbs_FACE );
while ( const TopoDS_Shape* face = faceIt->next() )
if (( !face->IsSame( theSinuFace.Face())) &&
( hasComputedFace = !mesh->GetSubMesh( *face )->IsEmpty() ))
break;
if ( !hasComputedFace )
sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
isComputed[i] = false;
}
}
} }
const SMESH_MAT2d::Branch& branch = theMA.getBranches()[0]; const SMESH_MAT2d::Branch& branch = theMA.getBranches()[0];
@ -907,7 +1078,7 @@ namespace
branch.getParameter( brp, maParamLast ); branch.getParameter( brp, maParamLast );
map< double, const SMDS_MeshNode* >::iterator u2n = nodeParams.begin(), u2nEnd = --nodeParams.end(); map< double, const SMDS_MeshNode* >::iterator u2n = nodeParams.begin(), u2nEnd = --nodeParams.end();
TMAPar2NPoints::iterator pos, end = pointsOnE.end(); TMAPar2NPoints::iterator end = pointsOnE.end(), pos = end;
TMAPar2NPoints::iterator & hint = (maParamLast > maParam1st) ? end : pos; TMAPar2NPoints::iterator & hint = (maParamLast > maParam1st) ? end : pos;
for ( ++u2n; u2n != u2nEnd; ++u2n ) for ( ++u2n; u2n != u2nEnd; ++u2n )
{ {
@ -918,7 +1089,7 @@ namespace
if ( !branch.getParameter( brp, maParam )) if ( !branch.getParameter( brp, maParam ))
return false; return false;
npN = NodePoint( u2n->second ); npN = NodePoint( u2n->second, u2n->first, iEdgeComputed );
npB = NodePoint( bndPnt ); npB = NodePoint( bndPnt );
pos = pointsOnE.insert( hint, make_pair( maParam, make_pair( np0, np1 ))); pos = pointsOnE.insert( hint, make_pair( maParam, make_pair( np0, np1 )));
} }
@ -950,7 +1121,8 @@ namespace
++iEdgePair; ++iEdgePair;
} }
if ( !projectVertices( theHelper, theMA, divPoints, theSinuEdges, isComputed, pointsOnE )) if ( !projectVertices( theHelper, theMA, divPoints, theSinuEdges, curves,
isComputed, pointsOnE, theSinuFace._nodesToMerge ))
return false; return false;
// create nodes // create nodes
@ -1115,6 +1287,29 @@ namespace
return true; return true;
} }
//================================================================================
/*!
* \brief Remove temporary node
*/
//================================================================================
void mergeNodes( SMESH_MesherHelper& theHelper,
SinuousFace& theSinuFace )
{
SMESH_MeshEditor editor( theHelper.GetMesh() );
SMESH_MeshEditor::TListOfListOfNodes nodesGroups;
TMergeMap::iterator n2nn = theSinuFace._nodesToMerge.begin();
for ( ; n2nn != theSinuFace._nodesToMerge.end(); ++n2nn )
{
nodesGroups.push_back( list< const SMDS_MeshNode* >() );
list< const SMDS_MeshNode* > & group = nodesGroups.back();
group.push_back( n2nn->first );
group.splice( group.end(), n2nn->second );
}
editor.MergeNodes( nodesGroups );
}
} // namespace } // namespace
@ -1200,37 +1395,49 @@ bool StdMeshers_QuadFromMedialAxis_1D2D::Compute(SMESH_Mesh& theMesh,
TopoDS_Face F = TopoDS::Face( theShape ); TopoDS_Face F = TopoDS::Face( theShape );
if ( F.Orientation() >= TopAbs_INTERNAL ) F.Orientation( TopAbs_FORWARD ); if ( F.Orientation() >= TopAbs_INTERNAL ) F.Orientation( TopAbs_FORWARD );
list< TopoDS_Edge > edges; SinuousFace sinuFace( F );
list< int > nbEdgesInWire;
int nbWire = SMESH_Block::GetOrderedEdges (F, edges, nbEdgesInWire);
vector< TopoDS_Edge > sinuSide[2], shortSide[2]; _progress = 0.01;
if ( nbWire == 1 && getSinuousEdges( helper, F, edges, sinuSide, shortSide ))
if ( getSinuousEdges( helper, sinuFace ))
{ {
vector< TopoDS_Edge > sinuEdges = sinuSide[0]; _progress = 0.2;
sinuEdges.insert( sinuEdges.end(), sinuSide[1].begin(), sinuSide[1].end() );
if ( sinuEdges.size() > 2 )
return error(COMPERR_BAD_SHAPE, "Not yet supported case" );
double minSegLen = getMinSegLen( helper, sinuEdges ); // if ( sinuFace._sinuEdges.size() > 2 )
SMESH_MAT2d::MedialAxis ma( F, sinuEdges, minSegLen, /*ignoreCorners=*/true ); // return error(COMPERR_BAD_SHAPE, "Not yet supported case" );
double minSegLen = getMinSegLen( helper, sinuFace._sinuEdges );
SMESH_MAT2d::MedialAxis ma( F, sinuFace._sinuEdges, minSegLen, /*ignoreCorners=*/true );
if ( !_regular1D ) if ( !_regular1D )
_regular1D = new Algo1D( _studyId, _gen ); _regular1D = new Algo1D( _studyId, _gen );
_regular1D->SetSegmentLength( minSegLen ); _regular1D->SetSegmentLength( minSegLen );
vector<double> maParams; vector<double> maParams;
if ( ! divideMA( helper, ma, sinuEdges, sinuSide[0].size(), _regular1D, maParams )) if ( ! divideMA( helper, ma, sinuFace, _regular1D, maParams ))
return error(COMPERR_BAD_SHAPE); return error(COMPERR_BAD_SHAPE);
if ( !computeShortEdges( helper, shortSide[0], _regular1D ) || _progress = 0.4;
!computeShortEdges( helper, shortSide[1], _regular1D ))
if ( !computeShortEdges( helper, sinuFace._shortSide[0], _regular1D ) ||
!computeShortEdges( helper, sinuFace._shortSide[1], _regular1D ))
return error("Failed to mesh short edges"); return error("Failed to mesh short edges");
if ( !computeSinuEdges( helper, ma, maParams, sinuEdges, sinuSide[0].size() )) _progress = 0.6;
if ( !computeSinuEdges( helper, minSegLen, ma, maParams, sinuFace ))
return error("Failed to mesh sinuous edges"); return error("Failed to mesh sinuous edges");
return computeQuads( helper, F, sinuSide, shortSide ); _progress = 0.8;
bool ok = computeQuads( helper, F, sinuFace._sinuSide, sinuFace._shortSide );
if ( ok )
mergeNodes( helper, sinuFace );
_progress = 1.;
return ok;
} }
return error(COMPERR_BAD_SHAPE, "Not implemented so far"); return error(COMPERR_BAD_SHAPE, "Not implemented so far");