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
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
(quadratic triangle, quadrangle, tetrahedron, hexahedron, pentahedron
and pyramid) and with central nodes (bi-quadratic triangle and
quadrangle and tri-quadratic hexahedron).<br>
(quadratic triangle, quadrangle, polygon, tetrahedron, hexahedron,
pentahedron and pyramid) and with central nodes (bi-quadratic triangle
and quadrangle and tri-quadratic hexahedron).<br>
Quadratic mesh can be obtained in two ways:
- Using a global \ref quadratic_mesh_anchor "Quadratic Mesh"
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
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.
@ -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
<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
combo box lists both \ref standalone_group "standalone groups"
and \ref group_on_geom "groups on geometry". If the user chooses a
group on geometry, he is warned and proposed to
\ref convert_to_standalone "convert this group to standalone".
combo box lists groups of all the
\ref grouping_elements_page "three types": both
\ref standalone_group "standalone groups",
\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
a new node/element is not created!

View File

@ -36,7 +36,7 @@ one of the following:
\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
to the specified group or to create the group anew using
<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
<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
combo box lists both \ref standalone_group "standalone groups"
and \ref group_on_geom "groups on geometry". If the user chooses a
group on geometry, he is warned and proposed to
\ref convert_to_standalone "convert this group to standalone".
combo box lists groups of all the
\ref grouping_elements_page "three types": both
\ref standalone_group "standalone groups",
\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
a new quadratic element is not created.
To create any <b>Quadratic Element</b> specify the nodes which will form your
element by selecting them in the 3D viewer with pressed Shift
button. Their numbers will appear in the dialog box as <b>Corner Nodes</b>
(alternatively you can just input numbers in this field without
selection). The edges formed by the corner nodes will appear in the
table. To define the middle 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.
To create any <b>Quadratic Element</b> specify the nodes which will
form your element by selecting them in the 3D viewer with pressed
Shift button and click \a Selection button to the right of
<b>Corner Nodes</b> label. Their numbers will appear in the dialog box
as <b>Corner Nodes</b> (alternatively you can just input numbers in
this field without selection; note that to use this way the mesh
should be selected before invoking this operation). The edges formed
by the corner nodes will appear in the table. To define the middle
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
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

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
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:
<ol>

View File

@ -66,6 +66,7 @@ module SMESH
ADD_QUADEDGE,
ADD_QUADTRIANGLE,
ADD_QUADQUADRANGLE,
ADD_QUADPOLYGON,
ADD_QUADTETRAHEDRON,
ADD_QUADPYRAMID,
ADD_QUADPENTAHEDRON,
@ -89,18 +90,18 @@ module SMESH
struct PointStruct { double x;
double y;
double z; } ;
double z; };
typedef sequence<PointStruct> nodes_array;
struct DirStruct { PointStruct PS ; } ; // analog to OCCT gp_Vec
struct DirStruct { PointStruct PS; }; // analog to OCCT gp_Vec
struct AxisStruct { double x;
double y;
double z;
double vx;
double vy;
double vz; } ;
double vz; };
/*!
* Node location on a shape
*/
@ -132,7 +133,7 @@ module SMESH
BALL,
NB_ELEMENT_TYPES
};
typedef sequence<ElementType> array_of_ElementType ;
typedef sequence<ElementType> array_of_ElementType;
/*!
* Enumeration for element geometry type, like SMDSAbs_GeometryType in SMDSAbs_ElementType.hxx
@ -775,7 +776,7 @@ module SMESH
long NbBiQuadQuadrangles()
raises (SALOME::SALOME_Exception);
long NbPolygons()
long NbPolygons(in ElementOrder order)
raises (SALOME::SALOME_Exception);
long NbVolumes()

View File

@ -143,6 +143,13 @@ module SMESH
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
* by number of given nodes).

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

View File

@ -68,7 +68,6 @@
#include <set>
#include <limits>
#include <TopTools_MapOfShape.hxx>
/*
AUXILIARY METHODS
@ -159,29 +158,6 @@ namespace {
}
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;
}
@ -233,7 +209,7 @@ void NumericalFunctor::SetMesh( const SMDS_Mesh* theMesh )
myMesh = theMesh;
}
bool NumericalFunctor::GetPoints(const int theId,
bool NumericalFunctor::GetPoints(const int theId,
TSequenceOfXYZ& theRes ) const
{
theRes.clear();
@ -257,6 +233,7 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
return false;
theRes.reserve( anElem->NbNodes() );
theRes.setElement( anElem );
// Get nodes of the element
SMDS_ElemIteratorPtr anIter;
@ -273,7 +250,6 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
break;
default:
anIter = anElem->nodesIterator();
//return false;
}
}
else {
@ -281,9 +257,13 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
}
if ( anIter ) {
double xyz[3];
while( anIter->more() ) {
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] ));
}
}
}
@ -348,7 +328,7 @@ void NumericalFunctor::GetHistogram(int nbIntervals,
std::multiset< double > values;
if ( elements.empty() )
{
SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator(GetType());
SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator( GetType() );
while ( elemIt->more() )
values.insert( GetValue( elemIt->next()->GetID() ));
}
@ -481,6 +461,27 @@ double MaxElementLength2D::GetValue( const TSequenceOfXYZ& P )
double D2 = getDistance(P( 3 ),P( 7 ));
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 )
{
@ -699,8 +700,9 @@ double MinimumAngle::GetValue( const TSequenceOfXYZ& P )
aMin = getAngle(P( P.size() ), P( 1 ), P( 2 ));
aMin = Min(aMin,getAngle(P( P.size()-1 ), P( P.size() ), P( 1 )));
for (int i=2; i<P.size();i++){
double A0 = getAngle( P( i-1 ), P( i ), P( i+1 ) );
for ( int i = 2; i < P.size(); i++ )
{
double A0 = getAngle( P( i-1 ), P( i ), P( i+1 ) );
aMin = Min(aMin,A0);
}
@ -1467,11 +1469,14 @@ SMDSAbs_ElementType Skew::GetType() const
double Area::GetValue( const TSequenceOfXYZ& P )
{
double val = 0.0;
if ( P.size() > 2 ) {
if ( P.size() > 2 )
{
gp_Vec aVec1( P(2) - P(1) );
gp_Vec aVec2( P(3) - P(1) );
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 aVec2( P(i) - P(1) );
gp_Vec tmp = aVec1 ^ aVec2;
@ -1523,7 +1528,7 @@ SMDSAbs_ElementType Length::GetType() const
//================================================================================
/*
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;
//cout<<"Length2D::GetValue"<<endl;
if (GetPoints(theElementId,P)){
//for(int jj=1; jj<=P.size(); jj++)
// 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();
if ( GetPoints( theElementId, P ))
{
double aVal = 0;
int len = P.size();
SMDSAbs_EntityType aType = P.getElementEntity();
switch (aType){
case SMDSAbs_All:
case SMDSAbs_Node:
case SMDSAbs_Edge:
if (len == 2){
switch (aType) {
case SMDSEntity_Edge:
if (len == 2)
aVal = getDistance( P( 1 ), P( 2 ) );
break;
}
else if (len == 3){ // quadratic edge
break;
case SMDSEntity_Quad_Edge:
if (len == 3) // quadratic edge
aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 ));
break;
}
case SMDSAbs_Face:
break;
case SMDSEntity_Triangle:
if (len == 3){ // triangles
double L1 = getDistance(P( 1 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 1 ));
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 L2 = getDistance(P( 2 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 4 ));
double L4 = getDistance(P( 4 ),P( 1 ));
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 L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 ));
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 L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 ));
double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 ));
aVal = Min(Min(L1,L2),Min(L3,L4));
break;
}
case SMDSAbs_Volume:
if (len == 4){ // tetraidrs
break;
case SMDSEntity_Tetra:
if (len == 4){ // tetrahedra
double L1 = getDistance(P( 1 ),P( 2 ));
double L2 = getDistance(P( 2 ),P( 3 ));
double L3 = getDistance(P( 3 ),P( 1 ));
@ -1595,9 +1596,10 @@ double Length2D::GetValue( long theElementId )
double L5 = getDistance(P( 2 ),P( 4 ));
double L6 = getDistance(P( 3 ),P( 4 ));
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 L2 = getDistance(P( 2 ),P( 3 ));
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(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 L2 = getDistance(P( 2 ),P( 3 ));
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(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 L2 = getDistance(P( 2 ),P( 3 ));
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(aVal,Min(Min(L7,L8),Min(L9,L10)));
aVal = Min(aVal,Min(L11,L12));
break;
}
break;
case SMDSEntity_Quad_Tetra:
if (len == 10){ // quadratic tetraidrs
double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 ));
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 L6 = getDistance(P( 3 ),P( 10 )) + getDistance(P( 10 ),P( 4 ));
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 L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 ));
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 ));
aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Min(aVal,Min(L7,L8));
break;
}
else if (len == 15){ // quadratic pentaidres
break;
case SMDSEntity_Quad_Penta:
if (len == 15){ // quadratic pentaidres
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 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 ));
aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
aVal = Min(aVal,Min(Min(L7,L8),L9));
break;
}
else if (len == 20){ // quadratic hexaider
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 L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 ));
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(aVal,Min(Min(L7,L8),Min(L9,L10)));
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 ) {
@ -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])
if(myPntId[1] < x.myPntId[1]) return true;
return false;
}
void Length2D::GetValues(TValues& theValues){
void Length2D::GetValues(TValues& theValues)
{
TValues aValues;
SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
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])
if(myPntId[1] < x.myPntId[1]) return true;
return false;
}
void MultiConnection2D::GetValues(MValues& theValues){
void MultiConnection2D::GetValues(MValues& theValues)
{
if ( !myMesh ) return;
SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
for(; anIter->more(); ){
@ -2526,7 +2581,7 @@ bool FreeFaces::IsSatisfy( long theId )
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 >::iterator TItrMapOfVolume; // iterator
TMapOfVolume mapOfVol;
@ -2624,12 +2679,11 @@ static bool isEqual( const Quantity_Color& theColor1,
{
// tolerance to compare colors
const double tol = 5*1e-3;
return ( fabs( theColor1.Red() - theColor2.Red() ) < tol &&
return ( fabs( theColor1.Red() - theColor2.Red() ) < tol &&
fabs( theColor1.Green() - theColor2.Green() ) < tol &&
fabs( theColor1.Blue() - theColor2.Blue() ) < tol );
fabs( theColor1.Blue() - theColor2.Blue() ) < tol );
}
void GroupColor::SetMesh( const SMDS_Mesh* theMesh )
{
myIDs.clear();
@ -4634,20 +4688,20 @@ bool LyingOnGeom::Contains( const SMESHDS_Mesh* theMeshDS,
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>
TSequenceOfXYZ::TSequenceOfXYZ(InputIterator theBegin, InputIterator theEnd): myArray(theBegin,theEnd)
TSequenceOfXYZ::TSequenceOfXYZ(InputIterator theBegin, InputIterator theEnd): myArray(theBegin,theEnd), myElem(0)
{}
TSequenceOfXYZ::~TSequenceOfXYZ()
@ -4656,6 +4710,7 @@ TSequenceOfXYZ::~TSequenceOfXYZ()
TSequenceOfXYZ& TSequenceOfXYZ::operator=(const TSequenceOfXYZ& theSequenceOfXYZ)
{
myArray = theSequenceOfXYZ.myArray;
myElem = theSequenceOfXYZ.myElem;
return *this;
}
@ -4689,6 +4744,11 @@ TSequenceOfXYZ::size_type TSequenceOfXYZ::size() const
return myArray.size();
}
SMDSAbs_EntityType TSequenceOfXYZ::getElementEntity() const
{
return myElem ? myElem->GetEntityType() : SMDSEntity_Last;
}
TMeshModifTracer::TMeshModifTracer():
myMeshModifTime(0), myMesh(0)
{

View File

@ -67,7 +67,7 @@ namespace SMESH{
public:
TSequenceOfXYZ();
TSequenceOfXYZ(size_type n);
explicit TSequenceOfXYZ(size_type n);
TSequenceOfXYZ(size_type n, const gp_XYZ& t);
@ -92,8 +92,16 @@ namespace SMESH{
size_type size() const;
void setElement(const SMDS_MeshElement* e) { myElem = e; }
const SMDS_MeshElement* getElement() const { return myElem; }
SMDSAbs_EntityType getElementEntity() const;
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_Quad_Polygon] = CGNS_ENUMV( NGON_n );
cgTypes[SMDSEntity_Polyhedra] = 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 );
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 ||
elemType == SMDSEntity_Hexagonal_Prism) // POLYHEDRA
{

File diff suppressed because it is too large Load Diff

View File

@ -605,12 +605,21 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
if ( polyTypesSupported ) {
aTElemTypeDatas.push_back( TElemTypeData(anEntity,
ePOLYGONE,
nbElemInfo.NbPolygons(),
nbElemInfo.NbPolygons( ORDER_LINEAR ),
SMDSAbs_Face));
// we need one more loop on poly elements to count nb of their nodes
aTElemTypeDatas.push_back( TElemTypeData(anEntity,
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));
}
#ifdef _ELEMENTS_BY_DIM_
@ -706,9 +715,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
// 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 ) {
// Count nb of nodes
while ( elemIterator->more() ) {
@ -758,9 +772,10 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
break;
}
myMed->SetPolygoneInfo(aPolygoneInfo);
}
}
nbPolygonNodes = 0; // to treat next polygon type
}
}
// Treat POLYEDREs
// ----------------

View File

@ -71,7 +71,7 @@ namespace MED{
eQUAD4=204, eTRIA6=206, eTRIA7=207, eQUAD8=208, eQUAD9=209,eTETRA4=304,
ePYRA5=305, ePENTA6=306, eHEXA8=308, eOCTA12=312, eTETRA10=310,
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*/,
eAllGeoType=-1 } EGeometrieElement;

View File

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

View File

@ -960,22 +960,19 @@ namespace MED
MED::TMeshInfo& aMeshInfo = *theInfo.myMeshInfo;
TValueHolder<TString, char> aMeshName(aMeshInfo.myName);
TValueHolder<TElemNum, med_int> anIndex(theInfo.myIndex);
TInt aNbElem = (TInt)theInfo.myElemNum->size();
TValueHolder<TElemNum, med_int> aConn(theInfo.myConn);
TValueHolder<EEntiteMaillage, med_entity_type> anEntity(theInfo.myEntity);
TValueHolder<TString, char > aMeshName(aMeshInfo.myName);
TValueHolder<TElemNum, med_int > anIndex (theInfo.myIndex);
TValueHolder<TElemNum, med_int > aConn (theInfo.myConn);
TValueHolder<EEntiteMaillage, med_entity_type > anEntity (theInfo.myEntity);
TValueHolder<EGeometrieElement, med_geometry_type> aGeom (theInfo.myGeom);
TValueHolder<EConnectivite, med_connectivity_mode> aConnMode(theInfo.myConnMode);
TInt aNbElem = (TInt)theInfo.myElemNum->size();
TErr aRet;
aRet = MEDmeshPolygonRd(myFile->Id(),
&aMeshName,
MED_NO_DT,
MED_NO_IT,
anEntity,
aConnMode,
&anIndex,
&aConn);
aRet = MEDmeshPolygon2Rd(myFile->Id(), &aMeshName,
MED_NO_DT, MED_NO_IT,
anEntity, aGeom,
aConnMode, &anIndex, &aConn);
if(theErr)
*theErr = aRet;
@ -983,18 +980,18 @@ namespace MED
EXCEPTION(std::runtime_error,"GetPolygoneInfo - MEDmeshPolygonRd(...)");
if(theInfo.myIsElemNames){
GetNames(theInfo,aNbElem,theInfo.myEntity,ePOLYGONE,&aRet);
GetNames(theInfo,aNbElem,theInfo.myEntity,theInfo.myGeom,&aRet);
if(theErr)
*theErr = aRet;
}
if(theInfo.myIsElemNum){
GetNumeration(theInfo,aNbElem,theInfo.myEntity,ePOLYGONE,&aRet);
GetNumeration(theInfo,aNbElem,theInfo.myEntity,theInfo.myGeom,&aRet);
if(theErr)
*theErr = aRet;
}
GetFamilies(theInfo,aNbElem,theInfo.myEntity,ePOLYGONE,&aRet);
GetFamilies(theInfo,aNbElem,theInfo.myEntity,theInfo.myGeom,&aRet);
if(theErr)
*theErr = aRet;
}
@ -1023,37 +1020,32 @@ namespace MED
MED::TPolygoneInfo& anInfo = const_cast<MED::TPolygoneInfo&>(theInfo);
MED::TMeshInfo& aMeshInfo = *anInfo.myMeshInfo;
TValueHolder<TString, char> aMeshName(aMeshInfo.myName);
TValueHolder<TElemNum, med_int> anIndex(anInfo.myIndex);
TValueHolder<TElemNum, med_int> aConn(anInfo.myConn);
TValueHolder<EEntiteMaillage, med_entity_type> anEntity(anInfo.myEntity);
TValueHolder<TString, char > aMeshName(aMeshInfo.myName);
TValueHolder<TElemNum, med_int > anIndex (anInfo.myIndex);
TValueHolder<TElemNum, med_int > aConn (anInfo.myConn);
TValueHolder<EEntiteMaillage, med_entity_type > anEntity (anInfo.myEntity);
TValueHolder<EGeometrieElement, med_geometry_type> aGeom (anInfo.myGeom);
TValueHolder<EConnectivite, med_connectivity_mode> aConnMode(anInfo.myConnMode);
TErr aRet = MEDmeshPolygonWr(myFile->Id(),
&aMeshName,
MED_NO_DT,
MED_NO_IT,
MED_UNDEF_DT,
anEntity,
aConnMode,
anInfo.myNbElem + 1,
&anIndex,
&aConn);
if(theErr)
TErr aRet = MEDmeshPolygon2Wr(myFile->Id(), &aMeshName,
MED_NO_DT, MED_NO_IT, MED_UNDEF_DT,
anEntity, aGeom,
aConnMode, anInfo.myNbElem + 1,
&anIndex, &aConn);
if(theErr)
*theErr = aRet;
else if(aRet < 0)
EXCEPTION(std::runtime_error,"SetPolygoneInfo - MEDmeshPolygonWr(...)");
SetNames(anInfo,theInfo.myEntity,ePOLYGONE,&aRet);
SetNames(anInfo,theInfo.myEntity,anInfo.myGeom,&aRet);
if(theErr)
*theErr = aRet;
SetNumeration(anInfo,theInfo.myEntity,ePOLYGONE,&aRet);
SetNumeration(anInfo,theInfo.myEntity,anInfo.myGeom,&aRet);
if(theErr)
*theErr = aRet;
SetFamilies(anInfo,theInfo.myEntity,ePOLYGONE,&aRet);
SetFamilies(anInfo,theInfo.myEntity,anInfo.myGeom,&aRet);
if(theErr)
*theErr = aRet;
}
@ -1094,7 +1086,7 @@ namespace MED
MED_NO_DT,
MED_NO_IT,
med_entity_type(theEntity),
MED_POLYGON,
med_geometry_type(theGeom),
MED_CONNECTIVITY,
med_connectivity_mode(theConnMode),
&chgt,
@ -1430,16 +1422,14 @@ namespace MED
}
return anInfo;
}
//-----------------------------------------------------------------
TInt
TVWrapper
::GetNbCells(const MED::TMeshInfo& theMeshInfo,
EEntiteMaillage theEntity,
EGeometrieElement theGeom,
EConnectivite theConnMode,
TErr* theErr)
TInt TVWrapper::GetNbCells(const MED::TMeshInfo& theMeshInfo,
EEntiteMaillage theEntity,
EGeometrieElement theGeom,
EConnectivite theConnMode,
TErr* theErr)
{
TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
@ -1449,48 +1439,50 @@ namespace MED
MED::TMeshInfo& aMeshInfo = const_cast<MED::TMeshInfo&>(theMeshInfo);
TValueHolder<TString, char> aMeshName(aMeshInfo.myName);
med_bool chgt,trsf;
if(theGeom!=MED::ePOLYGONE && theGeom!=MED::ePOLYEDRE && theGeom != MED::eBALL)
switch ( theGeom )
{
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);
}
else if(theGeom==MED::ePOLYGONE)
case MED::ePOLYGONE:
case MED::ePOLYGON2:
{
return MEDmeshnEntity(myFile->Id(),&aMeshName,MED_NO_DT,MED_NO_IT,med_entity_type(theEntity),
MED_POLYGON,MED_INDEX_NODE,med_connectivity_mode(theConnMode),&chgt,&trsf)-1;
return MEDmeshnEntity(myFile->Id(),&aMeshName,
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),
MED_POLYHEDRON,MED_INDEX_FACE,med_connectivity_mode(theConnMode),&chgt,&trsf)-1;
return MEDmeshnEntity(myFile->Id(),&aMeshName,
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 );
}
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;
}
//----------------------------------------------------------------------------
void
TVWrapper
::GetCellInfo(MED::TCellInfo& theInfo,
TErr* theErr)
void TVWrapper::GetCellInfo(MED::TCellInfo& theInfo, TErr* theErr)
{
TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
if(theErr && *theErr < 0)
return;
MED::TMeshInfo& aMeshInfo = *theInfo.myMeshInfo;
TValueHolder<TString, char> aMeshName (aMeshInfo.myName);

View File

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

View File

@ -55,35 +55,36 @@ 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;
return myElemVTK2ObjIds[theVtkID];
}
vtkIdType SMESH_ExtractGeometry::GetNodeObjId(int theVtkID){
vtkIdType SMESH_ExtractGeometry::GetNodeObjId(int theVtkID)
{
if ( theVtkID < 0 || theVtkID >= myNodeVTK2ObjIds.size()) return -1;
return myNodeVTK2ObjIds[theVtkID];
}
int SMESH_ExtractGeometry::RequestData(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
int SMESH_ExtractGeometry::RequestData(vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
// get the info objects
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
vtkInformation *outInfo = outputVector->GetInformationObject(0);
// get the input and ouptut
vtkDataSet *input = vtkDataSet::SafeDownCast(
inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkDataSet *input =
vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkUnstructuredGrid *output =
vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkIdType ptId, numPts, numCells, i, cellId, newCellId, newId, *pointMap;
vtkIdList *cellPts;
@ -100,35 +101,35 @@ int SMESH_ExtractGeometry::RequestData(
int npts;
numCells = input->GetNumberOfCells();
numPts = input->GetNumberOfPoints();
vtkDebugMacro(<< "Extracting geometry");
if ( ! this->ImplicitFunction )
{
{
vtkErrorMacro(<<"No implicit function specified");
return 0;
}
}
newCellPts = vtkIdList::New();
newCellPts->Allocate(VTK_CELL_SIZE);
if ( this->ExtractInside )
{
{
multiplier = 1.0;
}
else
{
}
else
{
multiplier = -1.0;
}
}
// Loop over all points determining whether they are inside the
// implicit function. Copy the points and point data if they are.
//
pointMap = new vtkIdType[numPts]; // maps old point ids into new
for (i=0; i < numPts; i++)
{
{
pointMap[i] = -1;
}
}
output->Allocate(numCells/4); //allocate storage for geometry/topology
newPts = vtkPoints::New();
@ -136,7 +137,7 @@ int SMESH_ExtractGeometry::RequestData(
outputPD->CopyAllocate(pd);
outputCD->CopyAllocate(cd);
vtkFloatArray *newScalars = NULL;
if(myStoreMapping){
myElemVTK2ObjIds.clear();
myElemVTK2ObjIds.reserve(numCells);
@ -145,110 +146,110 @@ int SMESH_ExtractGeometry::RequestData(
}
if ( ! this->ExtractBoundaryCells )
{
{
for ( ptId=0; ptId < numPts; ptId++ )
{
{
x = input->GetPoint(ptId);
if ( (this->ImplicitFunction->FunctionValue(x)*multiplier) < 0.0 )
{
{
newId = newPts->InsertNextPoint(x);
pointMap[ptId] = newId;
myNodeVTK2ObjIds.push_back(ptId);
outputPD->CopyData(pd,ptId,newId);
}
}
}
}
else
{
{
// To extract boundary cells, we have to create supplemental information
if ( this->ExtractBoundaryCells )
{
{
double val;
newScalars = vtkFloatArray::New();
newScalars->SetNumberOfValues(numPts);
for (ptId=0; ptId < numPts; ptId++ )
{
{
x = input->GetPoint(ptId);
val = this->ImplicitFunction->FunctionValue(x) * multiplier;
newScalars->SetValue(ptId, val);
if ( val < 0.0 )
{
{
newId = newPts->InsertNextPoint(x);
pointMap[ptId] = newId;
myNodeVTK2ObjIds.push_back(ptId);
outputPD->CopyData(pd,ptId,newId);
}
}
}
}
}
// Now loop over all cells to see whether they are inside implicit
// function (or on boundary if ExtractBoundaryCells is on).
//
for (cellId=0; cellId < numCells; cellId++)
{
{
cell = input->GetCell(cellId);
cellPts = cell->GetPointIds();
numCellPts = cell->GetNumberOfPoints();
newCellPts->Reset();
if ( ! this->ExtractBoundaryCells ) //requires less work
{
{
for ( npts=0, i=0; i < numCellPts; i++, npts++)
{
{
ptId = cellPts->GetId(i);
if ( pointMap[ptId] < 0 )
{
break; //this cell won't be inserted
}
else
{
newCellPts->InsertId(i,pointMap[ptId]);
}
}
} //if don't want to extract boundary cells
else //want boundary cells
{
for ( npts=0, i=0; i < numCellPts; i++ )
{
break; //this cell won't be inserted
}
else
{
newCellPts->InsertId(i,pointMap[ptId]);
}
}
} //if don't want to extract boundary cells
else //want boundary cells
{
for ( npts=0, i=0; i < numCellPts; i++ )
{
ptId = cellPts->GetId(i);
if ( newScalars->GetValue(ptId) <= 0.0 )
{
npts++;
}
}
if ( npts > 0 )
{
npts++;
}
}
if ( npts > 0 )
{
for ( i=0; i < numCellPts; i++ )
{
{
ptId = cellPts->GetId(i);
if ( pointMap[ptId] < 0 )
{
{
x = input->GetPoint(ptId);
newId = newPts->InsertNextPoint(x);
pointMap[ptId] = newId;
myNodeVTK2ObjIds.push_back(ptId);
outputPD->CopyData(pd,ptId,newId);
}
newCellPts->InsertId(i,pointMap[ptId]);
}
}//a boundary or interior cell
}//if mapping boundary cells
if ( npts >= numCellPts || (this->ExtractBoundaryCells && npts > 0) )
{
if(cell->GetCellType() == VTK_POLYHEDRON) {
newCellPts->Reset();
vtkUnstructuredGrid::SafeDownCast(input)->GetFaceStream( cellId ,newCellPts );
vtkUnstructuredGrid::ConvertFaceStreamPointIds(newCellPts, pointMap);
newCellPts->InsertId(i,pointMap[ptId]);
}
newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
myElemVTK2ObjIds.push_back(cellId);
outputCD->CopyData(cd,cellId,newCellId);
}//a boundary or interior cell
}//if mapping boundary cells
if ( npts >= numCellPts || (this->ExtractBoundaryCells && npts > 0) )
{
if(cell->GetCellType() == VTK_POLYHEDRON) {
newCellPts->Reset();
vtkUnstructuredGrid::SafeDownCast(input)->GetFaceStream( cellId ,newCellPts );
vtkUnstructuredGrid::ConvertFaceStreamPointIds(newCellPts, pointMap);
}
}//for all cells
newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
myElemVTK2ObjIds.push_back(cellId);
outputCD->CopyData(cd,cellId,newCellId);
}
}//for all cells
// Update ourselves and release memory
//
@ -256,11 +257,11 @@ int SMESH_ExtractGeometry::RequestData(
newCellPts->Delete();
output->SetPoints(newPts);
newPts->Delete();
if ( this->ExtractBoundaryCells )
{
{
newScalars->Delete();
}
}
output->Squeeze();
return 1;

View File

@ -28,14 +28,16 @@
#include "SMESH_ObjectDef.h"
#include "SMESH_ActorUtils.h"
#include "SMDS_Mesh.hxx"
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
#include "SMDS_BallElement.hxx"
#include "SMDS_Mesh.hxx"
#include "SMDS_MeshCell.hxx"
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
#include "SMESH_Actor.h"
#include "SMESH_ControlsDef.hxx"
#include "SalomeApp_Application.h"
#include "VTKViewer_ExtractUnstructuredGrid.h"
#include "VTKViewer_CellLocationsArray.h"
#include <SalomeApp_Application.h>
#include <VTKViewer_ExtractUnstructuredGrid.h>
#include <VTKViewer_CellLocationsArray.h>
#include CORBA_SERVER_HEADER(SMESH_Gen)
#include CORBA_SERVER_HEADER(SALOME_Exception)
@ -82,48 +84,48 @@ static int MYDEBUGWITHFILES = 0;
// function : getCellType
// purpose : Get type of VTK cell
//=================================================================================
static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
const bool thePoly,
const int theNbNodes )
{
switch( theType )
{
case SMDSAbs_0DElement: return VTK_VERTEX;
// static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
// const bool thePoly,
// const int theNbNodes )
// {
// switch( theType )
// {
// case SMDSAbs_0DElement: return VTK_VERTEX;
case SMDSAbs_Ball: return VTK_POLY_VERTEX;
// case SMDSAbs_Ball: return VTK_POLY_VERTEX;
case SMDSAbs_Edge:
if( theNbNodes == 2 ) return VTK_LINE;
else if ( theNbNodes == 3 ) return VTK_QUADRATIC_EDGE;
else return VTK_EMPTY_CELL;
// case SMDSAbs_Edge:
// if( theNbNodes == 2 ) return VTK_LINE;
// else if ( theNbNodes == 3 ) return VTK_QUADRATIC_EDGE;
// else return VTK_EMPTY_CELL;
case SMDSAbs_Face :
if (thePoly && theNbNodes>2 ) return VTK_POLYGON;
else if ( theNbNodes == 3 ) return VTK_TRIANGLE;
else if ( theNbNodes == 4 ) return VTK_QUAD;
else if ( theNbNodes == 6 ) return VTK_QUADRATIC_TRIANGLE;
else if ( theNbNodes == 8 ) return VTK_QUADRATIC_QUAD;
else if ( theNbNodes == 9 ) return VTK_BIQUADRATIC_QUAD;
else if ( theNbNodes == 7 ) return VTK_BIQUADRATIC_TRIANGLE;
else return VTK_EMPTY_CELL;
// case SMDSAbs_Face :
// if (thePoly && theNbNodes>2 ) return VTK_POLYGON;
// else if ( theNbNodes == 3 ) return VTK_TRIANGLE;
// else if ( theNbNodes == 4 ) return VTK_QUAD;
// else if ( theNbNodes == 6 ) return VTK_QUADRATIC_TRIANGLE;
// else if ( theNbNodes == 8 ) return VTK_QUADRATIC_QUAD;
// else if ( theNbNodes == 9 ) return VTK_BIQUADRATIC_QUAD;
// else if ( theNbNodes == 7 ) return VTK_BIQUADRATIC_TRIANGLE;
// else return VTK_EMPTY_CELL;
case SMDSAbs_Volume:
if (thePoly && theNbNodes>3 ) return VTK_POLYHEDRON; //VTK_CONVEX_POINT_SET;
else if ( theNbNodes == 4 ) return VTK_TETRA;
else if ( theNbNodes == 5 ) return VTK_PYRAMID;
else if ( theNbNodes == 6 ) return VTK_WEDGE;
else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON;
else if ( theNbNodes == 12 ) return VTK_HEXAGONAL_PRISM;
else if ( theNbNodes == 10 ) return VTK_QUADRATIC_TETRA;
else if ( theNbNodes == 20 ) return VTK_QUADRATIC_HEXAHEDRON;
else if ( theNbNodes == 27 ) return VTK_TRIQUADRATIC_HEXAHEDRON;
else if ( theNbNodes == 15 ) return VTK_QUADRATIC_WEDGE;
else if ( theNbNodes == 13 ) return VTK_QUADRATIC_PYRAMID; //VTK_CONVEX_POINT_SET;
else return VTK_EMPTY_CELL;
// case SMDSAbs_Volume:
// if (thePoly && theNbNodes>3 ) return VTK_POLYHEDRON; //VTK_CONVEX_POINT_SET;
// else if ( theNbNodes == 4 ) return VTK_TETRA;
// else if ( theNbNodes == 5 ) return VTK_PYRAMID;
// else if ( theNbNodes == 6 ) return VTK_WEDGE;
// else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON;
// else if ( theNbNodes == 12 ) return VTK_HEXAGONAL_PRISM;
// else if ( theNbNodes == 10 ) return VTK_QUADRATIC_TETRA;
// else if ( theNbNodes == 20 ) return VTK_QUADRATIC_HEXAHEDRON;
// else if ( theNbNodes == 27 ) return VTK_TRIQUADRATIC_HEXAHEDRON;
// else if ( theNbNodes == 15 ) return VTK_QUADRATIC_WEDGE;
// else if ( theNbNodes == 13 ) return VTK_QUADRATIC_PYRAMID; //VTK_CONVEX_POINT_SET;
// else return VTK_EMPTY_CELL;
default: return VTK_EMPTY_CELL;
}
}
// default: return VTK_EMPTY_CELL;
// }
// }
//=================================================================================
// functions : SMESH_VisualObjDef
@ -438,23 +440,23 @@ void SMESH_VisualObjDef::buildElemPrs()
for ( int i = 0; i < nbTypes; i++ ) // iterate through all types of elements
{
if ( nbEnts[ aTypes[ i ] ] > 0 ) {
const SMDSAbs_ElementType& aType = aTypes[ i ];
const TEntityList& aList = anEnts[ aType ];
TEntityList::const_iterator anIter;
for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
{
const SMDS_MeshElement* anElem = *anIter;
vtkIdType aNbNodes = anElem->NbNodes();
anIdList->SetNumberOfIds( aNbNodes );
const vtkIdType vtkElemType = getCellType( aType, anElem->IsPoly(), aNbNodes );
const vtkIdType vtkElemType = SMDS_MeshCell::toVtkType( anElem->GetEntityType() );
int anId = anElem->GetID();
mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
{
// Convertions connectivities from SMDS to VTK

View File

@ -123,7 +123,7 @@ SMESH_SVTKActor
SVTK::CopyPoints( GetSource(), aSourceDataSet );
SVTK::CopyPoints( myBallGrid, aSourceDataSet );
SVTK::CopyPoints( my0DGrid, aSourceDataSet );
int aNbOfParts = theMapIndex.Extent();
@ -143,12 +143,14 @@ SMESH_SVTKActor
{
if(aCell->GetCellType() == VTK_VERTEX ) {
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());
if(myVisualObj) {
outputCD->CopyData(cd, myVisualObj->GetElemVTKId(aPartId), newCellId);
}
} else {
}
else {
myUnstructuredGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds());
}
}

View File

@ -1339,8 +1339,6 @@ SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
}
else
{
//#ifdef VTK_HAVE_POLYHEDRON
//MESSAGE("AddPolygonalFaceWithID vtk " << ID);
myNodeIds.resize( nodes.size() );
for ( size_t i = 0; i < nodes.size(); ++i )
myNodeIds[i] = nodes[i]->getVtkId();
@ -1354,25 +1352,12 @@ SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
return 0;
}
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);
myCells[ID] = face;
myInfo.myNbPolygons++;
}
//#ifndef VTK_HAVE_POLYHEDRON
// if (!registerElement(ID, face))
// {
// registerElement(myElementIDFactory->GetFreeID(), face);
// //RemoveElement(face, false);
// //face = NULL;
// }
//#endif
return face;
}
@ -1386,6 +1371,69 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector<const SMDS_MeshNode*> &
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.
/// @param ID The ID of the new volume
@ -1779,8 +1827,8 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
{
MESSAGE("RemoveNode");
RemoveElement(node, true);
MESSAGE("RemoveNode");
RemoveElement(node, true);
}
///////////////////////////////////////////////////////////////////////////////
@ -1789,7 +1837,7 @@ void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
{
MESSAGE("Remove0DElement");
MESSAGE("Remove0DElement");
RemoveElement(elem0d,true);
}
@ -1799,8 +1847,8 @@ void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
{
MESSAGE("RemoveEdge");
RemoveElement(edge,true);
MESSAGE("RemoveEdge");
RemoveElement(edge,true);
}
///////////////////////////////////////////////////////////////////////////////
@ -1809,8 +1857,8 @@ void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
{
MESSAGE("RemoveFace");
RemoveElement(face, true);
MESSAGE("RemoveFace");
RemoveElement(face, true);
}
///////////////////////////////////////////////////////////////////////////////
@ -1819,8 +1867,8 @@ void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
{
MESSAGE("RemoveVolume");
RemoveElement(volume, true);
MESSAGE("RemoveVolume");
RemoveElement(volume, true);
}
//=======================================================================
@ -1830,8 +1878,8 @@ void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
bool SMDS_Mesh::RemoveFromParent()
{
if (myParent==NULL) return false;
else return (myParent->RemoveSubMesh(this));
if (myParent==NULL) return false;
else return (myParent->RemoveSubMesh(this));
}
//=======================================================================
@ -1841,20 +1889,20 @@ bool SMDS_Mesh::RemoveFromParent()
bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
{
bool found = false;
bool found = false;
list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
for (; itmsh!=myChildren.end() && !found; itmsh++)
{
SMDS_Mesh * submesh = *itmsh;
if (submesh == aMesh)
{
found = true;
myChildren.erase(itmsh);
}
}
list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
for (; itmsh!=myChildren.end() && !found; itmsh++)
{
SMDS_Mesh * submesh = *itmsh;
if (submesh == aMesh)
{
found = true;
myChildren.erase(itmsh);
}
}
return found;
return found;
}
//=======================================================================
@ -1874,10 +1922,10 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
bool Ok = false;
SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
if (cell)
{
Ok = cell->vtkOrder(nodes, nbnodes);
Ok = cell->ChangeNodes(nodes, nbnodes);
}
{
Ok = cell->vtkOrder(nodes, nbnodes);
Ok = cell->ChangeNodes(nodes, nbnodes);
}
if ( Ok ) { // update InverseElements

View File

@ -576,14 +576,22 @@ public:
virtual SMDS_MeshFace* AddPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes);
virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
(const std::vector<int> & nodes_ids,
const std::vector<int> & quantities,
const int ID);
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
(const std::vector<const SMDS_MeshNode*> & nodes,
const std::vector<int> & quantities,
(const std::vector<int> & nodes_ids,
const std::vector<int> & quantities,
const int ID);
virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
(const std::vector<const SMDS_MeshNode*> & nodes,
const std::vector<int> & quantities,
const int ID);
virtual SMDS_MeshVolume* AddPolyhedralVolume

View File

@ -56,7 +56,7 @@ VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType)
vtkTypes[ SMDSEntity_Quad_Quadrangle ] = VTK_QUADRATIC_QUAD;
vtkTypes[ SMDSEntity_BiQuad_Quadrangle ] = VTK_BIQUADRATIC_QUAD;
vtkTypes[ SMDSEntity_Polygon ] = VTK_POLYGON;
//vtkTypes[ SMDSEntity_Quad_Polygon ] = ;
vtkTypes[ SMDSEntity_Quad_Polygon ] = VTK_QUADRATIC_POLYGON;
vtkTypes[ SMDSEntity_Tetra ] = VTK_TETRA;
vtkTypes[ SMDSEntity_Quad_Tetra ] = VTK_QUADRATIC_TETRA;
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 ]]
*/
//================================================================================
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;
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 );
}
}
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];
}
@ -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;
if ( interlace.empty() )
@ -278,15 +306,28 @@ const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType sm
}
{
const int ids[] = {0,3,1,4,2,5,6};
interlace[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
interlace[SMDSEntity_Quad_Triangle ].assign( &ids[0], &ids[0]+6 );
interlace[SMDSEntity_BiQuad_Triangle].assign( &ids[0], &ids[0]+7 );
}
{
const int ids[] = {0,4,1,5,2,6,3,7,8};
interlace[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
interlace[SMDSEntity_Quad_Quadrangle ].assign( &ids[0], &ids[0]+8 );
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];
}

View File

@ -45,10 +45,12 @@ public:
static const std::vector<int>& fromVtkOrder(VTKCellType vtkType);
static const std::vector<int>& fromVtkOrder(SMDSAbs_EntityType smdsType);
static const std::vector<int>& reverseSmdsOrder(SMDSAbs_EntityType smdsType);
static const std::vector<int>& interlacedSmdsOrder(SMDSAbs_EntityType smdsType);
static const std::vector<int>& reverseSmdsOrder(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)
{
if ( interlace.empty() ) return;
@ -57,6 +59,15 @@ public:
tmpData[i] = data[ interlace[i] ];
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;

View File

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

View File

@ -43,6 +43,8 @@
using namespace std;
namespace
{
// ======================================================
// Node indices in faces depending on volume orientation
// 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
// ========================================================
namespace
{
struct XYZ {
double x;
double y;
@ -1498,6 +1498,7 @@ double SMDS_VolumeTool::MaxLinearSize2() const
//================================================================================
/*!
* \brief fast check that only one volume is build on the face nodes
* This check is valid for conformal meshes only
*/
//================================================================================
@ -1510,19 +1511,30 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherV
const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
const int di = myVolume->IsQuadratic() ? 2 : 1;
const SMDS_MeshNode* n1 = nodes[di*0];
const SMDS_MeshNode* n2 = nodes[di*1];
const SMDS_MeshNode* n3 = nodes[di*2];
const int di = myVolume->IsQuadratic() ? 2 : 1;
const int nbN = ( myFaceNbNodes/di <= 4 && !IsPoly()) ? 3 : myFaceNbNodes/di; // nb nodes to check
SMDS_ElemIteratorPtr eIt = n1->GetInverseElementIterator( SMDSAbs_Volume );
SMDS_ElemIteratorPtr nIt;
while ( eIt->more() ) {
SMDS_ElemIteratorPtr eIt = nodes[0]->GetInverseElementIterator( SMDSAbs_Volume );
while ( eIt->more() )
{
const SMDS_MeshElement* vol = eIt->next();
if ( vol != myVolume &&
vol->GetNodeIndex( n2 ) >= 0 &&
vol->GetNodeIndex( n3 ) >= 0 )
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;
return !isFree;
}

View File

@ -71,75 +71,73 @@ SMDS_VtkCellIteratorToUNV::SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCel
vtkUnstructuredGrid* grid = _mesh->getGrid();
grid->GetCellPoints((vtkIdType)_cellId, (vtkIdType&)_nbNodes, pts);
_vtkIdList->SetNumberOfIds(_nbNodes);
int *ids = 0;
const int *ids = 0;
switch (_type)
{
case SMDSEntity_Quad_Edge:
{
static int id[] = { 0, 2, 1 };
ids = id;
break;
}
case SMDSEntity_Quad_Triangle:
case SMDSEntity_BiQuad_Triangle:
{
static int id[] = { 0, 3, 1, 4, 2, 5 };
ids = id;
_nbNodes = 6;
break;
}
case SMDSEntity_Quad_Quadrangle:
case SMDSEntity_BiQuad_Quadrangle:
{
static int id[] = { 0, 4, 1, 5, 2, 6, 3, 7 };
ids = id;
_nbNodes = 8;
break;
}
case SMDSEntity_Quad_Tetra:
{
static int id[] = { 0, 4, 1, 5, 2, 6, 7, 8, 9, 3 };
ids = id;
break;
}
case SMDSEntity_Quad_Pyramid:
{
static int id[] = { 0, 5, 1, 6, 2, 7, 3, 8, 9, 10, 11, 12, 4 };
ids = id;
break;
}
case SMDSEntity_Penta:
{
static int id[] = { 0, 2, 1, 3, 5, 4 };
ids = id;
break;
}
case SMDSEntity_Quad_Penta:
{
static int id[] = { 0, 8, 2, 7, 1, 6, 12, 14, 13, 3, 11, 5, 10, 4, 9 };
ids = id;
break;
}
case SMDSEntity_Quad_Hexa:
case SMDSEntity_TriQuad_Hexa:
{
static int id[] = { 0, 8, 1, 9, 2, 10, 3, 11, 16, 17, 18, 19, 4, 12, 5, 13, 6, 14, 7, 15 };
ids = id;
_nbNodes = 20;
break;
}
case SMDSEntity_Polygon:
case SMDSEntity_Quad_Polygon:
case SMDSEntity_Polyhedra:
case SMDSEntity_Quad_Polyhedra:
default:
{
// 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,
// 25, 26, 27, 28, 29 };
// ids = id;
// break;
}
case SMDSEntity_Quad_Edge:
{
static int id[] = { 0, 2, 1 };
ids = id;
break;
}
case SMDSEntity_Quad_Triangle:
case SMDSEntity_BiQuad_Triangle:
{
static int id[] = { 0, 3, 1, 4, 2, 5 };
ids = id;
_nbNodes = 6;
break;
}
case SMDSEntity_Quad_Quadrangle:
case SMDSEntity_BiQuad_Quadrangle:
{
static int id[] = { 0, 4, 1, 5, 2, 6, 3, 7 };
ids = id;
_nbNodes = 8;
break;
}
case SMDSEntity_Quad_Tetra:
{
static int id[] = { 0, 4, 1, 5, 2, 6, 7, 8, 9, 3 };
ids = id;
break;
}
case SMDSEntity_Quad_Pyramid:
{
static int id[] = { 0, 5, 1, 6, 2, 7, 3, 8, 9, 10, 11, 12, 4 };
ids = id;
break;
}
case SMDSEntity_Penta:
{
static int id[] = { 0, 2, 1, 3, 5, 4 };
ids = id;
break;
}
case SMDSEntity_Quad_Penta:
{
static int id[] = { 0, 8, 2, 7, 1, 6, 12, 14, 13, 3, 11, 5, 10, 4, 9 };
ids = id;
break;
}
case SMDSEntity_Quad_Hexa:
case SMDSEntity_TriQuad_Hexa:
{
static int id[] = { 0, 8, 1, 9, 2, 10, 3, 11, 16, 17, 18, 19, 4, 12, 5, 13, 6, 14, 7, 15 };
ids = id;
_nbNodes = 20;
break;
}
case SMDSEntity_Polygon:
case SMDSEntity_Quad_Polygon:
case SMDSEntity_Polyhedra:
case SMDSEntity_Quad_Polyhedra:
default:
const std::vector<int>& i = SMDS_MeshCell::interlacedSmdsOrder(aType, _nbNodes);
if ( !i.empty() )
ids = & i[0];
}
if ( ids )
for (int i = 0; i < _nbNodes; i++)
_vtkIdList->SetId(i, pts[ids[i]]);
@ -176,34 +174,34 @@ SMDS_VtkCellIteratorPolyH::SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCel
_nbNodes = _vtkIdList->GetNumberOfIds();
switch (_type)
{
case SMDSEntity_Polyhedra:
{
//MESSAGE("SMDS_VtkCellIterator Polyhedra");
vtkIdType nFaces = 0;
vtkIdType* ptIds = 0;
grid->GetFaceStream(_cellId, nFaces, ptIds);
int id = 0;
_nbNodesInFaces = 0;
for (int i = 0; i < nFaces; i++)
{
int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
_nbNodesInFaces += nodesInFace;
id += (nodesInFace + 1);
}
_vtkIdList->SetNumberOfIds(_nbNodesInFaces);
id = 0;
int n = 0;
for (int i = 0; i < nFaces; i++)
{
int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
for (int k = 1; k <= nodesInFace; k++)
_vtkIdList->SetId(n++, ptIds[id + k]);
id += (nodesInFace + 1);
}
break;
}
default:
assert(0);
case SMDSEntity_Polyhedra:
{
//MESSAGE("SMDS_VtkCellIterator Polyhedra");
vtkIdType nFaces = 0;
vtkIdType* ptIds = 0;
grid->GetFaceStream(_cellId, nFaces, ptIds);
int id = 0;
_nbNodesInFaces = 0;
for (int i = 0; i < nFaces; i++)
{
int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
_nbNodesInFaces += nodesInFace;
id += (nodesInFace + 1);
}
_vtkIdList->SetNumberOfIds(_nbNodesInFaces);
id = 0;
int n = 0;
for (int i = 0; i < nFaces; i++)
{
int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
for (int k = 1; k <= nodesInFace; k++)
_vtkIdList->SetId(n++, ptIds[id + k]);
id += (nodesInFace + 1);
}
break;
}
default:
assert(0);
}
}

View File

@ -85,6 +85,15 @@ void SMDS_VtkFace::initPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* me
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)
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
@ -111,26 +120,28 @@ void SMDS_VtkFace::Print(std::ostream & OS) const
int SMDS_VtkFace::NbEdges() const
{
// TODO quadratic polygons ?
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
int nbEdges = 3;
switch (aVtkType)
{
case VTK_TRIANGLE:
case VTK_QUADRATIC_TRIANGLE:
case VTK_BIQUADRATIC_TRIANGLE:
nbEdges = 3;
break;
case VTK_QUAD:
case VTK_QUADRATIC_QUAD:
case VTK_BIQUADRATIC_QUAD:
nbEdges = 4;
break;
case VTK_POLYGON:
default:
nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints();
break;
case VTK_TRIANGLE:
case VTK_QUADRATIC_TRIANGLE:
case VTK_BIQUADRATIC_TRIANGLE:
nbEdges = 3;
break;
case VTK_QUAD:
case VTK_QUADRATIC_QUAD:
case VTK_BIQUADRATIC_QUAD:
nbEdges = 4;
break;
case VTK_QUADRATIC_POLYGON:
nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints() / 2;
break;
case VTK_POLYGON:
default:
nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints();
break;
}
return nbEdges;
}
@ -186,6 +197,7 @@ bool SMDS_VtkFace::IsQuadratic() const
{
case VTK_QUADRATIC_TRIANGLE:
case VTK_QUADRATIC_QUAD:
case VTK_QUADRATIC_POLYGON:
case VTK_BIQUADRATIC_QUAD:
case VTK_BIQUADRATIC_TRIANGLE:
return true;
@ -199,7 +211,7 @@ bool SMDS_VtkFace::IsPoly() const
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
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
@ -209,33 +221,36 @@ bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
int rankFirstMedium = 0;
switch (aVtkType)
{
case VTK_QUADRATIC_TRIANGLE:
case VTK_BIQUADRATIC_TRIANGLE:
rankFirstMedium = 3; // medium nodes are of rank 3,4,5
break;
case VTK_QUADRATIC_QUAD:
case VTK_BIQUADRATIC_QUAD:
rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7
break;
default:
//MESSAGE("wrong element type " << aVtkType);
return false;
case VTK_QUADRATIC_TRIANGLE:
case VTK_BIQUADRATIC_TRIANGLE:
rankFirstMedium = 3; // medium nodes are of rank 3,4,5
break;
case VTK_QUADRATIC_QUAD:
case VTK_BIQUADRATIC_QUAD:
rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7
break;
case VTK_QUADRATIC_POLYGON:
rankFirstMedium = grid->GetCell(myVtkID)->GetNumberOfPoints() / 2;
break;
default:
//MESSAGE("wrong element type " << aVtkType);
return false;
}
vtkIdType npts = 0;
vtkIdType* pts = 0;
grid->GetCellPoints(myVtkID, npts, pts);
vtkIdType nodeId = node->getVtkId();
for (int rank = 0; rank < npts; rank++)
{
if (pts[rank] == nodeId)
{
if (pts[rank] == nodeId)
{
//MESSAGE("rank " << rank << " is medium node " << (rank < rankFirstMedium));
if (rank < rankFirstMedium)
return false;
else
return true;
}
//MESSAGE("rank " << rank << " is medium node " << (rank < rankFirstMedium));
if (rank < rankFirstMedium)
return false;
else
return true;
}
}
//throw SALOME_Exception(LOCALIZED("node does not belong to this element"));
MESSAGE("======================================================");
MESSAGE("= IsMediumNode: node does not belong to this element =");
@ -248,8 +263,17 @@ int SMDS_VtkFace::NbCornerNodes() const
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
vtkIdType aVtkType = grid->GetCellType(myVtkID);
if ( aVtkType != VTK_POLYGON )
return nbPoints <= 4 ? nbPoints : nbPoints / 2;
switch ( aVtkType )
{
case VTK_POLYGON:
break;
case VTK_QUADRATIC_POLYGON:
nbPoints /= 2;
break;
default:
if ( nbPoints > 4 )
nbPoints /= 2;
}
return nbPoints;
}
@ -273,7 +297,8 @@ SMDSAbs_GeometryType SMDS_VtkFace::GetGeomType() const
case VTK_QUADRATIC_QUAD:
case VTK_BIQUADRATIC_QUAD: return SMDSGeom_QUADRANGLE;
case VTK_POLYGON: return SMDSGeom_POLYGON;
case VTK_POLYGON:
case VTK_QUADRATIC_POLYGON: return SMDSGeom_POLYGON;
default:;
}
return SMDSGeom_NONE;

View File

@ -34,6 +34,7 @@ public:
~SMDS_VtkFace();
void init(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);
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);
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 NbBiQuadQuadrangles() 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 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();
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
*/
SMDS_MeshElement* AddElement(const std::vector<const SMDS_MeshNode*> & nodes,
const SMDSAbs_ElementType type,
const bool isPoly,
const int ID = -1,
const double ballDiameter=0.);
const ElemFeatures& features);
/*!
* \brief Add element
*/
SMDS_MeshElement* AddElement(const std::vector<int> & nodeIDs,
const SMDSAbs_ElementType type,
const bool isPoly,
const int ID = -1);
SMDS_MeshElement* AddElement(const std::vector<int> & nodeIDs,
const ElemFeatures& features);
int Remove (const std::list< int >& theElemIDs, const bool isNodes);
// Remove a node or an element.
@ -741,11 +769,11 @@ public:
void LinearAngleVariation(const int NbSteps,
list<double>& theAngles);
bool doubleNodes( SMESHDS_Mesh* theMeshDS,
const TIDSortedElemSet& theElems,
const TIDSortedElemSet& theNodesNot,
std::map< const SMDS_MeshNode*, const SMDS_MeshNode* >& theNodeNodeMap,
const bool theIsDoubleElem );
bool doubleNodes( SMESHDS_Mesh* theMeshDS,
const TIDSortedElemSet& theElems,
const TIDSortedElemSet& theNodesNot,
TNodeNodeMap& theNodeNodeMap,
const bool theIsDoubleElem );
void copyPosition( const SMDS_MeshNode* from,
const SMDS_MeshNode* to );

View File

@ -1996,26 +1996,28 @@ SMDS_MeshFace* SMESH_MesherHelper::AddPolygonalFace (const vector<const SMDS_Mes
SMESHDS_Mesh * meshDS = GetMeshDS();
SMDS_MeshFace* elem = 0;
if(!myCreateQuadratic) {
if(!myCreateQuadratic)
{
if(id)
elem = meshDS->AddPolygonalFaceWithID(nodes, id);
else
elem = meshDS->AddPolygonalFace(nodes);
}
else {
vector<const SMDS_MeshNode*> newNodes;
else
{
vector<const SMDS_MeshNode*> newNodes( nodes.size() * 2 );
newNodes = nodes;
for ( int i = 0; i < nodes.size(); ++i )
{
const SMDS_MeshNode* n1 = nodes[i];
const SMDS_MeshNode* n2 = nodes[(i+1)%nodes.size()];
const SMDS_MeshNode* n12 = GetMediumNode( n1, n2, force3d, TopAbs_FACE );
newNodes.push_back( n1 );
newNodes.push_back( n12 );
}
if(id)
elem = meshDS->AddPolygonalFaceWithID(newNodes, id);
elem = meshDS->AddQuadPolygonalFaceWithID(newNodes, id);
else
elem = meshDS->AddPolygonalFace(newNodes);
elem = meshDS->AddQuadPolygonalFace(newNodes);
}
if ( mySetElemOnShape && myShapeID > 0 )
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
//=======================================================================
@ -903,6 +930,7 @@ SMESH_Client::Update(bool theIsClear)
case SMESH::ADD_QUADEDGE : AddQuadEdgesWithID ( 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_QUADPOLYGON : AddQuadPolygonsWithID( 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_QUADPENTAHEDRON : AddQuadPentasWithID ( mySMDSMesh, aSeq, anId ); break;

View File

@ -295,6 +295,28 @@ void SMESHDS_Command::AddPolygonalFace (const int ElementID,
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
//purpose :

View File

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

View File

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

View File

@ -213,7 +213,7 @@ void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z
//=======================================================================
//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,
@ -708,9 +708,9 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<int>& nod
return anElem;
}
SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
(const std::vector<const SMDS_MeshNode*>& nodes,
const int ID)
SMDS_MeshFace*
SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*>& nodes,
const int ID)
{
SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
if (anElem) {
@ -724,8 +724,8 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
return anElem;
}
SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
(const std::vector<const SMDS_MeshNode*>& nodes)
SMDS_MeshFace*
SMESHDS_Mesh::AddPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes)
{
SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
if (anElem) {
@ -739,6 +739,53 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
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
//purpose :

View File

@ -511,6 +511,14 @@ public:
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
(const std::vector<int>& nodes_ids,
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);
}
//=======================================================================
//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
//purpose :

View File

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

View File

@ -532,7 +532,6 @@ namespace
{
format = "CGNS";
notSupportedElemTypes.push_back( SMESH::Entity_Ball );
notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Triangle );
}
else if ( isSAUV )
{
@ -543,6 +542,7 @@ namespace
notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa );
notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
}
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 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_Polygon];
info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
long nbVolumes = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra] +
info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] +
info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid] +
@ -3274,6 +3274,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
case SMESHOp::OpBiQuadraticTriangle:
case SMESHOp::OpQuadraticQuadrangle:
case SMESHOp::OpBiQuadraticQuadrangle:
case SMESHOp::OpQuadraticPolygon:
case SMESHOp::OpQuadraticTetrahedron:
case SMESHOp::OpQuadraticPyramid:
case SMESHOp::OpQuadraticPentahedron:
@ -3286,15 +3287,16 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
SMDSAbs_EntityType type = SMDSEntity_Last;
switch (theCommandID) {
case SMESHOp::OpQuadraticEdge: type = SMDSEntity_Quad_Edge; break;
case SMESHOp::OpQuadraticTriangle: type = SMDSEntity_Quad_Triangle; break;
case SMESHOp::OpBiQuadraticTriangle: type = SMDSEntity_BiQuad_Triangle; break;
case SMESHOp::OpQuadraticQuadrangle: type = SMDSEntity_Quad_Quadrangle; break;
case SMESHOp::OpBiQuadraticQuadrangle: type = SMDSEntity_BiQuad_Quadrangle; break;
case SMESHOp::OpQuadraticTetrahedron: type = SMDSEntity_Quad_Tetra; break;
case SMESHOp::OpQuadraticPyramid: type = SMDSEntity_Quad_Pyramid; break;
case SMESHOp::OpQuadraticPentahedron: type = SMDSEntity_Quad_Penta; break;
case SMESHOp::OpQuadraticHexahedron: type = SMDSEntity_Quad_Hexa; break;
case SMESHOp::OpQuadraticEdge: type = SMDSEntity_Quad_Edge; break;
case SMESHOp::OpQuadraticTriangle: type = SMDSEntity_Quad_Triangle; break;
case SMESHOp::OpBiQuadraticTriangle: type = SMDSEntity_BiQuad_Triangle; break;
case SMESHOp::OpQuadraticQuadrangle: type = SMDSEntity_Quad_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::OpQuadraticPyramid: type = SMDSEntity_Quad_Pyramid; break;
case SMESHOp::OpQuadraticPentahedron: type = SMDSEntity_Quad_Penta; break;
case SMESHOp::OpQuadraticHexahedron: type = SMDSEntity_Quad_Hexa; break;
case SMESHOp::OpTriQuadraticHexahedron: type = SMDSEntity_TriQuad_Hexa; break;
default: break;
}
@ -3909,6 +3911,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createSMESHAction( SMESHOp::OpBiQuadraticTriangle, "BIQUADRATIC_TRIANGLE", "ICON_DLG_BIQUADRATIC_TRIANGLE" );
createSMESHAction( SMESHOp::OpQuadraticQuadrangle, "QUADRATIC_QUADRANGLE", "ICON_DLG_QUADRATIC_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::OpQuadraticPyramid, "QUADRATIC_PYRAMID", "ICON_DLG_QUADRATIC_PYRAMID" );
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::OpQuadraticQuadrangle, addId, -1 );
createMenu( SMESHOp::OpBiQuadraticQuadrangle, addId, -1 );
createMenu( SMESHOp::OpQuadraticPolygon, addId, -1 );
createMenu( SMESHOp::OpQuadraticTetrahedron, addId, -1 );
createMenu( SMESHOp::OpQuadraticPyramid, addId, -1 );
createMenu( SMESHOp::OpQuadraticPentahedron, addId, -1 );
@ -4276,6 +4280,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createTool( SMESHOp::OpBiQuadraticTriangle, addNonElemTb );
createTool( SMESHOp::OpQuadraticQuadrangle, addNonElemTb );
createTool( SMESHOp::OpBiQuadraticQuadrangle, addNonElemTb );
createTool( SMESHOp::OpQuadraticPolygon, addNonElemTb );
createTool( SMESHOp::OpQuadraticTetrahedron, addNonElemTb );
createTool( SMESHOp::OpQuadraticPyramid, addNonElemTb );
createTool( SMESHOp::OpQuadraticPentahedron, addNonElemTb );

View File

@ -214,12 +214,13 @@ namespace SMESH
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();
myBallPolyData->Reset();
myBallPolyData->DeleteCells();
myBallPolyData->SetPoints(aGrid->GetPoints());
vtkDataArray* aScalars = vtkDataArray::CreateDataArray(VTK_DOUBLE);
aScalars->SetNumberOfComponents(1);
aScalars->SetNumberOfTuples(theIds.size());
@ -235,7 +236,7 @@ namespace SMESH
aScalars->SetTuple(anId,&d);
anIds->Reset();
}
anIds->Delete();
myBallPolyData->Modified();
SetVisibility (false, false, true);
@ -582,6 +583,13 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
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];
}
}
@ -590,16 +598,19 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
SMESH::long_array_var anIdList = new SMESH::long_array;
anIdList->length( 1 );
anIdList[0] = -1;
const bool onlyNodesInMesh = ( myMesh->NbElements() == 0 );
//const bool onlyNodesInMesh = ( myMesh->NbElements() == 0 );
int nbElemsBefore = 0;
switch (myElementType) {
case SMDSAbs_0DElement:
nbElemsBefore = myMesh->Nb0DElements();
anIdList->length( anArrayOfIndices->length() );
for ( size_t i = 0; i < anArrayOfIndices->length(); ++i )
anIdList[i] = aMeshEditor->Add0DElement(anArrayOfIndices[i]);
break;
case SMDSAbs_Ball:
if ( myGeomType == SMDSEntity_Ball ) {
nbElemsBefore = myMesh->NbBalls();
anIdList->length( anArrayOfIndices->length() );
for ( size_t i = 0; i < anArrayOfIndices->length(); ++i )
anIdList[i] = aMeshEditor->AddBall(anArrayOfIndices[i],
@ -607,21 +618,24 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
}
break;
case SMDSAbs_Edge:
nbElemsBefore = myMesh->NbEdges();
anIdList[0] = aMeshEditor->AddEdge(anArrayOfIndices.inout()); break;
case SMDSAbs_Face:
nbElemsBefore = myMesh->NbFaces();
if ( myIsPoly )
anIdList[0] = aMeshEditor->AddPolygonalFace(anArrayOfIndices.inout());
else
anIdList[0] = aMeshEditor->AddFace(anArrayOfIndices.inout());
break;
default:
nbElemsBefore = myMesh->NbVolumes();
anIdList[0] = aMeshEditor->AddVolume(anArrayOfIndices.inout()); break;
}
if ( anIdList[0] > 0 && addToGroup && !aGroupName.isEmpty() ) {
SMESH::SMESH_Group_var aGroupUsed;
if ( aGroup->_is_nil() ) {
// create new group
// create new group
aGroupUsed = SMESH::AddGroup( myMesh, (SMESH::ElementType)myElementType, aGroupName );
if ( !aGroupUsed->_is_nil() ) {
myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
@ -629,7 +643,8 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
}
}
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() ) {
aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
if ( !aGroupUsed->_is_nil() && idx > 0 ) {
@ -637,6 +652,13 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
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
aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
}
@ -650,8 +672,24 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
mySelectionMgr->setSelectedObjects( aList, false );
mySimulation->SetVisibility(false);
if ( onlyNodesInMesh )
myActor->SetRepresentation( SMESH_Actor::eEdge ); // wireframe
// if ( onlyNodesInMesh )
// 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();
buttonOk->setEnabled(false);

View File

@ -95,13 +95,39 @@
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,
bool toReverse, // inverse element
bool toVtkOrder ) // smds connectivity to vtk one
{
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 );
}
if ( toVtkOrder ) // from smds to vtk connectivity
@ -113,7 +139,8 @@ namespace
}
namespace SMESH
{
class TElementSimulationQuad {
class TElementSimulationQuad
{
SalomeApp_Application* myApplication;
SUIT_ViewWindow* myViewWindow;
SVTK_ViewWindow* myVTKViewWindow;
@ -148,7 +175,7 @@ namespace SMESH
myPreviewActor->PickableOff();
myPreviewActor->VisibilityOff();
myPreviewActor->SetMapper(myMapper);
QColor ffc, bfc;
int delta;
vtkProperty* myProp = vtkProperty::New();
@ -249,35 +276,12 @@ namespace SMESH
myGrid->Delete();
// myProp->Delete();
// myBackProp->Delete();
// myProp->Delete();
// myBackProp->Delete();
}
};
}
// 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
\brief Simple 'busy state' flag locker.
@ -335,7 +339,6 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
mySMESHGUI( theModule ),
mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
myGeomType( theType ),
//myType( theType ),
myBusy( false )
{
setModal( false );
@ -359,6 +362,9 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
case SMDSEntity_Quad_Quadrangle:
anElementName = QString("QUADRATIC_QUADRANGLE");
break;
case SMDSEntity_Quad_Polygon:
anElementName = QString("QUADRATIC_POLYGON");
break;
case SMDSEntity_BiQuad_Quadrangle:
anElementName = QString("BIQUADRATIC_QUADRANGLE");
break;
@ -561,6 +567,11 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
myNbCenterNodes = 1;
myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
break;
case SMDSEntity_Quad_Polygon:
aNumRows = 5;
myNbCorners = 0; // no limit
myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_polygons
break;
case SMDSEntity_Quad_Tetra:
aNumRows = 6;
myNbCorners = 4;
@ -689,6 +700,7 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
break;
case SMDSEntity_Quad_Triangle:
case SMDSEntity_Quad_Quadrangle:
case SMDSEntity_Quad_Polygon:
case SMDSEntity_BiQuad_Triangle:
case SMDSEntity_BiQuad_Quadrangle:
case SMDSEntity_Quad_Tetra:
@ -716,7 +728,7 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
if ( myReverseCB->isChecked())
ReverseConnectivity( anIds, myGeomType, /*toReverse=*/true, /*toVtkOrder=*/false );
int aNumberOfIds = anIds.size();
int aNumberOfIds = anIds.size();
SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
anArrayOfIdeces->length( aNumberOfIds );
@ -739,7 +751,14 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
if ( !aGeomGroup->_is_nil() ) {
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 );
if ( res == 1 ) return false;
}
@ -748,24 +767,31 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
}
SMESH::ElementType anElementType;
long anElemId = -1;
long anElemId = -1, nbElemsBefore = 0;
SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
switch (myGeomType) {
case SMDSEntity_Quad_Edge:
anElementType = SMESH::EDGE;
nbElemsBefore = myMesh->NbEdges();
anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
case SMDSEntity_Quad_Triangle:
case SMDSEntity_Quad_Quadrangle:
case SMDSEntity_BiQuad_Triangle:
case SMDSEntity_BiQuad_Quadrangle:
anElementType = SMESH::FACE;
nbElemsBefore = myMesh->NbFaces();
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_Pyramid:
case SMDSEntity_Quad_Penta:
case SMDSEntity_Quad_Hexa:
case SMDSEntity_TriQuad_Hexa:
anElementType = SMESH::VOLUME;
nbElemsBefore = myMesh->NbVolumes();
anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
default: break;
}
@ -781,7 +807,8 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
}
}
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() ) {
aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
if ( !aGroupUsed->_is_nil() && idx > 0 ) {
@ -789,6 +816,13 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
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
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() );
mySelector->ClearIndex();
mySelectionMgr->setSelectedObjects( aList, false );
@ -1007,6 +1058,7 @@ void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
anElementType = SMESH::EDGE; break;
case SMDSEntity_Quad_Triangle:
case SMDSEntity_Quad_Quadrangle:
case SMDSEntity_Quad_Polygon:
case SMDSEntity_BiQuad_Triangle:
case SMDSEntity_BiQuad_Quadrangle:
anElementType = SMESH::FACE; break;
@ -1269,6 +1321,44 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
{
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 )
{
myTable->setEnabled( true );
@ -1295,6 +1385,10 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
aFirstColIds = FirstQuadrangleIds;
aLastColIds = LastQuadrangleIds;
break;
case SMDSEntity_Quad_Polygon:
aFirstColIds = & FirstPolygonIds[0];
aLastColIds = & LastPolygonIds[0];
break;
case SMDSEntity_Quad_Tetra:
aFirstColIds = FirstTetrahedronIds;
aLastColIds = LastTetrahedronIds;

View File

@ -39,7 +39,7 @@ public:
private:
void InverseEntityMode( unsigned int& theOutputMode,
unsigned int theMode );
unsigned int theMode );
private slots:
void onOk();

View File

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

View File

@ -306,11 +306,13 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
QLabel* a2DQuaBiQuad = createField();
QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this );
QLabel* a2DPolTotal = createField();
QLabel* a2DPolLin = createField();
QLabel* a2DPolQuad = createField();
myWidgets[ index++ ] << a2DLine;
myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad << a2DBiQuad;
myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
myWidgets[ index++ ] << a2DPolLab << a2DPolTotal;
myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad;
// ... 3D elements
QWidget* a3DLine = createLine();
@ -414,6 +416,8 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
l->addWidget( a2DQuaBiQuad, 17, 4 );
l->addWidget( a2DPolLab, 18, 0 );
l->addWidget( a2DPolTotal, 18, 1 );
l->addWidget( a2DPolLin, 18, 2 );
l->addWidget( a2DPolQuad, 18, 3 );
l->addWidget( a3DLine, 19, 1, 1, 4 );
l->addWidget( a3DLab, 20, 0 );
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] ) );
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 nb2DPolygons = info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_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 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][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_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 nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
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][iQuadratic] ->setProperty( "text", "?" );
myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
myWidgets[i2DPolygons][iLinear] ->setProperty( "text", "?" );
myWidgets[i2DPolygons][iQuadratic] ->setProperty( "text", "?" );
myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" );
myWidgets[iNb][iTotal] ->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][iQuadratic] ->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[i3D][iTotal] ->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*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( "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*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";

View File

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

View File

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

View File

@ -792,6 +792,10 @@
<source>MEN_POLYGON</source>
<translation>Polygon</translation>
</message>
<message>
<source>MEN_QUADRATIC_POLYGON</source>
<translation>Quadratic Polygon</translation>
</message>
<message>
<source>MEN_POLYHEDRON</source>
<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>
</message>
<message>
<source>MESH_STANDALONE_GRP_CHOSEN</source>
<source>MESH_GEOM_GRP_CHOSEN</source>
<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>
</message>
<message>
@ -1225,6 +1234,14 @@ Please enter correct values and try again</translation>
<source>SMESH_ADD_POLYGON_TITLE</source>
<translation>Add Polygon</translation>
</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>
<source>SMESH_ADD_PENTA</source>
<translation>Add pentahedron</translation>
@ -3224,6 +3241,10 @@ Use Display Entity menu command to show them.
<source>STB_POLYGON</source>
<translation>Polygon</translation>
</message>
<message>
<source>STB_QUADRATIC_POLYGON</source>
<translation>Quadratic Polygon</translation>
</message>
<message>
<source>STB_POLYHEDRON</source>
<translation>Polyhedron</translation>
@ -3880,6 +3901,10 @@ Use Display Entity menu command to show them.
<source>TOP_POLYGON</source>
<translation>Polygon</translation>
</message>
<message>
<source>TOP_QUADRATIC_POLYGON</source>
<translation>Quadratic Polygon</translation>
</message>
<message>
<source>TOP_POLYHEDRON</source>
<translation>Polyhedron</translation>

View File

@ -859,7 +859,7 @@ namespace
}
// 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;
for ( size_t i = 0; i < branchEdges.size(); ++i )
{
@ -912,28 +912,24 @@ namespace
{
edgeInd += dInd;
if ( edgeInd < 0 ||
edgeInd >= (int) branchEdges[ brID ].size() ||
branchEdges[ brID ][ edgeInd ] != bndSegs[ i ]._edge )
if (( edgeInd < 0 ||
edgeInd >= (int) branchEdges[ brID ].size() ) ||
( branchEdges[ brID ][ edgeInd ] != bndSegs[ i ]._edge &&
branchEdges[ brID ][ edgeInd ]->twin() != bndSegs[ i ]._edge ))
{
if ( bndSegs[ i ]._branchID < 0 &&
branchEdges[ brID ].back() == bndSegs[ i ]._edge )
if ( bndSegs[ i ]._branchID < 0 )
{
edgeInd = branchEdges[ brID ].size() - 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 &&
branchEdges[ brID ].front() == bndSegs[ i ]._edge )
else // bndSegs[ i ]._branchID > 0
{
edgeInd = 0;
dInd = +1;
}
else
{
for ( edgeInd = 0; edgeInd < branchEdges[ brID ].size(); ++edgeInd )
if ( branchEdges[ brID ][ edgeInd ] == bndSegs[ i ]._edge )
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
if ( bndPoints._maEdges.empty() )
{
// should not get here according to algo design
// should not get here according to algo design???
edgeInd = 0;
}
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
* \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 [out] p - the found BranchPoint
* \return bool - is OK
@ -1052,7 +1048,7 @@ bool SMESH_MAT2d::Boundary::getBranchPoint( const std::size_t iEdge,
return false;
const BndPoints& points = _pointsPerEdge[ iEdge ];
const bool edgeReverse = ( points._params[0] > points._params.back() );
const bool edgeReverse = ( points._params[0] > points._params.back() );
if ( u < ( edgeReverse ? points._params.back() : points._params[0] ))
u = edgeReverse ? points._params.back() : points._params[0];
@ -1071,13 +1067,29 @@ bool SMESH_MAT2d::Boundary::getBranchPoint( const std::size_t iEdge,
while ( points._params[i ] > u ) --i;
while ( points._params[i+1] < u ) ++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 ];
bool maReverse = ( maE.second < 0 );
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;
return true;
@ -1244,6 +1256,8 @@ bool SMESH_MAT2d::Branch::getBoundaryPoints(std::size_t iMAEdge,
{
if ( iMAEdge > _maEdges.size() )
return false;
if ( iMAEdge == _maEdges.size() )
iMAEdge = _maEdges.size() - 1;
size_t iGeom1 = getGeomEdge( _maEdges[ iMAEdge ] );
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 )
return false;
if ( p._iEdge == _params.size()-1 )
return u = 1.;
u = ( _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::ListOfGroups_var aListOfGroups;
::SMESH_MeshEditor::ElemFeatures elemType;
std::vector<const SMDS_MeshNode*> aNodesArray;
// 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
aNewElem = 0;
switch ( anElem->GetEntityType() )
{
case SMDSEntity_Polyhedra:
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 ( anElem->GetType() == SMDSAbs_Node )
aNewElem = 0;
else
aNewElem =
aNewEditor.AddElement( aNodesArray, elemType.Init( anElem, /*basicOnly=*/false ));
if ( 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();
::SMESH_MeshEditor editor( &newMesh_i->GetImpl() );
::SMESH_MeshEditor::ElemFeatures elemType;
// 3. Get elements to copy
@ -2808,30 +2791,12 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
// add elements
if ( elem->GetType() != SMDSAbs_Node )
{
int ID = toKeepIDs ? elem->GetID() : 0;
const SMDS_MeshElement * newElem;
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);
elemType.Init( elem, /*basicOnly=*/false );
if ( toKeepIDs ) elemType.SetID( elem->GetID() );
const SMDS_MeshElement * newElem = editor.AddElement( nodes, elemType );
if ( toCopyGroups && !toKeepIDs )
e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem ));
}
}
} // while ( srcElemIt->more() )

View File

@ -154,20 +154,11 @@ namespace MeshEditor_I {
}
// creates a corresponding element on copied nodes
SMDS_MeshElement* anElemCopy = 0;
if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
{
const SMDS_VtkVolume* ph =
dynamic_cast<const SMDS_VtkVolume*> (anElem);
if ( ph )
anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
(anElemNodesID, ph->GetQuantities(),anElem->GetID());
}
else {
anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
anElem->GetType(),
anElem->IsPoly() );
}
::SMESH_MeshEditor::ElemFeatures elemType;
elemType.Init( anElem, /*basicOnly=*/false );
elemType.SetID( anElem->GetID() );
SMDS_MeshElement* anElemCopy =
::SMESH_MeshEditor(this).AddElement( anElemNodesID, elemType );
return anElemCopy;
}
//!< Copy a node
@ -535,7 +526,7 @@ TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewEle
SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
throw (SALOME::SALOME_Exception)
{
{
SMESH_TRY;
const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
@ -557,7 +548,7 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
myPreviewData = new SMESH::MeshPreviewStruct();
myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
SMDSAbs_ElementType previewType = SMDSAbs_All;
if ( !hasBadElems )
if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
@ -577,7 +568,10 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
while ( itMeshElems->more() ) {
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() ) {
const SMDS_MeshNode* aMeshNode = itElemNodes->next();
int aNodeID = aMeshNode->GetID();
@ -1059,6 +1053,7 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
* AddPolygonalFace
*/
//=============================================================================
CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
throw (SALOME::SALOME_Exception)
{
@ -1082,6 +1077,35 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO
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

View File

@ -117,6 +117,8 @@ public:
throw (SALOME::SALOME_Exception);
CORBA::Long AddPolygonalFace(const SMESH::long_array & IDsOfNodes)
throw (SALOME::SALOME_Exception);
CORBA::Long AddQuadPolygonalFace(const SMESH::long_array & IDsOfNodes)
throw (SALOME::SALOME_Exception);
CORBA::Long AddVolume(const SMESH::long_array & IDsOfNodes)
throw (SALOME::SALOME_Exception);
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();
}
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);
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)
@ -4851,6 +4851,7 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
::SMESH_MeshEditor::ElemFeatures elemType;
// submesh by subshape id
if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
@ -4883,7 +4884,7 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
if ( elem )
{
::SMESH_MeshEditor editor( _impl );
elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
elem = editor.AddElement( nodes, elemType.Init( elem ));
}
}
if ( elem )

View File

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

View File

@ -2242,11 +2242,11 @@ class Mesh:
def NbBiQuadQuadrangles(self):
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
# @ingroup l1_meshinfo
def NbPolygons(self):
return self.mesh.NbPolygons()
def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
return self.mesh.NbPolygons(elementOrder)
## Returns the number of volumes in the mesh
# @return an integer value
@ -2367,7 +2367,7 @@ class Mesh:
## Returns the type of mesh element
# @return the value from SMESH::ElementType enumeration
# @ingroup l1_meshinfo
def GetElementType(self, id, iselem):
def GetElementType(self, id, iselem=True):
return self.mesh.GetElementType(id, iselem)
## Returns the geometric type of mesh element
@ -2455,24 +2455,22 @@ class Mesh:
def GetElementPosition(self,ElemID):
return self.mesh.GetElementPosition(ElemID)
## If the given element is a node, returns the ID of shape
# \n If there is no node for the given ID - returns -1
# @return an integer value
## Returns the ID of the shape, on which the given node was generated.
# @return an integer value > 0 or -1 if there is no node for the given
# ID or the node is not assigned to any geometry
# @ingroup l1_meshinfo
def GetShapeID(self, id):
return self.mesh.GetShapeID(id)
## Returns the ID of the result shape after
# FindShape() from SMESH_MeshEditor for the given element
# \n If there is no element for the given ID - returns -1
# @return an integer value
## Returns the ID of the shape, on which the given element was generated.
# @return an integer value > 0 or -1 if there is no element for the given
# ID or the element is not assigned to any geometry
# @ingroup l1_meshinfo
def GetShapeIDForElem(self,id):
return self.mesh.GetShapeIDForElem(id)
## Returns the number of nodes for the given element
# \n If there is no element for the given ID - returns -1
# @return an integer value
## Returns the number of nodes of the given element
# @return an integer value > 0 or -1 if there is no element for the given ID
# @ingroup l1_meshinfo
def GetElemNbNodes(self, 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
# @ingroup l1_meshinfo
def IsMediumNodeOfAnyElem(self, nodeID, elementType):
def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
## Returns the number of edges for the given element
@ -2756,6 +2754,14 @@ class Mesh:
def AddPolygonalFace(self, 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
# by the number of given nodes).
# @param IDsOfNodes the list of node IDs for creation of the element.
@ -3990,8 +3996,8 @@ class Mesh:
## Creates a symmetrical copy of mesh elements
# @param IDsOfElements list of elements ids
# @param Mirror is AxisStruct or geom object(point, line, plane)
# @param theMirrorType is POINT, AXIS or PLANE
# If the Mirror is a geom object this parameter is unnecessary
# @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
# 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 MakeGroups forces the generation of new groups from existing ones (if Copy)
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
@ -4012,8 +4018,8 @@ class Mesh:
## Creates a new mesh by a symmetrical copy of mesh elements
# @param IDsOfElements the list of elements ids
# @param Mirror is AxisStruct or geom object (point, line, plane)
# @param theMirrorType is POINT, AXIS or PLANE
# If the Mirror is a geom object this parameter is unnecessary
# @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
# If the Mirror is a geom object this parameter is unnecessary
# @param MakeGroups to generate new groups from existing ones
# @param NewMeshName a name of the new mesh to create
# @return instance of Mesh class
@ -4033,8 +4039,8 @@ class Mesh:
## Creates a symmetrical copy of the object
# @param theObject mesh, submesh or group
# @param Mirror AxisStruct or geom object (point, line, plane)
# @param theMirrorType is POINT, AXIS or PLANE
# If the Mirror is a geom object this parameter is unnecessary
# @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
# 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 MakeGroups forces the generation of new groups from existing ones (if Copy)
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
@ -4055,8 +4061,8 @@ class Mesh:
## Creates a new mesh by a symmetrical copy of the object
# @param theObject mesh, submesh or group
# @param Mirror AxisStruct or geom object (point, line, plane)
# @param theMirrorType POINT, AXIS or PLANE
# If the Mirror is a geom object this parameter is unnecessary
# @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
# If the Mirror is a geom object this parameter is unnecessary
# @param MakeGroups forces the generation of new groups from existing ones
# @param NewMeshName the name of the new mesh to create
# @return instance of Mesh class
@ -4420,8 +4426,9 @@ class Mesh:
## Creates Duplicates given elements, i.e. creates new elements based on the
# same nodes as the given ones.
# @param theElements - container of elements to duplicate. It can be a Mesh,
# sub-mesh, group, filter or a list of element IDs.
# @param theGroupName - a name of group to contain the generated elements.
# 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.
# If a group with such a name already exists, the new elements
# are added to the existng group, else a new group is created.
# If \a theGroupName is empty, new elements are not added

View File

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

View File

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

View File

@ -29,6 +29,7 @@
#include "SMESH_Gen.hxx"
#include "SMESH_MAT2d.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_MeshEditor.hxx"
#include "SMESH_MesherHelper.hxx"
#include "SMESH_ProxyMesh.hxx"
#include "SMESH_subMesh.hxx"
@ -124,6 +125,34 @@ bool StdMeshers_QuadFromMedialAxis_1D2D::CheckHypothesis(SMESH_Mesh& aMe
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
@ -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
@ -331,36 +372,42 @@ namespace
//================================================================================
/*!
* \brief Find EDGEs to discretize using projection from MA
* \param [in] theFace - 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
* \param [in,out] theSinuFace - the FACE to be meshed
* \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]
*/
//================================================================================
bool getSinuousEdges( SMESH_MesherHelper& theHelper,
const TopoDS_Face& theFace,
list<TopoDS_Edge>& theWire,
vector<TopoDS_Edge> theSinuEdges[2],
vector<TopoDS_Edge> theShortEdges[2])
SinuousFace& theSinuFace)
{
vector<TopoDS_Edge> * theSinuEdges = & theSinuFace._sinuSide [0];
vector<TopoDS_Edge> * theShortEdges = & theSinuFace._shortSide[0];
theSinuEdges[0].clear();
theSinuEdges[1].clear();
theShortEdges[0].clear();
theShortEdges[1].clear();
vector<TopoDS_Edge> allEdges( theWire.begin(), theWire.end() );
vector<TopoDS_Edge> & allEdges = theSinuFace._edges;
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;
// create MedialAxis to find short edges by analyzing MA branches
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
// so there should be two branch points
@ -430,6 +477,10 @@ namespace
!vCommon.IsSame( theHelper.IthVertex( 1, theSinuEdges[0].back() )))
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 &&
theSinuEdges [0].size() > 0 && theSinuEdges [1].size() > 0 );
@ -437,17 +488,17 @@ namespace
// therefor we use a complex criterion to find TWO short non-sinuous EDGEs
// and the rest EDGEs will be treated as sinuous.
// A short edge should have the following features:
// a) straight
// b) short
// c) with convex corners at ends
// d) far from the other short EDGE
// a) straight
// b) short
// c) with convex corners at ends
// d) far from the other short EDGE
// vector< double > isStraightEdge( nbEdges, 0 ); // criterion value
// vector< double > isStraightEdge( nbEdges, 0 ); // criterion value
// // a0) evaluate continuity
// const double contiWgt = 0.5; // weight of continuity in the criterion
// multimap< int, TopoDS_Edge > continuity;
// for ( size_t i = 0; i < nbEdges; ++I )
// // a0) evaluate continuity
// const double contiWgt = 0.5; // weight of continuity in the criterion
// multimap< int, TopoDS_Edge > continuity;
// for ( size_t i = 0; i < nbEdges; ++I )
// {
// BRepAdaptor_Curve curve( allEdges[i] );
// GeomAbs_Shape C = GeomAbs_CN;
@ -604,21 +655,21 @@ namespace
bool divideMA( SMESH_MesherHelper& theHelper,
const SMESH_MAT2d::MedialAxis& theMA,
const vector<TopoDS_Edge>& theSinuEdges,
const size_t theSinuSide0Size,
const SinuousFace& theSinuFace,
SMESH_Algo* the1dAlgo,
vector<double>& theMAParams )
{
// check if all EDGEs of one size are meshed, then MA discretization is not needed
SMESH_Mesh* mesh = theHelper.GetMesh();
size_t nbComputedEdges[2] = { 0, 0 };
for ( size_t i = 1; i < theSinuEdges.size(); ++i )
{
bool isComputed = ( ! mesh->GetSubMesh( theSinuEdges[i] )->IsEmpty() );
nbComputedEdges[ i < theSinuSide0Size ] += isComputed;
}
if ( nbComputedEdges[0] == theSinuSide0Size ||
nbComputedEdges[1] == theSinuEdges.size() - theSinuSide0Size )
for ( size_t iS = 0; iS < 2; ++iS )
for ( size_t i = 0; i < theSinuFace._sinuSide[iS].size(); ++i )
{
bool isComputed = ( ! mesh->GetSubMesh( theSinuFace._sinuSide[iS][i] )->IsEmpty() );
nbComputedEdges[ iS ] += isComputed;
}
if ( nbComputedEdges[0] == theSinuFace._sinuSide[0].size() ||
nbComputedEdges[1] == theSinuFace._sinuSide[1].size() )
return true; // discretization is not needed
@ -631,13 +682,13 @@ namespace
// cout << "Write " << file << endl;
// 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 );
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 )
edge = theSinuEdges[i];
edge = theSinuFace._sinuEdges[i];
}
SMESH_Algo* algo = the1dAlgo;
@ -664,14 +715,13 @@ namespace
//================================================================================
/*!
* \brief Modifies division parameters on MA to make them coincide with projections
* of VERTEXes to MA for a given pair of opposite EDGEs
* \brief Select division parameters on MA and make them coincide at ends with
* projections of VERTEXes to MA for a given pair of opposite EDGEs
* \param [in] theEdgePairInd - index of the EDGE pair
* \param [in] theDivPoints - the BranchPoint's dividing MA into parts each
* corresponding to a unique pair of opposite EDGEs
* \param [in,out] theMAParams - the MA division parameters to modify
* \param [in,out] theParBeg - index of the 1st division point for the given EDGE pair
* \param [in,out] theParEnd - index of the last division point for the given EDGE pair
* \param [in] theMAParams - the MA division parameters
* \param [out] theSelectedMAParams - the selected MA parameters
* \return bool - is OK
*/
//================================================================================
@ -686,11 +736,49 @@ namespace
theSelectedMAParams = theMAParams;
return true;
}
if ( theEdgePairInd > theDivPoints.size() )
if ( theEdgePairInd > theDivPoints.size() || theMAParams.empty() )
return false;
// TODO
return false;
// find a range of params to copy
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;
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(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;
BRep_Tool::Range( theSinuEdges[ theNodePnt._edgeInd ], f,l );
const double tol = 1e-3 * ( l - f );
TopoDS_Vertex V;
if ( Abs( f - theNodePnt._u ))
if ( Abs( f - theNodePnt._u ) < tol )
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);
if ( !V.IsNull() )
@ -752,21 +846,25 @@ namespace
* \brief Add to the map of NodePoint's those on VERTEXes
* \param [in,out] theHelper - the helper
* \param [in] theMA - Medial Axis
* \param [in] theMinSegLen - minimal segment length
* \param [in] theDivPoints - projections of VERTEXes to MA
* \param [in] theSinuEdges - the sinuous EDGEs
* \param [in] theSideEdgeIDs - indices of sinuous EDGEs per side
* \param [in] theIsEdgeComputed - is sinuous EGDE is meshed
* \param [in,out] thePointsOnE - the map to fill
* \param [out] theNodes2Merge - the map of nodes to merge
*/
//================================================================================
bool projectVertices( SMESH_MesherHelper& theHelper,
//const double theMinSegLen,
const SMESH_MAT2d::MedialAxis& theMA,
const vector< SMESH_MAT2d::BranchPoint >& theDivPoints,
const vector<TopoDS_Edge>& theSinuEdges,
//const vector< int > theSideEdgeIDs[2],
const vector< Handle(Geom_Curve) >& theCurves,
const vector< bool >& theIsEdgeComputed,
map< double, pair< NodePoint, NodePoint > > & thePointsOnE)
map< double, pair< NodePoint, NodePoint > > & thePointsOnE,
TMergeMap& theNodes2Merge)
{
if ( theDivPoints.empty() )
return true;
@ -784,29 +882,85 @@ namespace
if ( !branch.getBoundaryPoints( theDivPoints[i], bp[0], bp[1] ))
return false;
NodePoint np[2] = { NodePoint( bp[0] ),
NodePoint( bp[1] ) };
NodePoint np[2] = { NodePoint( bp[0] ),
NodePoint( bp[1] )};
bool isVertex[2] = { findVertex( np[0], theSinuEdges, meshDS ),
findVertex( np[1], theSinuEdges, meshDS )};
map< double, pair< NodePoint, NodePoint > >::iterator u2NP =
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] )
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 )
continue;
// 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
// projection is wide enough; joining is done by setting the same node to the BoundaryPoint
// - a neighbor projection is merged this this one if it too close; a node of deleted
// 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 creating a node coincident with the
// 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
// 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;
}
@ -816,6 +970,7 @@ namespace
* \brief Divide the sinuous EDGEs by projecting the division point of Medial
* Axis to the EGDEs
* \param [in] theHelper - the helper
* \param [in] theMinSegLen - minimal segment length
* \param [in] theMA - the Medial Axis
* \param [in] theMAParams - parameters of division points of \a theMA
* \param [in] theSinuEdges - the EDGEs to make nodes on
@ -825,10 +980,10 @@ namespace
//================================================================================
bool computeSinuEdges( SMESH_MesherHelper& theHelper,
double /*theMinSegLen*/,
SMESH_MAT2d::MedialAxis& theMA,
vector<double>& theMAParams,
const vector<TopoDS_Edge>& theSinuEdges,
const size_t theSinuSide0Size)
SinuousFace& theSinuFace)
{
if ( theMA.getBranches().size() != 1 )
return false;
@ -842,6 +997,7 @@ namespace
SMESHDS_Mesh* meshDS = theHelper.GetMeshDS();
double f,l;
const vector< TopoDS_Edge >& theSinuEdges = theSinuFace._sinuEdges;
vector< Handle(Geom_Curve) > curves ( theSinuEdges.size() );
vector< int > edgeIDs( theSinuEdges.size() );
vector< bool > isComputed( theSinuEdges.size() );
@ -854,8 +1010,23 @@ namespace
SMESH_subMesh* sm = mesh->GetSubMesh( theSinuEdges[i] );
edgeIDs [i] = sm->GetId();
isComputed[i] = ( !sm->IsEmpty() );
// if ( isComputed[i] )
// hasComputed = true;
if ( isComputed[i] )
{
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];
@ -907,7 +1078,7 @@ namespace
branch.getParameter( brp, maParamLast );
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;
for ( ++u2n; u2n != u2nEnd; ++u2n )
{
@ -918,7 +1089,7 @@ namespace
if ( !branch.getParameter( brp, maParam ))
return false;
npN = NodePoint( u2n->second );
npN = NodePoint( u2n->second, u2n->first, iEdgeComputed );
npB = NodePoint( bndPnt );
pos = pointsOnE.insert( hint, make_pair( maParam, make_pair( np0, np1 )));
}
@ -950,7 +1121,8 @@ namespace
++iEdgePair;
}
if ( !projectVertices( theHelper, theMA, divPoints, theSinuEdges, isComputed, pointsOnE ))
if ( !projectVertices( theHelper, theMA, divPoints, theSinuEdges, curves,
isComputed, pointsOnE, theSinuFace._nodesToMerge ))
return false;
// create nodes
@ -1115,6 +1287,29 @@ namespace
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
@ -1181,7 +1376,7 @@ bool StdMeshers_QuadFromMedialAxis_1D2D::computeQuads( SMESH_MesherHelper&
StdMeshers_Quadrangle_2D::myProxyMesh.reset();
StdMeshers_Quadrangle_2D::myHelper = 0;
return ok;
}
@ -1200,37 +1395,49 @@ bool StdMeshers_QuadFromMedialAxis_1D2D::Compute(SMESH_Mesh& theMesh,
TopoDS_Face F = TopoDS::Face( theShape );
if ( F.Orientation() >= TopAbs_INTERNAL ) F.Orientation( TopAbs_FORWARD );
list< TopoDS_Edge > edges;
list< int > nbEdgesInWire;
int nbWire = SMESH_Block::GetOrderedEdges (F, edges, nbEdgesInWire);
SinuousFace sinuFace( F );
vector< TopoDS_Edge > sinuSide[2], shortSide[2];
if ( nbWire == 1 && getSinuousEdges( helper, F, edges, sinuSide, shortSide ))
_progress = 0.01;
if ( getSinuousEdges( helper, sinuFace ))
{
vector< TopoDS_Edge > sinuEdges = sinuSide[0];
sinuEdges.insert( sinuEdges.end(), sinuSide[1].begin(), sinuSide[1].end() );
if ( sinuEdges.size() > 2 )
return error(COMPERR_BAD_SHAPE, "Not yet supported case" );
_progress = 0.2;
double minSegLen = getMinSegLen( helper, sinuEdges );
SMESH_MAT2d::MedialAxis ma( F, sinuEdges, minSegLen, /*ignoreCorners=*/true );
// if ( sinuFace._sinuEdges.size() > 2 )
// 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 )
_regular1D = new Algo1D( _studyId, _gen );
_regular1D->SetSegmentLength( minSegLen );
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);
if ( !computeShortEdges( helper, shortSide[0], _regular1D ) ||
!computeShortEdges( helper, shortSide[1], _regular1D ))
_progress = 0.4;
if ( !computeShortEdges( helper, sinuFace._shortSide[0], _regular1D ) ||
!computeShortEdges( helper, sinuFace._shortSide[1], _regular1D ))
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 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");

View File

@ -106,7 +106,7 @@ StdMeshersGUI_DistrPreview::StdMeshersGUI_DistrPreview( QWidget* p, StdMeshers::
myDistr->attach( this );
QPen distrPen = QPen( Qt::blue, 1 );
QwtSymbol* distrSymbol = new QwtSymbol( QwtSymbol::XCross, QBrush( Qt::blue ),
QPen( Qt::blue ), QSize( 5, 5 ) );
QPen( Qt::blue ), QSize( 5, 5 ) );
myDistr->setPen( distrPen );
myDistr->setSymbol( distrSymbol );
if( Plot2d_QwtLegendLabel* anItem = getLegendLabel( myDistr ) ) {

View File

@ -57,7 +57,7 @@ public:
StdMeshersGUI_ObjectReferenceParamWdg( SUIT_SelectionFilter* filter,
QWidget* parent,
bool multiSelection=false
/* ,bool stretch=true*/);
/* ,bool stretch=true*/);
StdMeshersGUI_ObjectReferenceParamWdg( SMESH::MeshObjectType objType,
QWidget* parent,
bool multiSelection=false);