-// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
#include <Standard_Failure.hxx>
#include <Standard_ErrorHandler.hxx>
-#include <OSD_Parallel.hxx>
#include "SMESH_TryCatch.hxx" // include after OCCT headers!
using namespace std;
using namespace SMESH::Controls;
-namespace
-{
- template < class ELEM_SET >
- SMDS_ElemIteratorPtr elemSetIterator( const ELEM_SET& elements )
- {
- typedef SMDS_SetIterator
- < SMDS_pElement, typename ELEM_SET::const_iterator> TSetIterator;
- return SMDS_ElemIteratorPtr( new TSetIterator( elements.begin(), elements.end() ));
- }
-}
-
//=======================================================================
//function : SMESH_MeshEditor
//purpose :
void SMESH_MeshEditor::ClearLastCreated()
{
- myLastCreatedNodes.Clear();
- myLastCreatedElems.Clear();
+ SMESHUtils::FreeVector( myLastCreatedElems );
+ SMESHUtils::FreeVector( myLastCreatedNodes );
}
//================================================================================
myIsQuad = elem->IsQuadratic();
if ( myType == SMDSAbs_Volume && !basicOnly )
{
- vector<int > quant = static_cast<const SMDS_VtkVolume* >( elem )->GetQuantities();
+ vector<int> quant = static_cast<const SMDS_MeshVolume* >( elem )->GetQuantities();
myPolyhedQuantities.swap( quant );
}
}
default:;
}
- if ( e ) myLastCreatedElems.Append( e );
+ if ( e ) myLastCreatedElems.push_back( e );
return e;
}
int SMESH_MeshEditor::Remove (const list< int >& theIDs,
const bool isNodes )
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
SMESHDS_Mesh* aMesh = GetMeshDS();
set< SMESH_subMesh *> smmap;
}
else
{
- elemIt = elemSetIterator( elements );
+ elemIt = SMESHUtils::elemSetIterator( elements );
}
while ( elemIt->more() )
SMDS_ElemIteratorPtr it0D = n->GetInverseElementIterator( SMDSAbs_0DElement );
if ( duplicateElements || !it0D->more() )
{
- myLastCreatedElems.Append( GetMeshDS()->Add0DElement( n ));
- all0DElems.insert( myLastCreatedElems.Last() );
+ myLastCreatedElems.push_back( GetMeshDS()->Add0DElement( n ));
+ all0DElems.insert( myLastCreatedElems.back() );
}
while ( it0D->more() )
all0DElems.insert( it0D->next() );
int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
SMESHDS_Mesh * aMesh = GetMeshDS();
if ( aMesh->ShapeToMesh().IsNull() )
aNodes[5] = nd2;
}
-//=======================================================================
-//function : nbEdgeConnectivity
-//purpose : return number of the edges connected with the theNode.
-// if theEdges has connections with the other type of the
-// elements, return -1
-//=======================================================================
-
-static int nbEdgeConnectivity(const SMDS_MeshNode* theNode)
-{
- // SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator();
- // int nb=0;
- // while(elemIt->more()) {
- // elemIt->next();
- // nb++;
- // }
- // return nb;
- return theNode->NbInverseElements();
-}
-
//=======================================================================
//function : getNodesFromTwoTria
//purpose :
bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
const SMDS_MeshElement * theTria2 )
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
- if (!theTria1 || !theTria2)
+ if ( !theTria1 || !theTria2 ||
+ !dynamic_cast<const SMDS_MeshCell*>( theTria1 ) ||
+ !dynamic_cast<const SMDS_MeshCell*>( theTria2 ) ||
+ theTria1->GetType() != SMDSAbs_Face ||
+ theTria2->GetType() != SMDSAbs_Face )
return false;
- const SMDS_VtkFace* F1 = dynamic_cast<const SMDS_VtkFace*>( theTria1 );
- if (!F1) return false;
- const SMDS_VtkFace* F2 = dynamic_cast<const SMDS_VtkFace*>( theTria2 );
- if (!F2) return false;
if ((theTria1->GetEntityType() == SMDSEntity_Triangle) &&
- (theTria2->GetEntityType() == SMDSEntity_Triangle)) {
-
+ (theTria2->GetEntityType() == SMDSEntity_Triangle))
+ {
// 1 +--+ A theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
// | /| theTria2: ( B A 2 ) B->1 ( 1 A 2 ) |\ |
// |/ | | \|
gp_Pnt xyz;
if ( F.IsNull() )
{
- xyz = ( SMESH_TNodeXYZ( nodes[3] ) +
- SMESH_TNodeXYZ( nodes[4] ) +
- SMESH_TNodeXYZ( nodes[5] )) / 3.;
+ xyz = ( SMESH_NodeXYZ( nodes[3] ) +
+ SMESH_NodeXYZ( nodes[4] ) +
+ SMESH_NodeXYZ( nodes[5] )) / 3.;
}
else
{
bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1,
const SMDS_MeshNode * theNode2)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
const SMDS_MeshElement *tr1, *tr2;
if ( !findTriangles( theNode1, theNode2, tr1, tr2 ))
return false;
- const SMDS_VtkFace* F1 = dynamic_cast<const SMDS_VtkFace*>( tr1 );
- if (!F1) return false;
- const SMDS_VtkFace* F2 = dynamic_cast<const SMDS_VtkFace*>( tr2 );
- if (!F2) return false;
+ if ( !dynamic_cast<const SMDS_MeshCell*>( tr1 ) ||
+ !dynamic_cast<const SMDS_MeshCell*>( tr2 ))
+ return false;
+
if ((tr1->GetEntityType() == SMDSEntity_Triangle) &&
(tr2->GetEntityType() == SMDSEntity_Triangle)) {
bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
const SMDS_MeshNode * theNode2)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
const SMDS_MeshElement *tr1, *tr2;
if ( !findTriangles( theNode1, theNode2, tr1, tr2 ))
return false;
- const SMDS_VtkFace* F1 = dynamic_cast<const SMDS_VtkFace*>( tr1 );
- if (!F1) return false;
- const SMDS_VtkFace* F2 = dynamic_cast<const SMDS_VtkFace*>( tr2 );
- if (!F2) return false;
+ if ( !dynamic_cast<const SMDS_MeshCell*>( tr1 ) ||
+ !dynamic_cast<const SMDS_MeshCell*>( tr2 ))
+ return false;
+
SMESHDS_Mesh * aMesh = GetMeshDS();
if ((tr1->GetEntityType() == SMDSEntity_Triangle) &&
- (tr2->GetEntityType() == SMDSEntity_Triangle)) {
-
+ (tr2->GetEntityType() == SMDSEntity_Triangle))
+ {
const SMDS_MeshNode* aNodes [ 4 ];
if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 ))
return false;
const SMDS_MeshElement* newElem = 0;
newElem = aMesh->AddFace( aNodes[0], aNodes[1], aNodes[2], aNodes[3] );
- myLastCreatedElems.Append(newElem);
+ myLastCreatedElems.push_back(newElem);
AddToSameGroups( newElem, tr1, aMesh );
int aShapeId = tr1->getshapeId();
if ( aShapeId )
- {
- aMesh->SetMeshElementOnShape( newElem, aShapeId );
- }
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+
aMesh->RemoveElement( tr1 );
aMesh->RemoveElement( tr2 );
const SMDS_MeshElement* newElem = 0;
newElem = aMesh->AddFace( aNodes[0], aNodes[1], aNodes[2], aNodes[3],
aNodes[4], aNodes[5], aNodes[6], aNodes[7]);
- myLastCreatedElems.Append(newElem);
+ myLastCreatedElems.push_back(newElem);
AddToSameGroups( newElem, tr1, aMesh );
int aShapeId = tr1->getshapeId();
if ( aShapeId )
- {
- aMesh->SetMeshElementOnShape( newElem, aShapeId );
- }
+ {
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ }
aMesh->RemoveElement( tr1 );
aMesh->RemoveElement( tr2 );
bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
if (!theElem)
return false;
const SMDSAbs_EntityType geomType = theElem->GetEntityType();
if ( geomType == SMDSEntity_Polyhedra ) // polyhedron
{
- const SMDS_VtkVolume* aPolyedre =
- dynamic_cast<const SMDS_VtkVolume*>( theElem );
+ const SMDS_MeshVolume* aPolyedre = SMDS_Mesh::DownCast< SMDS_MeshVolume >( theElem );
if (!aPolyedre) {
MESSAGE("Warning: bad volumic element");
return false;
if ( theFaces.empty() )
{
- SMDS_FaceIteratorPtr fIt = GetMeshDS()->facesIterator(/*idInceasingOrder=*/true);
+ SMDS_FaceIteratorPtr fIt = GetMeshDS()->facesIterator(/*idInceasingOrder=true*/);
while ( fIt->more() )
theFaces.insert( theFaces.end(), fIt->next() );
}
if ( theFaces.empty() )
faceIt = GetMeshDS()->elementsIterator( SMDSAbs_Face );
else
- faceIt = elemSetIterator( theFaces );
+ faceIt = SMESHUtils::elemSetIterator( theFaces );
vector< const SMDS_MeshNode* > faceNodes;
TIDSortedElemSet checkedVolumes;
bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
SMESH::Controls::NumericalFunctorPtr theCrit)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
if ( !theCrit.get() )
return false;
- SMESHDS_Mesh * aMesh = GetMeshDS();
-
+ SMESHDS_Mesh * aMesh = GetMeshDS();
Handle(Geom_Surface) surface;
SMESH_MesherHelper helper( *GetMesh() );
+ myLastCreatedElems.reserve( theElems.size() * 2 );
+
TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
{
const SMDS_MeshElement* newElem1 = 0;
const SMDS_MeshElement* newElem2 = 0;
- if ( !elem->IsQuadratic() ) // split liner quadrangle
+ if ( !elem->IsQuadratic() ) // split linear quadrangle
{
// for MaxElementLength2D functor we return minimum diagonal for splitting,
// because aBadRate1=2*len(diagonal 1-3); aBadRate2=2*len(diagonal 2-4)
// care of a new element
- myLastCreatedElems.Append(newElem1);
- myLastCreatedElems.Append(newElem2);
+ myLastCreatedElems.push_back(newElem1);
+ myLastCreatedElems.push_back(newElem2);
AddToSameGroups( newElem1, elem, aMesh );
AddToSameGroups( newElem2, elem, aMesh );
void SMESH_MeshEditor::QuadTo4Tri (TIDSortedElemSet & theElems)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
+ myLastCreatedElems.reserve( theElems.size() * 4 );
SMESH_MesherHelper helper( *GetMesh() );
helper.SetElementsOnShape( true );
SMDS_ElemIteratorPtr faceIt;
if ( theElems.empty() ) faceIt = GetMeshDS()->elementsIterator(SMDSAbs_Face);
- else faceIt = elemSetIterator( theElems );
+ else faceIt = SMESHUtils::elemSetIterator( theElems );
bool checkUV;
gp_XY uv [9]; uv[8] = gp_XY(0,0);
if ( F.IsNull() )
{
for ( ; iN < nodes.size(); ++iN )
- xyz[ iN ] = SMESH_TNodeXYZ( nodes[ iN ] );
+ xyz[ iN ] = SMESH_NodeXYZ( nodes[ iN ] );
for ( ; iN < 8; ++iN ) // mid-side points of a linear qudrangle
xyz[ iN ] = 0.5 * ( xyz[ iN - 4 ] + xyz[( iN - 3 )%4 ] );
nCentral = helper.AddNode( xyz[8].X(), xyz[8].Y(), xyz[8].Z(), /*id=*/0,
uv[8].X(), uv[8].Y() );
- myLastCreatedNodes.Append( nCentral );
+ myLastCreatedNodes.push_back( nCentral );
}
// create 4 triangles
nodes[(i+1)%4],
nCentral );
ReplaceElemInGroups( tria, quad, GetMeshDS() );
- myLastCreatedElems.Append( tria );
+ myLastCreatedElems.push_back( tria );
}
}
}
int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement* theQuad,
SMESH::Controls::NumericalFunctorPtr theCrit)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
if (!theCrit.get())
return -1;
volTool.GetBaryCenter( bc[0], bc[1], bc[2] );
SMDS_MeshNode* gcNode = helper.AddNode( bc[0], bc[1], bc[2] );
nodes.push_back( gcNode );
- newNodes.Append( gcNode );
+ newNodes.push_back( gcNode );
}
if ( !splitMethod._faceBaryNode.empty() )
{
if ( !f_n->second )
{
volTool.GetFaceBaryCenter( iF_n->first, bc[0], bc[1], bc[2] );
- newNodes.Append( f_n->second = helper.AddNode( bc[0], bc[1], bc[2] ));
+ newNodes.push_back( f_n->second = helper.AddNode( bc[0], bc[1], bc[2] ));
}
nodes.push_back( iF_n->second = f_n->second );
}
const int* volConn = splitMethod._connectivity;
if ( splitMethod._nbCorners == 4 ) // tetra
for ( int i = 0; i < splitMethod._nbSplits; ++i, volConn += splitMethod._nbCorners )
- newElems.Append( splitVols[ i ] = helper.AddVolume( nodes[ volConn[0] ],
- nodes[ volConn[1] ],
- nodes[ volConn[2] ],
- nodes[ volConn[3] ]));
+ newElems.push_back( splitVols[ i ] = helper.AddVolume( nodes[ volConn[0] ],
+ nodes[ volConn[1] ],
+ nodes[ volConn[2] ],
+ nodes[ volConn[3] ]));
else // prisms
for ( int i = 0; i < splitMethod._nbSplits; ++i, volConn += splitMethod._nbCorners )
- newElems.Append( splitVols[ i ] = helper.AddVolume( nodes[ volConn[0] ],
- nodes[ volConn[1] ],
- nodes[ volConn[2] ],
- nodes[ volConn[3] ],
- nodes[ volConn[4] ],
- nodes[ volConn[5] ]));
+ newElems.push_back( splitVols[ i ] = helper.AddVolume( nodes[ volConn[0] ],
+ nodes[ volConn[1] ],
+ nodes[ volConn[2] ],
+ nodes[ volConn[3] ],
+ nodes[ volConn[4] ],
+ nodes[ volConn[5] ]));
ReplaceElemInGroups( elem, splitVols, GetMeshDS() );
if ( fSubMesh ) // update position of the bary node on geometry
{
if ( subMesh )
- subMesh->RemoveNode( baryNode, false );
+ subMesh->RemoveNode( baryNode );
GetMeshDS()->SetNodeOnFace( baryNode, fSubMesh->GetID() );
const TopoDS_Shape& s = GetMeshDS()->IndexToShape( fSubMesh->GetID() );
if ( !s.IsNull() && s.ShapeType() == TopAbs_FACE )
gp_XY uv( 1e100, 1e100 );
double distXYZ[4];
if ( !fHelper.CheckNodeUV( TopoDS::Face( s ), baryNode,
- uv, /*tol=*/1e-7, /*force=*/true, distXYZ ) &&
+ uv, /*tol=*/1e-7, /*force=*/true, distXYZ ) &&
uv.X() < 1e100 )
{
// node is too far from the surface
if ( !triangles[ i ]) continue;
if ( fSubMesh )
fSubMesh->AddElement( triangles[ i ]);
- newElems.Append( triangles[ i ]);
+ newElems.push_back( triangles[ i ]);
}
ReplaceElemInGroups( face, triangles, GetMeshDS() );
GetMeshDS()->RemoveFreeElement( face, fSubMesh, /*fromGroups=*/false );
const gp_Ax1& theFacetNormal,
TFacetOfElem & theFacets)
{
- #define THIS_METHOD "SMESH_MeshEditor::GetHexaFacetsToSplit(): "
+#define THIS_METHOD "SMESH_MeshEditor::GetHexaFacetsToSplit(): "
// Find a hexa closest to the location of theFacetNormal
bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
const bool the13Diag)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
-
- SMESHDS_Mesh * aMesh = GetMeshDS();
+ ClearLastCreated();
+ myLastCreatedElems.reserve( theElems.size() * 2 );
+ SMESHDS_Mesh * aMesh = GetMeshDS();
Handle(Geom_Surface) surface;
SMESH_MesherHelper helper( *GetMesh() );
newElem1 = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
newElem2 = aMesh->AddFace( aNodes[3], aNodes[1], aNodes[2] );
}
- myLastCreatedElems.Append(newElem1);
- myLastCreatedElems.Append(newElem2);
+ myLastCreatedElems.push_back(newElem1);
+ myLastCreatedElems.push_back(newElem2);
// put a new triangle on the same shape and add to the same groups
if ( aShapeId )
{
centrNode = helper.GetCentralNode( aNodes[0], aNodes[1], aNodes[2], aNodes[3],
aNodes[4], aNodes[5], aNodes[6], aNodes[7],
surface.IsNull() );
- myLastCreatedNodes.Append(centrNode);
+ myLastCreatedNodes.push_back(centrNode);
}
// create a new element
newElem2 = aMesh->AddFace(aNodes[3], aNodes[1], aNodes[2],
centrNode, aNodes[5], aNodes[6] );
}
- myLastCreatedElems.Append(newElem1);
- myLastCreatedElems.Append(newElem2);
+ myLastCreatedElems.push_back(newElem1);
+ myLastCreatedElems.push_back(newElem2);
// put a new triangle on the same shape and add to the same groups
if ( aShapeId )
{
SMESH::Controls::NumericalFunctorPtr theCrit,
const double theMaxAngle)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
+ myLastCreatedElems.reserve( theElems.size() / 2 );
if ( !theCrit.get() )
return false;
{
const SMDS_MeshElement* newElem = 0;
newElem = aMesh->AddFace(n12[0], n12[1], n12[2], n12[3] );
- myLastCreatedElems.Append(newElem);
+ myLastCreatedElems.push_back(newElem);
AddToSameGroups( newElem, tr1, aMesh );
int aShapeId = tr1->getshapeId();
if ( aShapeId )
else
newElem = aMesh->AddFace(aNodes[0], aNodes[1], aNodes[2], aNodes[3],
aNodes[4], aNodes[5], aNodes[6], aNodes[7]);
- myLastCreatedElems.Append(newElem);
+ myLastCreatedElems.push_back(newElem);
AddToSameGroups( newElem, tr1, aMesh );
int aShapeId = tr1->getshapeId();
if ( aShapeId )
if ( tr1->NbNodes() == 3 ) {
const SMDS_MeshElement* newElem = 0;
newElem = aMesh->AddFace(n13[0], n13[1], n13[2], n13[3] );
- myLastCreatedElems.Append(newElem);
+ myLastCreatedElems.push_back(newElem);
AddToSameGroups( newElem, tr1, aMesh );
int aShapeId = tr1->getshapeId();
if ( aShapeId )
else
newElem = aMesh->AddFace(aNodes[0], aNodes[1], aNodes[2], aNodes[3],
aNodes[4], aNodes[5], aNodes[6], aNodes[7]);
- myLastCreatedElems.Append(newElem);
+ myLastCreatedElems.push_back(newElem);
AddToSameGroups( newElem, tr1, aMesh );
int aShapeId = tr1->getshapeId();
if ( aShapeId )
return true;
}
-
-/*#define DUMPSO(txt) \
-// cout << txt << endl;
-//=============================================================================
-//
-//
-//
-//=============================================================================
-static void swap( int i1, int i2, int idNodes[], gp_Pnt P[] )
-{
-if ( i1 == i2 )
-return;
-int tmp = idNodes[ i1 ];
-idNodes[ i1 ] = idNodes[ i2 ];
-idNodes[ i2 ] = tmp;
-gp_Pnt Ptmp = P[ i1 ];
-P[ i1 ] = P[ i2 ];
-P[ i2 ] = Ptmp;
-DUMPSO( i1 << "(" << idNodes[ i2 ] << ") <-> " << i2 << "(" << idNodes[ i1 ] << ")");
-}
-
-//=======================================================================
-//function : SortQuadNodes
-//purpose : Set 4 nodes of a quadrangle face in a good order.
-// Swap 1<->2 or 2<->3 nodes and correspondingly return
-// 1 or 2 else 0.
-//=======================================================================
-
-int SMESH_MeshEditor::SortQuadNodes (const SMDS_Mesh * theMesh,
-int idNodes[] )
-{
- gp_Pnt P[4];
- int i;
- for ( i = 0; i < 4; i++ ) {
- const SMDS_MeshNode *n = theMesh->FindNode( idNodes[i] );
- if ( !n ) return 0;
- P[ i ].SetCoord( n->X(), n->Y(), n->Z() );
- }
-
- gp_Vec V1(P[0], P[1]);
- gp_Vec V2(P[0], P[2]);
- gp_Vec V3(P[0], P[3]);
-
- gp_Vec Cross1 = V1 ^ V2;
- gp_Vec Cross2 = V2 ^ V3;
-
- i = 0;
- if (Cross1.Dot(Cross2) < 0)
- {
- Cross1 = V2 ^ V1;
- Cross2 = V1 ^ V3;
-
- if (Cross1.Dot(Cross2) < 0)
- i = 2;
- else
- i = 1;
- swap ( i, i + 1, idNodes, P );
-
- // for ( int ii = 0; ii < 4; ii++ ) {
- // const SMDS_MeshNode *n = theMesh->FindNode( idNodes[ii] );
- // DUMPSO( ii << "(" << idNodes[ii] <<") : "<<n->X()<<" "<<n->Y()<<" "<<n->Z());
- // }
- }
- return i;
-}
-
-//=======================================================================
-//function : SortHexaNodes
-//purpose : Set 8 nodes of a hexahedron in a good order.
-// Return success status
-//=======================================================================
-
-bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh,
- int idNodes[] )
-{
- gp_Pnt P[8];
- int i;
- DUMPSO( "INPUT: ========================================");
- for ( i = 0; i < 8; i++ ) {
- const SMDS_MeshNode *n = theMesh->FindNode( idNodes[i] );
- if ( !n ) return false;
- P[ i ].SetCoord( n->X(), n->Y(), n->Z() );
- DUMPSO( i << "(" << idNodes[i] <<") : "<<n->X()<<" "<<n->Y()<<" "<<n->Z());
- }
- DUMPSO( "========================================");
-
-
- set<int> faceNodes; // ids of bottom face nodes, to be found
- set<int> checkedId1; // ids of tried 2-nd nodes
- Standard_Real leastDist = DBL_MAX; // dist of the 4-th node from 123 plane
- const Standard_Real tol = 1.e-6; // tolerance to find nodes in plane
- int iMin, iLoop1 = 0;
-
- // Loop to try the 2-nd nodes
-
- while ( leastDist > DBL_MIN && ++iLoop1 < 8 )
- {
- // Find not checked 2-nd node
- for ( i = 1; i < 8; i++ )
- if ( checkedId1.find( idNodes[i] ) == checkedId1.end() ) {
- int id1 = idNodes[i];
- swap ( 1, i, idNodes, P );
- checkedId1.insert ( id1 );
- break;
- }
-
- // Find the 3-d node so that 1-2-3 triangle to be on a hexa face,
- // ie that all but meybe one (id3 which is on the same face) nodes
- // lay on the same side from the triangle plane.
-
- bool manyInPlane = false; // more than 4 nodes lay in plane
- int iLoop2 = 0;
- while ( ++iLoop2 < 6 ) {
-
- // get 1-2-3 plane coeffs
- Standard_Real A, B, C, D;
- gp_Vec N = gp_Vec (P[0], P[1]).Crossed( gp_Vec (P[0], P[2]) );
- if ( N.SquareMagnitude() > gp::Resolution() )
- {
- gp_Pln pln ( P[0], N );
- pln.Coefficients( A, B, C, D );
-
- // find the node (iMin) closest to pln
- Standard_Real dist[ 8 ], minDist = DBL_MAX;
- set<int> idInPln;
- for ( i = 3; i < 8; i++ ) {
- dist[i] = A * P[i].X() + B * P[i].Y() + C * P[i].Z() + D;
- if ( fabs( dist[i] ) < minDist ) {
- minDist = fabs( dist[i] );
- iMin = i;
- }
- if ( fabs( dist[i] ) <= tol )
- idInPln.insert( idNodes[i] );
- }
-
- // there should not be more than 4 nodes in bottom plane
- if ( idInPln.size() > 1 )
- {
- DUMPSO( "### idInPln.size() = " << idInPln.size());
- // idInPlane does not contain the first 3 nodes
- if ( manyInPlane || idInPln.size() == 5)
- return false; // all nodes in one plane
- manyInPlane = true;
-
- // set the 1-st node to be not in plane
- for ( i = 3; i < 8; i++ ) {
- if ( idInPln.find( idNodes[ i ] ) == idInPln.end() ) {
- DUMPSO( "### Reset 0-th node");
- swap( 0, i, idNodes, P );
- break;
- }
- }
-
- // reset to re-check second nodes
- leastDist = DBL_MAX;
- faceNodes.clear();
- checkedId1.clear();
- iLoop1 = 0;
- break; // from iLoop2;
- }
-
- // check that the other 4 nodes are on the same side
- bool sameSide = true;
- bool isNeg = dist[ iMin == 3 ? 4 : 3 ] <= 0.;
- for ( i = 3; sameSide && i < 8; i++ ) {
- if ( i != iMin )
- sameSide = ( isNeg == dist[i] <= 0.);
- }
-
- // keep best solution
- if ( sameSide && minDist < leastDist ) {
- leastDist = minDist;
- faceNodes.clear();
- faceNodes.insert( idNodes[ 1 ] );
- faceNodes.insert( idNodes[ 2 ] );
- faceNodes.insert( idNodes[ iMin ] );
- DUMPSO( "loop " << iLoop2 << " id2 " << idNodes[ 1 ] << " id3 " << idNodes[ 2 ]
- << " leastDist = " << leastDist);
- if ( leastDist <= DBL_MIN )
- break;
- }
- }
-
- // set next 3-d node to check
- int iNext = 2 + iLoop2;
- if ( iNext < 8 ) {
- DUMPSO( "Try 2-nd");
- swap ( 2, iNext, idNodes, P );
- }
- } // while ( iLoop2 < 6 )
- } // iLoop1
-
- if ( faceNodes.empty() ) return false;
-
- // Put the faceNodes in proper places
- for ( i = 4; i < 8; i++ ) {
- if ( faceNodes.find( idNodes[ i ] ) != faceNodes.end() ) {
- // find a place to put
- int iTo = 1;
- while ( faceNodes.find( idNodes[ iTo ] ) != faceNodes.end() )
- iTo++;
- DUMPSO( "Set faceNodes");
- swap ( iTo, i, idNodes, P );
- }
- }
-
-
- // Set nodes of the found bottom face in good order
- DUMPSO( " Found bottom face: ");
- i = SortQuadNodes( theMesh, idNodes );
- if ( i ) {
- gp_Pnt Ptmp = P[ i ];
- P[ i ] = P[ i+1 ];
- P[ i+1 ] = Ptmp;
- }
- // else
- // for ( int ii = 0; ii < 4; ii++ ) {
- // const SMDS_MeshNode *n = theMesh->FindNode( idNodes[ii] );
- // DUMPSO( ii << "(" << idNodes[ii] <<") : "<<n->X()<<" "<<n->Y()<<" "<<n->Z());
- // }
-
- // Gravity center of the top and bottom faces
- gp_Pnt aGCb = ( P[0].XYZ() + P[1].XYZ() + P[2].XYZ() + P[3].XYZ() ) / 4.;
- gp_Pnt aGCt = ( P[4].XYZ() + P[5].XYZ() + P[6].XYZ() + P[7].XYZ() ) / 4.;
-
- // Get direction from the bottom to the top face
- gp_Vec upDir ( aGCb, aGCt );
- Standard_Real upDirSize = upDir.Magnitude();
- if ( upDirSize <= gp::Resolution() ) return false;
- upDir / upDirSize;
-
- // Assure that the bottom face normal points up
- gp_Vec Nb = gp_Vec (P[0], P[1]).Crossed( gp_Vec (P[0], P[2]) );
- Nb += gp_Vec (P[0], P[2]).Crossed( gp_Vec (P[0], P[3]) );
- if ( Nb.Dot( upDir ) < 0 ) {
- DUMPSO( "Reverse bottom face");
- swap( 1, 3, idNodes, P );
- }
-
- // Find 5-th node - the one closest to the 1-st among the last 4 nodes.
- Standard_Real minDist = DBL_MAX;
- for ( i = 4; i < 8; i++ ) {
- // projection of P[i] to the plane defined by P[0] and upDir
- gp_Pnt Pp = P[i].Translated( upDir * ( upDir.Dot( gp_Vec( P[i], P[0] ))));
- Standard_Real sqDist = P[0].SquareDistance( Pp );
- if ( sqDist < minDist ) {
- minDist = sqDist;
- iMin = i;
- }
- }
- DUMPSO( "Set 4-th");
- swap ( 4, iMin, idNodes, P );
-
- // Set nodes of the top face in good order
- DUMPSO( "Sort top face");
- i = SortQuadNodes( theMesh, &idNodes[4] );
- if ( i ) {
- i += 4;
- gp_Pnt Ptmp = P[ i ];
- P[ i ] = P[ i+1 ];
- P[ i+1 ] = Ptmp;
- }
-
- // Assure that direction of the top face normal is from the bottom face
- gp_Vec Nt = gp_Vec (P[4], P[5]).Crossed( gp_Vec (P[4], P[6]) );
- Nt += gp_Vec (P[4], P[6]).Crossed( gp_Vec (P[4], P[7]) );
- if ( Nt.Dot( upDir ) < 0 ) {
- DUMPSO( "Reverse top face");
- swap( 5, 7, idNodes, P );
- }
-
- // DUMPSO( "OUTPUT: ========================================");
- // for ( i = 0; i < 8; i++ ) {
- // float *p = ugrid->GetPoint(idNodes[i]);
- // DUMPSO( i << "(" << idNodes[i] << ") : " << p[0] << " " << p[1] << " " << p[2]);
- // }
-
- return true;
-}*/
-
//================================================================================
/*!
* \brief Return nodes linked to the given one
double theTgtAspectRatio,
const bool the2D)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
if ( theTgtAspectRatio < 1.0 )
theTgtAspectRatio = 1.0;
// }
if ( project ) { // compute new UV
gp_XY newUV;
- gp_Pnt pNode = SMESH_TNodeXYZ( node );
+ gp_Pnt pNode = SMESH_NodeXYZ( node );
if ( !getClosestUV( projector, pNode, newUV )) {
MESSAGE("Node Projection Failed " << node);
}
// if ( posType != SMDS_TOP_3DSPACE )
// dist2 = pNode.SquareDistance( surface->Value( newUV.X(), newUV.Y() ));
// if ( dist2 < dist1 )
- uv = newUV;
+ uv = newUV;
}
}
// store UV in the map
const SMDS_MeshElement* QF = *elemIt;
if ( QF->IsQuadratic() )
{
- nodes.assign( SMDS_MeshElement::iterator( QF->interlacedNodesElemIterator() ),
+ nodes.assign( SMDS_MeshElement::iterator( QF->interlacedNodesIterator() ),
SMDS_MeshElement::iterator() );
nodes.push_back( nodes[0] );
gp_Pnt xyz;
xyz = surface->Value( uv.X(), uv.Y() );
}
else {
- xyz = 0.5 * ( SMESH_TNodeXYZ( nodes[i-1] ) + SMESH_TNodeXYZ( nodes[i+1] ));
+ xyz = 0.5 * ( SMESH_NodeXYZ( nodes[i-1] ) + SMESH_NodeXYZ( nodes[i+1] ));
}
- if (( SMESH_TNodeXYZ( nodes[i] ) - xyz.XYZ() ).Modulus() > disttol )
+ if (( SMESH_NodeXYZ( nodes[i] ) - xyz.XYZ() ).Modulus() > disttol )
// we have to move a medium node
aMesh->MoveNode( nodes[i], xyz.X(), xyz.Y(), xyz.Z() );
}
const int iNotSame)
{
- SMESH_TNodeXYZ pP = prevNodes[ iNotSame ];
- SMESH_TNodeXYZ pN = nextNodes[ iNotSame ];
+ SMESH_NodeXYZ pP = prevNodes[ iNotSame ];
+ SMESH_NodeXYZ pN = nextNodes[ iNotSame ];
gp_XYZ extrDir( pN - pP ), faceNorm;
SMESH_MeshAlgos::FaceNormal( face, faceNorm, /*normalized=*/false );
break;
}
case SMDSEntity_Triangle: // TRIANGLE --->
- {
- if ( nbDouble > 0 ) break;
- if ( nbSame == 0 ) // ---> pentahedron
- aNewElem = aMesh->AddVolume (prevNod[ 0 ], prevNod[ 1 ], prevNod[ 2 ],
- nextNod[ 0 ], nextNod[ 1 ], nextNod[ 2 ] );
-
- else if ( nbSame == 1 ) // ---> pyramid
- aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
- nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
- nextNod[ iSameNode ]);
-
- else // 2 same nodes: ---> tetrahedron
- aNewElem = aMesh->AddVolume (prevNod[ 0 ], prevNod[ 1 ], prevNod[ 2 ],
- nextNod[ iNotSameNode ]);
- break;
- }
+ {
+ if ( nbDouble > 0 ) break;
+ if ( nbSame == 0 ) // ---> pentahedron
+ aNewElem = aMesh->AddVolume (prevNod[ 0 ], prevNod[ 1 ], prevNod[ 2 ],
+ nextNod[ 0 ], nextNod[ 1 ], nextNod[ 2 ] );
+
+ else if ( nbSame == 1 ) // ---> pyramid
+ aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
+ nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
+ nextNod[ iSameNode ]);
+
+ else // 2 same nodes: ---> tetrahedron
+ aNewElem = aMesh->AddVolume (prevNod[ 0 ], prevNod[ 1 ], prevNod[ 2 ],
+ nextNod[ iNotSameNode ]);
+ break;
+ }
case SMDSEntity_Quad_Edge: // sweep quadratic EDGE --->
+ {
+ if ( nbSame == 2 )
+ return;
+ if ( nbDouble+nbSame == 2 )
{
- if ( nbSame == 2 )
- return;
- if ( nbDouble+nbSame == 2 )
- {
- if(nbSame==0) { // ---> quadratic quadrangle
- aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[1], nextNod[0],
- prevNod[2], midlNod[1], nextNod[2], midlNod[0]);
- }
- else { //(nbSame==1) // ---> quadratic triangle
- if(sames[0]==2) {
- return; // medium node on axis
- }
- else if(sames[0]==0)
- aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[1],
- prevNod[2], midlNod[1], nextNod[2] );
- else // sames[0]==1
- aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[0],
- prevNod[2], nextNod[2], midlNod[0]);
- }
+ if(nbSame==0) { // ---> quadratic quadrangle
+ aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[1], nextNod[0],
+ prevNod[2], midlNod[1], nextNod[2], midlNod[0]);
}
- else if ( nbDouble == 3 )
- {
- if ( nbSame == 0 ) { // ---> bi-quadratic quadrangle
- aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[1], nextNod[0],
- prevNod[2], midlNod[1], nextNod[2], midlNod[0], midlNod[2]);
+ else { //(nbSame==1) // ---> quadratic triangle
+ if(sames[0]==2) {
+ return; // medium node on axis
}
+ else if(sames[0]==0)
+ aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[1],
+ prevNod[2], midlNod[1], nextNod[2] );
+ else // sames[0]==1
+ aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[0],
+ prevNod[2], nextNod[2], midlNod[0]);
+ }
+ }
+ else if ( nbDouble == 3 )
+ {
+ if ( nbSame == 0 ) { // ---> bi-quadratic quadrangle
+ aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[1], nextNod[0],
+ prevNod[2], midlNod[1], nextNod[2], midlNod[0], midlNod[2]);
}
- else
- return;
- break;
}
+ else
+ return;
+ break;
+ }
case SMDSEntity_Quadrangle: { // sweep QUADRANGLE --->
if ( nbDouble > 0 ) break;
if ( aNewElem ) {
newElems.push_back( aNewElem );
- myLastCreatedElems.Append(aNewElem);
- srcElements.Append( elem );
+ myLastCreatedElems.push_back(aNewElem);
+ srcElements.push_back( elem );
}
// set new prev nodes
if ( !isQuadratic ) {
if ( !aMesh->FindEdge( vecNewNodes[ 0 ]->second.back(),
vecNewNodes[ 1 ]->second.back())) {
- myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
- vecNewNodes[ 1 ]->second.back()));
- srcElements.Append( elem );
+ myLastCreatedElems.push_back(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
+ vecNewNodes[ 1 ]->second.back()));
+ srcElements.push_back( elem );
}
}
else {
if ( !aMesh->FindEdge( vecNewNodes[ 0 ]->second.back(),
vecNewNodes[ 1 ]->second.back(),
vecNewNodes[ 2 ]->second.back())) {
- myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
- vecNewNodes[ 1 ]->second.back(),
- vecNewNodes[ 2 ]->second.back()));
- srcElements.Append( elem );
+ myLastCreatedElems.push_back(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
+ vecNewNodes[ 1 ]->second.back(),
+ vecNewNodes[ 2 ]->second.back()));
+ srcElements.push_back( elem );
}
}
}
// make a new edge and a ceiling for a new edge
const SMDS_MeshElement* edge;
if ( ! ( edge = aMesh->FindEdge( n1, n2 ))) {
- myLastCreatedElems.Append( edge = aMesh->AddEdge( n1, n2 )); // free link edge
- srcElements.Append( myLastCreatedElems.Last() );
+ myLastCreatedElems.push_back( edge = aMesh->AddEdge( n1, n2 )); // free link edge
+ srcElements.push_back( myLastCreatedElems.back() );
}
n1 = vecNewNodes[ iNode ]->second.back();
n2 = vecNewNodes[ iNext ]->second.back();
if ( !aMesh->FindEdge( n1, n2 )) {
- myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 )); // new edge ceiling
- srcElements.Append( edge );
+ myLastCreatedElems.push_back(aMesh->AddEdge( n1, n2 )); // new edge ceiling
+ srcElements.push_back( edge );
}
}
}
// make an edge and a ceiling for a new edge
// find medium node
if ( !aMesh->FindEdge( n1, n2, n3 )) {
- myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 )); // free link edge
- srcElements.Append( elem );
+ myLastCreatedElems.push_back(aMesh->AddEdge( n1, n2, n3 )); // free link edge
+ srcElements.push_back( elem );
}
n1 = vecNewNodes[ iNode ]->second.back();
n2 = vecNewNodes[ iNext ]->second.back();
n3 = vecNewNodes[ iNode+nbn ]->second.back();
if ( !aMesh->FindEdge( n1, n2, n3 )) {
- myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 )); // ceiling edge
- srcElements.Append( elem );
+ myLastCreatedElems.push_back(aMesh->AddEdge( n1, n2, n3 )); // ceiling edge
+ srcElements.push_back( elem );
}
}
}
SMDS_VolumeTool vTool( *v, /*ignoreCentralNodes=*/false );
int iF, nbF = vTool.NbFaces();
for ( iF = 0; iF < nbF; iF ++ ) {
- if (vTool.IsFreeFace( iF ) &&
- vTool.GetFaceNodes( iF, faceNodeSet ) &&
- initNodeSet != faceNodeSet) // except an initial face
+ if ( vTool.IsFreeFace( iF ) &&
+ vTool.GetFaceNodes( iF, faceNodeSet ) &&
+ initNodeSet != faceNodeSet) // except an initial face
{
if ( nbSteps == 1 && faceNodeSet == topNodeSet )
continue;
if ( f )
aMesh->ChangeElementNodes( f, &newOrder[0], nbn );
else
- myLastCreatedElems.Append(aMesh->AddFace( newOrder[ 0 ], newOrder[ 1 ],
- newOrder[ 2 ] ));
+ myLastCreatedElems.push_back(aMesh->AddFace( newOrder[ 0 ], newOrder[ 1 ],
+ newOrder[ 2 ] ));
}
}
else if ( nbn == 4 ) ///// quadrangle
if ( f )
aMesh->ChangeElementNodes( f, &newOrder[0], nbn );
else
- myLastCreatedElems.Append(aMesh->AddFace( newOrder[ 0 ], newOrder[ 1 ],
- newOrder[ 2 ], newOrder[ 3 ]));
+ myLastCreatedElems.push_back(aMesh->AddFace( newOrder[ 0 ], newOrder[ 1 ],
+ newOrder[ 2 ], newOrder[ 3 ]));
}
}
else if ( nbn == 6 && isQuadratic ) /////// quadratic triangle
if ( f )
aMesh->ChangeElementNodes( f, &newOrder[0], nbn );
else
- myLastCreatedElems.Append(aMesh->AddFace( newOrder[ 0 ],
- newOrder[ 1 ],
- newOrder[ 2 ],
- newOrder[ 3 ],
- newOrder[ 4 ],
- newOrder[ 5 ] ));
+ myLastCreatedElems.push_back(aMesh->AddFace( newOrder[ 0 ],
+ newOrder[ 1 ],
+ newOrder[ 2 ],
+ newOrder[ 3 ],
+ newOrder[ 4 ],
+ newOrder[ 5 ] ));
}
}
else if ( nbn == 8 && isQuadratic ) /////// quadratic quadrangle
if ( f )
aMesh->ChangeElementNodes( f, &newOrder[0], nbn );
else
- myLastCreatedElems.Append(aMesh->AddFace(newOrder[ 0 ], newOrder[ 1 ],
- newOrder[ 2 ], newOrder[ 3 ],
- newOrder[ 4 ], newOrder[ 5 ],
- newOrder[ 6 ], newOrder[ 7 ]));
+ myLastCreatedElems.push_back(aMesh->AddFace(newOrder[ 0 ], newOrder[ 1 ],
+ newOrder[ 2 ], newOrder[ 3 ],
+ newOrder[ 4 ], newOrder[ 5 ],
+ newOrder[ 6 ], newOrder[ 7 ]));
}
}
else if ( nbn == 9 && isQuadratic ) /////// bi-quadratic quadrangle
if ( f )
aMesh->ChangeElementNodes( f, &newOrder[0], nbn );
else
- myLastCreatedElems.Append(aMesh->AddFace(newOrder[ 0 ], newOrder[ 1 ],
- newOrder[ 2 ], newOrder[ 3 ],
- newOrder[ 4 ], newOrder[ 5 ],
- newOrder[ 6 ], newOrder[ 7 ],
- newOrder[ 8 ]));
+ myLastCreatedElems.push_back(aMesh->AddFace(newOrder[ 0 ], newOrder[ 1 ],
+ newOrder[ 2 ], newOrder[ 3 ],
+ newOrder[ 4 ], newOrder[ 5 ],
+ newOrder[ 6 ], newOrder[ 7 ],
+ newOrder[ 8 ]));
}
}
else //////// polygon
}
}
- while ( srcElements.Length() < myLastCreatedElems.Length() )
- srcElements.Append( *srcEdge );
+ while ( srcElements.size() < myLastCreatedElems.size() )
+ srcElements.push_back( *srcEdge );
} // loop on free faces
AddElement( nodeVec, anyFace.Init( elem ));
- while ( srcElements.Length() < myLastCreatedElems.Length() )
- srcElements.Append( elem );
+ while ( srcElements.size() < myLastCreatedElems.size() )
+ srcElements.push_back( elem );
}
}
} // loop on swept elements
const bool theMakeGroups,
const bool theMakeWalls)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
+
+ setElemsFirst( theElemSets );
+ myLastCreatedElems.reserve( theElemSets[0].size() * theNbSteps );
+ myLastCreatedNodes.reserve( theElemSets[1].size() * theNbSteps );
// source elements for each generated one
SMESH_SequenceOfElemPtr srcElems, srcNodes;
+ srcElems.reserve( theElemSets[0].size() );
+ srcNodes.reserve( theElemSets[1].size() );
gp_Trsf aTrsf;
aTrsf.SetRotation( theAxis, theAngle );
myMesh->NbFaces(ORDER_QUADRATIC) +
myMesh->NbVolumes(ORDER_QUADRATIC) );
// loop on theElemSets
- setElemsFirst( theElemSets );
TIDSortedElemSet::iterator itElem;
for ( int is2ndSet = 0; is2ndSet < 2; ++is2ndSet )
{
{
aTrsf2.Transforms( coord[0], coord[1], coord[2] );
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
- myLastCreatedNodes.Append(newNode);
- srcNodes.Append( node );
+ myLastCreatedNodes.push_back(newNode);
+ srcNodes.push_back( node );
listNewNodes.push_back( newNode );
aTrsf2.Transforms( coord[0], coord[1], coord[2] );
}
}
// create a corner node
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
- myLastCreatedNodes.Append(newNode);
- srcNodes.Append( node );
+ myLastCreatedNodes.push_back(newNode);
+ srcNodes.push_back( node );
listNewNodes.push_back( newNode );
}
else {
SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec& theStep,
const int theNbSteps,
const std::list<double>& theScales,
+ const std::list<double>& theAngles,
const gp_XYZ* theBasePoint,
const int theFlags,
const double theTolerance):
for (int i=1; i<=theNbSteps; i++ )
mySteps->Append( stepSize );
- int nbScales = theScales.size();
- if ( nbScales > 0 )
+ if ( !theScales.empty() )
{
- if ( IsLinearVariation() && nbScales < theNbSteps )
+ if ( IsScaleVariation() && (int)theScales.size() < theNbSteps )
+ linearScaleVariation( theNbSteps, const_cast< std::list<double>& >( theScales ));
+
+ // add medium scales
+ std::list<double>::const_iterator s2 = theScales.begin(), s1 = s2++;
+ myScales.reserve( theNbSteps * 2 );
+ myScales.push_back( 0.5 * ( *s1 + 1. ));
+ myScales.push_back( *s1 );
+ for ( ; s2 != theScales.end(); s1 = s2++ )
{
- myScales.reserve( theNbSteps );
- std::list<double>::const_iterator scale = theScales.begin();
- double prevScale = 1.0;
- for ( int iSc = 1; scale != theScales.end(); ++scale, ++iSc )
- {
- int iStep = int( iSc / double( nbScales ) * theNbSteps + 0.5 );
- int stDelta = Max( 1, iStep - myScales.size());
- double scDelta = ( *scale - prevScale ) / stDelta;
- for ( int iStep = 0; iStep < stDelta; ++iStep )
- {
- myScales.push_back( prevScale + scDelta );
- prevScale = myScales.back();
- }
- prevScale = *scale;
- }
+ myScales.push_back( 0.5 * ( *s1 + *s2 ));
+ myScales.push_back( *s2 );
}
- else
+ }
+
+ if ( !theAngles.empty() )
+ {
+ std::list<double>& angles = const_cast< std::list<double>& >( theAngles );
+ if ( IsAngleVariation() && (int)theAngles.size() < theNbSteps )
+ linearAngleVariation( theNbSteps, angles );
+
+ // accumulate angles
+ double angle = 0;
+ int nbAngles = 0;
+ std::list<double>::iterator a1 = angles.begin(), a2;
+ for ( ; a1 != angles.end(); ++a1, ++nbAngles )
+ {
+ angle += *a1;
+ *a1 = angle;
+ }
+ while ( nbAngles++ < theNbSteps )
+ angles.push_back( angles.back() );
+
+ // add medium angles
+ a2 = angles.begin(), a1 = a2++;
+ myAngles.push_back( 0.5 * *a1 );
+ myAngles.push_back( *a1 );
+ for ( ; a2 != angles.end(); a1 = a2++ )
{
- myScales.assign( theScales.begin(), theScales.end() );
+ myAngles.push_back( 0.5 * ( *a1 + *a2 ));
+ myAngles.push_back( *a2 );
}
}
+
if ( theBasePoint )
{
myBaseP = *theBasePoint;
}
}
+//=======================================================================
+//function : ExtrusParam
+//purpose : for extrusion along path
+//=======================================================================
+
+SMESH_MeshEditor::ExtrusParam::ExtrusParam( const std::vector< PathPoint >& thePoints,
+ const gp_Pnt* theBasePoint,
+ const std::list<double>& theScales,
+ const bool theMakeGroups )
+ : myBaseP( Precision::Infinite(), 0, 0 ),
+ myFlags( EXTRUSION_FLAG_BOUNDARY | ( theMakeGroups ? EXTRUSION_FLAG_GROUPS : 0 )),
+ myPathPoints( thePoints )
+{
+ if ( theBasePoint )
+ {
+ myBaseP = theBasePoint->XYZ();
+ }
+
+ if ( !theScales.empty() )
+ {
+ // add medium scales
+ std::list<double>::const_iterator s2 = theScales.begin(), s1 = s2++;
+ myScales.reserve( thePoints.size() * 2 );
+ myScales.push_back( 0.5 * ( 1. + *s1 ));
+ myScales.push_back( *s1 );
+ for ( ; s2 != theScales.end(); s1 = s2++ )
+ {
+ myScales.push_back( 0.5 * ( *s1 + *s2 ));
+ myScales.push_back( *s2 );
+ }
+ }
+
+ myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesAlongTrack;
+}
+
//=======================================================================
//function : ExtrusParam::SetElementsToUse
//purpose : stores elements to use for extrusion by normal, depending on
while ( itN->more() ) {
const SMDS_MeshElement* node = itN->next();
if ( newNodes.insert( node ).second )
- myBaseP += SMESH_TNodeXYZ( node );
+ myBaseP += SMESH_NodeXYZ( node );
}
}
}
std::list<const SMDS_MeshNode*> & newNodes,
const bool makeMediumNodes)
{
- gp_XYZ p = SMESH_TNodeXYZ( srcNode );
+ gp_XYZ p = SMESH_NodeXYZ( srcNode );
int nbNodes = 0;
for ( beginStepIter( makeMediumNodes ); moreSteps(); ++nbNodes ) // loop on steps
newNodes.push_back( newNode );
}
- if ( !myScales.empty() )
+ if ( !myScales.empty() || !myAngles.empty() )
{
- if ( makeMediumNodes && myMediumScales.empty() )
- {
- myMediumScales.resize( myScales.size() );
- double prevFactor = 1.;
- for ( size_t i = 0; i < myScales.size(); ++i )
- {
- myMediumScales[i] = 0.5 * ( prevFactor + myScales[i] );
- prevFactor = myScales[i];
- }
- }
- typedef std::vector<double>::iterator ScaleIt;
- ScaleIt scales[] = { myScales.begin(), myMediumScales.begin() };
+ gp_XYZ center = myBaseP;
+ gp_Ax1 ratationAxis( center, myDir );
+ gp_Trsf rotation;
- size_t iSc = 0, nbScales = myScales.size() + myMediumScales.size();
-
- gp_XYZ center = myBaseP;
std::list<const SMDS_MeshNode*>::iterator nIt = newNodes.begin();
- size_t iN = 0;
- for ( beginStepIter( makeMediumNodes ); moreSteps() && ( iN < nbScales ); ++nIt, ++iN )
+ size_t i = !makeMediumNodes;
+ for ( beginStepIter( makeMediumNodes );
+ moreSteps();
+ ++nIt, i += 1 + !makeMediumNodes )
{
center += myDir.XYZ() * nextStep();
- iSc += int( makeMediumNodes );
- ScaleIt& scale = scales[ iSc % 2 ];
-
- gp_XYZ xyz = SMESH_TNodeXYZ( *nIt );
- xyz = ( *scale * ( xyz - center )) + center;
- mesh->MoveNode( *nIt, xyz.X(), xyz.Y(), xyz.Z() );
-
- ++scale;
+ gp_XYZ xyz = SMESH_NodeXYZ( *nIt );
+ bool moved = false;
+ if ( i < myScales.size() )
+ {
+ xyz = ( myScales[i] * ( xyz - center )) + center;
+ moved = true;
+ }
+ if ( !myAngles.empty() )
+ {
+ rotation.SetRotation( ratationAxis, myAngles[i] );
+ rotation.Transforms( xyz );
+ moved = true;
+ }
+ if ( moved )
+ mesh->MoveNode( *nIt, xyz.X(), xyz.Y(), xyz.Z() );
+ else
+ break;
}
}
return nbNodes;
std::list<const SMDS_MeshNode*> & newNodes,
const bool makeMediumNodes)
{
- gp_XYZ P1 = SMESH_TNodeXYZ( srcNode );
+ gp_XYZ P1 = SMESH_NodeXYZ( srcNode );
int nbNodes = 0;
for ( beginStepIter( makeMediumNodes ); moreSteps(); ++nbNodes ) // loop on steps
P1 += myDir.XYZ() * nextStep();
// try to search in sequence of existing nodes
- // if myNodes.Length()>0 we 'nave to use given sequence
+ // if myNodes.size()>0 we 'nave to use given sequence
// else - use all nodes of mesh
const SMDS_MeshNode * node = 0;
- if ( myNodes.Length() > 0 ) {
- int i;
- for(i=1; i<=myNodes.Length(); i++) {
- gp_XYZ P2 = SMESH_TNodeXYZ( myNodes.Value(i) );
+ if ( myNodes.Length() > 0 )
+ {
+ for ( int i = 1; i <= myNodes.Length(); i++ )
+ {
+ SMESH_NodeXYZ P2 = myNodes.Value(i);
if (( P1 - P2 ).SquareModulus() < myTolerance * myTolerance )
{
node = myNodes.Value(i);
}
}
}
- else {
+ else
+ {
SMDS_NodeIteratorPtr itn = mesh->nodesIterator();
- while(itn->more()) {
- SMESH_TNodeXYZ P2( itn->next() );
+ while(itn->more())
+ {
+ SMESH_NodeXYZ P2 = itn->next();
if (( P1 - P2 ).SquareModulus() < myTolerance * myTolerance )
{
node = P2._node;
{
const bool alongAvgNorm = ( myFlags & EXTRUSION_FLAG_BY_AVG_NORMAL );
- gp_XYZ p = SMESH_TNodeXYZ( srcNode );
+ gp_XYZ p = SMESH_NodeXYZ( srcNode );
// get normals to faces sharing srcNode
vector< gp_XYZ > norms, baryCenters;
gp_XYZ bc(0,0,0);
int nbN = 0;
for ( SMDS_ElemIteratorPtr nIt = face->nodesIterator(); nIt->more(); ++nbN )
- bc += SMESH_TNodeXYZ( nIt->next() );
+ bc += SMESH_NodeXYZ( nIt->next() );
baryCenters.push_back( bc / nbN );
}
}
return 0;
}
+//=======================================================================
+//function : ExtrusParam::makeNodesAlongTrack
+//purpose : create nodes for extrusion along path
+//=======================================================================
+
+int SMESH_MeshEditor::ExtrusParam::
+makeNodesAlongTrack( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes)
+{
+ const Standard_Real aTolAng=1.e-4;
+
+ gp_Pnt aV0x = myBaseP;
+ gp_Pnt aPN0 = SMESH_NodeXYZ( srcNode );
+
+ const PathPoint& aPP0 = myPathPoints[0];
+ gp_Pnt aP0x = aPP0.myPnt;
+ gp_Dir aDT0x= aPP0.myTgt;
+
+ std::vector< gp_Pnt > centers;
+ centers.reserve( NbSteps() * 2 );
+
+ gp_Trsf aTrsf, aTrsfRot, aTrsfRotT1T0;
+
+ for ( size_t j = 1; j < myPathPoints.size(); ++j )
+ {
+ const PathPoint& aPP = myPathPoints[j];
+ const gp_Pnt& aP1x = aPP.myPnt;
+ const gp_Dir& aDT1x = aPP.myTgt;
+
+ // Translation
+ gp_Vec aV01x( aP0x, aP1x );
+ aTrsf.SetTranslation( aV01x );
+ gp_Pnt aV1x = aV0x.Transformed( aTrsf );
+ gp_Pnt aPN1 = aPN0.Transformed( aTrsf );
+
+ // rotation 1 [ T1,T0 ]
+ Standard_Real aAngleT1T0 = -aDT1x.Angle( aDT0x );
+ if ( fabs( aAngleT1T0 ) > aTolAng )
+ {
+ gp_Dir aDT1T0 = aDT1x ^ aDT0x;
+ aTrsfRotT1T0.SetRotation( gp_Ax1( aV1x, aDT1T0 ), aAngleT1T0 );
+
+ aPN1 = aPN1.Transformed( aTrsfRotT1T0 );
+ }
+
+ // rotation 2
+ if ( aPP.myAngle != 0. )
+ {
+ aTrsfRot.SetRotation( gp_Ax1( aV1x, aDT1x ), aPP.myAngle );
+ aPN1 = aPN1.Transformed( aTrsfRot );
+ }
+
+ // make new node
+ if ( makeMediumNodes )
+ {
+ // create additional node
+ gp_XYZ midP = 0.5 * ( aPN1.XYZ() + aPN0.XYZ() );
+ const SMDS_MeshNode* newNode = mesh->AddNode( midP.X(), midP.Y(), midP.Z() );
+ newNodes.push_back( newNode );
+
+ }
+ const SMDS_MeshNode* newNode = mesh->AddNode( aPN1.X(), aPN1.Y(), aPN1.Z() );
+ newNodes.push_back( newNode );
+
+ centers.push_back( 0.5 * ( aV0x.XYZ() + aV1x.XYZ() ));
+ centers.push_back( aV1x );
+
+ aPN0 = aPN1;
+ aP0x = aP1x;
+ aV0x = aV1x;
+ aDT0x = aDT1x;
+ }
+
+ // scale
+ if ( !myScales.empty() )
+ {
+ gp_Trsf aTrsfScale;
+ std::list<const SMDS_MeshNode*>::iterator node = newNodes.begin();
+ for ( size_t i = !makeMediumNodes;
+ i < myScales.size() && node != newNodes.end();
+ i += ( 1 + !makeMediumNodes ), ++node )
+ {
+ aTrsfScale.SetScale( centers[ i ], myScales[ i ] );
+ gp_Pnt aN = SMESH_NodeXYZ( *node );
+ gp_Pnt aP = aN.Transformed( aTrsfScale );
+ mesh->MoveNode( *node, aP.X(), aP.Y(), aP.Z() );
+ }
+ }
+
+ return myPathPoints.size() + makeMediumNodes * ( myPathPoints.size() - 2 );
+}
+
//=======================================================================
//function : ExtrusionSweep
//purpose :
const int theFlags,
const double theTolerance)
{
- ExtrusParam aParams( theStep, theNbSteps, std::list<double>(), 0, theFlags, theTolerance );
+ std::list<double> dummy;
+ ExtrusParam aParams( theStep, theNbSteps, dummy, dummy, 0,
+ theFlags, theTolerance );
return ExtrusionSweep( theElems, aParams, newElemsMap );
}
+namespace
+{
+
+//=======================================================================
+//function : getOriFactor
+//purpose : Return -1 or 1 depending on if order of given nodes corresponds to
+// edge curve orientation
+//=======================================================================
+
+ double getOriFactor( const TopoDS_Edge& edge,
+ const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ SMESH_MesherHelper& helper)
+ {
+ double u1 = helper.GetNodeU( edge, n1, n2 );
+ double u2 = helper.GetNodeU( edge, n2, n1 );
+ return u1 < u2 ? 1. : -1.;
+ }
+}
//=======================================================================
//function : ExtrusionSweep
ExtrusParam& theParams,
TTElemOfElemListMap& newElemsMap)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
+
+ setElemsFirst( theElemSets );
+ myLastCreatedElems.reserve( theElemSets[0].size() * theParams.NbSteps() );
+ myLastCreatedNodes.reserve( theElemSets[1].size() * theParams.NbSteps() );
// source elements for each generated one
SMESH_SequenceOfElemPtr srcElems, srcNodes;
+ srcElems.reserve( theElemSets[0].size() );
+ srcNodes.reserve( theElemSets[1].size() );
- setElemsFirst( theElemSets );
const int nbSteps = theParams.NbSteps();
theParams.SetElementsToUse( theElemSets[0], theElemSets[1] );
newNodesItVec.reserve( nbNodes );
// loop on elem nodes
- SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ SMDS_NodeIteratorPtr itN = elem->nodeIterator();
while ( itN->more() )
{
// check if a node has been already sweeped
- const SMDS_MeshNode* node = cast2Node( itN->next() );
+ const SMDS_MeshNode* node = itN->next();
TNodeOfNodeListMap::iterator nIt =
mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
list<const SMDS_MeshNode*>::iterator newNodesIt = listNewNodes.begin();
for ( ; newNodesIt != listNewNodes.end(); ++newNodesIt )
{
- myLastCreatedNodes.Append( *newNodesIt );
- srcNodes.Append( node );
+ myLastCreatedNodes.push_back( *newNodesIt );
+ srcNodes.push_back( node );
}
}
else
//=======================================================================
SMESH_MeshEditor::Extrusion_Error
SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2],
- SMESH_subMesh* theTrack,
+ SMESH_Mesh* theTrackMesh,
+ SMDS_ElemIteratorPtr theTrackIterator,
const SMDS_MeshNode* theN1,
- const bool theHasAngles,
- list<double>& theAngles,
- const bool theLinearVariation,
- const bool theHasRefPoint,
- const gp_Pnt& theRefPoint,
+ std::list<double>& theAngles,
+ const bool theAngleVariation,
+ std::list<double>& theScales,
+ const bool theScaleVariation,
+ const gp_Pnt* theRefPoint,
const bool theMakeGroups)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
-
- int aNbE;
- std::list<double> aPrms;
- TIDSortedElemSet::iterator itElem;
-
- gp_XYZ aGC;
- TopoDS_Edge aTrackEdge;
- TopoDS_Vertex aV1, aV2;
-
- SMDS_ElemIteratorPtr aItE;
- SMDS_NodeIteratorPtr aItN;
- SMDSAbs_ElementType aTypeE;
-
- TNodeOfNodeListMap mapNewNodes;
+ ClearLastCreated();
// 1. Check data
- aNbE = theElements[0].size() + theElements[1].size();
- // nothing to do
- if ( !aNbE )
+ if ( theElements[0].empty() && theElements[1].empty() )
return EXTR_NO_ELEMENTS;
- // 1.1 Track Pattern
- ASSERT( theTrack );
-
- SMESHDS_SubMesh* pSubMeshDS = theTrack->GetSubMeshDS();
- if ( !pSubMeshDS )
- return ExtrusionAlongTrack( theElements, theTrack->GetFather(), theN1,
- theHasAngles, theAngles, theLinearVariation,
- theHasRefPoint, theRefPoint, theMakeGroups );
-
- aItE = pSubMeshDS->GetElements();
- while ( aItE->more() ) {
- const SMDS_MeshElement* pE = aItE->next();
- aTypeE = pE->GetType();
- // Pattern must contain links only
- if ( aTypeE != SMDSAbs_Edge )
- return EXTR_PATH_NOT_EDGE;
- }
-
- list<SMESH_MeshEditor_PathPoint> fullList;
-
- const TopoDS_Shape& aS = theTrack->GetSubShape();
- // Sub-shape for the Pattern must be an Edge or Wire
- if( aS.ShapeType() == TopAbs_EDGE ) {
- aTrackEdge = TopoDS::Edge( aS );
- // the Edge must not be degenerated
- if ( SMESH_Algo::isDegenerated( aTrackEdge ) )
- return EXTR_BAD_PATH_SHAPE;
- TopExp::Vertices( aTrackEdge, aV1, aV2 );
- aItN = theTrack->GetFather()->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes();
- const SMDS_MeshNode* aN1 = aItN->next();
- aItN = theTrack->GetFather()->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes();
- const SMDS_MeshNode* aN2 = aItN->next();
- // starting node must be aN1 or aN2
- if ( !( aN1 == theN1 || aN2 == theN1 ) )
- return EXTR_BAD_STARTING_NODE;
- aItN = pSubMeshDS->GetNodes();
- while ( aItN->more() ) {
- const SMDS_MeshNode* pNode = aItN->next();
- const SMDS_EdgePosition* pEPos =
- static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
- double aT = pEPos->GetUParameter();
- aPrms.push_back( aT );
- }
- //Extrusion_Error err =
- makeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList);
- } else if( aS.ShapeType() == TopAbs_WIRE ) {
- list< SMESH_subMesh* > LSM;
- TopTools_SequenceOfShape Edges;
- SMESH_subMeshIteratorPtr itSM = theTrack->getDependsOnIterator(false,true);
- while(itSM->more()) {
- SMESH_subMesh* SM = itSM->next();
- LSM.push_back(SM);
- const TopoDS_Shape& aS = SM->GetSubShape();
- Edges.Append(aS);
- }
- list< list<SMESH_MeshEditor_PathPoint> > LLPPs;
- int startNid = theN1->GetID();
- TColStd_MapOfInteger UsedNums;
-
- int NbEdges = Edges.Length();
- int i = 1;
- for(; i<=NbEdges; i++) {
- int k = 0;
- list< SMESH_subMesh* >::iterator itLSM = LSM.begin();
- for(; itLSM!=LSM.end(); itLSM++) {
- k++;
- if(UsedNums.Contains(k)) continue;
- aTrackEdge = TopoDS::Edge( Edges.Value(k) );
- SMESH_subMesh* locTrack = *itLSM;
- SMESHDS_SubMesh* locMeshDS = locTrack->GetSubMeshDS();
- TopExp::Vertices( aTrackEdge, aV1, aV2 );
- aItN = locTrack->GetFather()->GetSubMesh(aV1)->GetSubMeshDS()->GetNodes();
- const SMDS_MeshNode* aN1 = aItN->next();
- aItN = locTrack->GetFather()->GetSubMesh(aV2)->GetSubMeshDS()->GetNodes();
- const SMDS_MeshNode* aN2 = aItN->next();
- // starting node must be aN1 or aN2
- if ( !( aN1->GetID() == startNid || aN2->GetID() == startNid ) ) continue;
- // 2. Collect parameters on the track edge
- aPrms.clear();
- aItN = locMeshDS->GetNodes();
- while ( aItN->more() ) {
- const SMDS_MeshNode* pNode = aItN->next();
- const SMDS_EdgePosition* pEPos =
- static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
- double aT = pEPos->GetUParameter();
- aPrms.push_back( aT );
- }
- list<SMESH_MeshEditor_PathPoint> LPP;
- //Extrusion_Error err =
- makeEdgePathPoints(aPrms, aTrackEdge,(aN1->GetID()==startNid), LPP);
- LLPPs.push_back(LPP);
- UsedNums.Add(k);
- // update startN for search following edge
- if( aN1->GetID() == startNid ) startNid = aN2->GetID();
- else startNid = aN1->GetID();
- break;
- }
- }
- list< list<SMESH_MeshEditor_PathPoint> >::iterator itLLPP = LLPPs.begin();
- list<SMESH_MeshEditor_PathPoint> firstList = *itLLPP;
- list<SMESH_MeshEditor_PathPoint>::iterator itPP = firstList.begin();
- for(; itPP!=firstList.end(); itPP++) {
- fullList.push_back( *itPP );
- }
- SMESH_MeshEditor_PathPoint PP1 = fullList.back();
- fullList.pop_back();
- itLLPP++;
- for(; itLLPP!=LLPPs.end(); itLLPP++) {
- list<SMESH_MeshEditor_PathPoint> currList = *itLLPP;
- itPP = currList.begin();
- SMESH_MeshEditor_PathPoint PP2 = currList.front();
- gp_Dir D1 = PP1.Tangent();
- gp_Dir D2 = PP2.Tangent();
- gp_Dir Dnew( gp_Vec( (D1.X()+D2.X())/2, (D1.Y()+D2.Y())/2,
- (D1.Z()+D2.Z())/2 ) );
- PP1.SetTangent(Dnew);
- fullList.push_back(PP1);
- itPP++;
- for(; itPP!=firstList.end(); itPP++) {
- fullList.push_back( *itPP );
- }
- PP1 = fullList.back();
- fullList.pop_back();
- }
- // if wire not closed
- fullList.push_back(PP1);
- // else ???
- }
- else {
- return EXTR_BAD_PATH_SHAPE;
- }
-
- return makeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation,
- theHasRefPoint, theRefPoint, theMakeGroups);
-}
-
-
-//=======================================================================
-//function : ExtrusionAlongTrack
-//purpose :
-//=======================================================================
-SMESH_MeshEditor::Extrusion_Error
-SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2],
- SMESH_Mesh* theTrack,
- const SMDS_MeshNode* theN1,
- const bool theHasAngles,
- list<double>& theAngles,
- const bool theLinearVariation,
- const bool theHasRefPoint,
- const gp_Pnt& theRefPoint,
- const bool theMakeGroups)
-{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
-
- int aNbE;
- std::list<double> aPrms;
- TIDSortedElemSet::iterator itElem;
-
- gp_XYZ aGC;
- TopoDS_Edge aTrackEdge;
- TopoDS_Vertex aV1, aV2;
-
- SMDS_ElemIteratorPtr aItE;
- SMDS_NodeIteratorPtr aItN;
- SMDSAbs_ElementType aTypeE;
+ ASSERT( theTrackMesh );
+ if ( ! theTrackIterator || !theTrackIterator->more() )
+ return EXTR_NO_ELEMENTS;
- TNodeOfNodeListMap mapNewNodes;
+ // 2. Get ordered nodes
+ SMESH_MeshAlgos::TElemGroupVector branchEdges;
+ SMESH_MeshAlgos::TNodeGroupVector branchNods;
+ SMESH_MeshAlgos::Get1DBranches( theTrackIterator, branchEdges, branchNods, theN1 );
+ if ( branchEdges.empty() )
+ return EXTR_PATH_NOT_EDGE;
- // 1. Check data
- aNbE = theElements[0].size() + theElements[1].size();
- // nothing to do
- if ( !aNbE )
- return EXTR_NO_ELEMENTS;
+ if ( branchEdges.size() > 1 )
+ return EXTR_BAD_PATH_SHAPE;
- // 1.1 Track Pattern
- ASSERT( theTrack );
-
- SMESHDS_Mesh* pMeshDS = theTrack->GetMeshDS();
-
- aItE = pMeshDS->elementsIterator();
- while ( aItE->more() ) {
- const SMDS_MeshElement* pE = aItE->next();
- aTypeE = pE->GetType();
- // Pattern must contain links only
- if ( aTypeE != SMDSAbs_Edge )
- return EXTR_PATH_NOT_EDGE;
- }
-
- list<SMESH_MeshEditor_PathPoint> fullList;
-
- const TopoDS_Shape& aS = theTrack->GetShapeToMesh();
-
- if ( !theTrack->HasShapeToMesh() ) {
- //Mesh without shape
- const SMDS_MeshNode* currentNode = NULL;
- const SMDS_MeshNode* prevNode = theN1;
- std::vector<const SMDS_MeshNode*> aNodesList;
- aNodesList.push_back(theN1);
- int nbEdges = 0, conn=0;
- const SMDS_MeshElement* prevElem = NULL;
- const SMDS_MeshElement* currentElem = NULL;
- int totalNbEdges = theTrack->NbEdges();
- SMDS_ElemIteratorPtr nIt;
-
- //check start node
- if( !theTrack->GetMeshDS()->Contains(theN1) ) {
- return EXTR_BAD_STARTING_NODE;
- }
-
- conn = nbEdgeConnectivity(theN1);
- if( conn != 1 )
- return EXTR_PATH_NOT_EDGE;
-
- aItE = theN1->GetInverseElementIterator();
- prevElem = aItE->next();
- currentElem = prevElem;
- //Get all nodes
- if(totalNbEdges == 1 ) {
- nIt = currentElem->nodesIterator();
- currentNode = static_cast<const SMDS_MeshNode*>(nIt->next());
- if(currentNode == prevNode)
- currentNode = static_cast<const SMDS_MeshNode*>(nIt->next());
- aNodesList.push_back(currentNode);
- } else {
- nIt = currentElem->nodesIterator();
- while( nIt->more() ) {
- currentNode = static_cast<const SMDS_MeshNode*>(nIt->next());
- if(currentNode == prevNode)
- currentNode = static_cast<const SMDS_MeshNode*>(nIt->next());
- aNodesList.push_back(currentNode);
-
- //case of the closed mesh
- if(currentNode == theN1) {
- nbEdges++;
- break;
- }
+ std::vector< const SMDS_MeshNode* >& pathNodes = branchNods[0];
+ std::vector< const SMDS_MeshElement* >& pathEdges = branchEdges[0];
+ if ( pathNodes[0] != theN1 && pathNodes[1] != theN1 )
+ return EXTR_BAD_STARTING_NODE;
- conn = nbEdgeConnectivity(currentNode);
- if(conn > 2) {
- return EXTR_PATH_NOT_EDGE;
- }else if( conn == 1 && nbEdges > 0 ) {
- //End of the path
- nbEdges++;
- break;
- }else {
- prevNode = currentNode;
- aItE = currentNode->GetInverseElementIterator();
- currentElem = aItE->next();
- if( currentElem == prevElem)
- currentElem = aItE->next();
- nIt = currentElem->nodesIterator();
- prevElem = currentElem;
- nbEdges++;
- }
- }
- }
-
- if(nbEdges != totalNbEdges)
- return EXTR_PATH_NOT_EDGE;
-
- TopTools_SequenceOfShape Edges;
- list< list<SMESH_MeshEditor_PathPoint> > LLPPs;
- int startNid = theN1->GetID();
- for ( size_t i = 1; i < aNodesList.size(); i++ )
- {
- gp_Pnt p1 = SMESH_TNodeXYZ( aNodesList[i-1] );
- gp_Pnt p2 = SMESH_TNodeXYZ( aNodesList[i] );
- TopoDS_Edge e = BRepBuilderAPI_MakeEdge( p1, p2 );
- list<SMESH_MeshEditor_PathPoint> LPP;
- aPrms.clear();
- makeEdgePathPoints(aPrms, e, (aNodesList[i-1]->GetID()==startNid), LPP);
- LLPPs.push_back(LPP);
- if ( aNodesList[i-1]->GetID() == startNid ) startNid = aNodesList[i ]->GetID();
- else startNid = aNodesList[i-1]->GetID();
- }
-
- list< list<SMESH_MeshEditor_PathPoint> >::iterator itLLPP = LLPPs.begin();
- list<SMESH_MeshEditor_PathPoint> firstList = *itLLPP;
- list<SMESH_MeshEditor_PathPoint>::iterator itPP = firstList.begin();
- for(; itPP!=firstList.end(); itPP++) {
- fullList.push_back( *itPP );
- }
-
- SMESH_MeshEditor_PathPoint PP1 = fullList.back();
- SMESH_MeshEditor_PathPoint PP2;
- fullList.pop_back();
- itLLPP++;
- for(; itLLPP!=LLPPs.end(); itLLPP++) {
- list<SMESH_MeshEditor_PathPoint> currList = *itLLPP;
- itPP = currList.begin();
- PP2 = currList.front();
- gp_Dir D1 = PP1.Tangent();
- gp_Dir D2 = PP2.Tangent();
- gp_Dir Dnew( 0.5 * ( D1.XYZ() + D2.XYZ() ));
- PP1.SetTangent(Dnew);
- fullList.push_back(PP1);
- itPP++;
- for(; itPP!=currList.end(); itPP++) {
- fullList.push_back( *itPP );
- }
- PP1 = fullList.back();
- fullList.pop_back();
- }
- fullList.push_back(PP1);
-
- } // Sub-shape for the Pattern must be an Edge or Wire
- else if ( aS.ShapeType() == TopAbs_EDGE )
- {
- aTrackEdge = TopoDS::Edge( aS );
- // the Edge must not be degenerated
- if ( SMESH_Algo::isDegenerated( aTrackEdge ) )
- return EXTR_BAD_PATH_SHAPE;
- TopExp::Vertices( aTrackEdge, aV1, aV2 );
- const SMDS_MeshNode* aN1 = SMESH_Algo::VertexNode( aV1, pMeshDS );
- const SMDS_MeshNode* aN2 = SMESH_Algo::VertexNode( aV2, pMeshDS );
- // starting node must be aN1 or aN2
- if ( !( aN1 == theN1 || aN2 == theN1 ) )
- return EXTR_BAD_STARTING_NODE;
- aItN = pMeshDS->nodesIterator();
- while ( aItN->more() ) {
- const SMDS_MeshNode* pNode = aItN->next();
- if( pNode==aN1 || pNode==aN2 ) continue;
- const SMDS_EdgePosition* pEPos =
- static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
- double aT = pEPos->GetUParameter();
- aPrms.push_back( aT );
- }
- //Extrusion_Error err =
- makeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList);
- }
- else if( aS.ShapeType() == TopAbs_WIRE ) {
- list< SMESH_subMesh* > LSM;
- TopTools_SequenceOfShape Edges;
- TopExp_Explorer eExp(aS, TopAbs_EDGE);
- for(; eExp.More(); eExp.Next()) {
- TopoDS_Edge E = TopoDS::Edge( eExp.Current() );
- if( SMESH_Algo::isDegenerated(E) ) continue;
- SMESH_subMesh* SM = theTrack->GetSubMesh(E);
- if(SM) {
- LSM.push_back(SM);
- Edges.Append(E);
- }
- }
- list< list<SMESH_MeshEditor_PathPoint> > LLPPs;
- TopoDS_Vertex aVprev;
- TColStd_MapOfInteger UsedNums;
- int NbEdges = Edges.Length();
- int i = 1;
- for(; i<=NbEdges; i++) {
- int k = 0;
- list< SMESH_subMesh* >::iterator itLSM = LSM.begin();
- for(; itLSM!=LSM.end(); itLSM++) {
- k++;
- if(UsedNums.Contains(k)) continue;
- aTrackEdge = TopoDS::Edge( Edges.Value(k) );
- SMESH_subMesh* locTrack = *itLSM;
- SMESHDS_SubMesh* locMeshDS = locTrack->GetSubMeshDS();
- TopExp::Vertices( aTrackEdge, aV1, aV2 );
- bool aN1isOK = false, aN2isOK = false;
- if ( aVprev.IsNull() ) {
- // if previous vertex is not yet defined, it means that we in the beginning of wire
- // and we have to find initial vertex corresponding to starting node theN1
- const SMDS_MeshNode* aN1 = SMESH_Algo::VertexNode( aV1, pMeshDS );
- const SMDS_MeshNode* aN2 = SMESH_Algo::VertexNode( aV2, pMeshDS );
- // starting node must be aN1 or aN2
- aN1isOK = ( aN1 && aN1 == theN1 );
- aN2isOK = ( aN2 && aN2 == theN1 );
- }
- else {
- // we have specified ending vertex of the previous edge on the previous iteration
- // and we have just to check that it corresponds to any vertex in current segment
- aN1isOK = aVprev.IsSame( aV1 );
- aN2isOK = aVprev.IsSame( aV2 );
- }
- if ( !aN1isOK && !aN2isOK ) continue;
- // 2. Collect parameters on the track edge
- aPrms.clear();
- aItN = locMeshDS->GetNodes();
- while ( aItN->more() ) {
- const SMDS_MeshNode* pNode = aItN->next();
- const SMDS_EdgePosition* pEPos =
- static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
- double aT = pEPos->GetUParameter();
- aPrms.push_back( aT );
- }
- list<SMESH_MeshEditor_PathPoint> LPP;
- //Extrusion_Error err =
- makeEdgePathPoints(aPrms, aTrackEdge, aN1isOK, LPP);
- LLPPs.push_back(LPP);
- UsedNums.Add(k);
- // update startN for search following edge
- if ( aN1isOK ) aVprev = aV2;
- else aVprev = aV1;
- break;
+ if ( theTrackMesh->NbEdges( ORDER_QUADRATIC ) > 0 )
+ {
+ // add medium nodes to pathNodes
+ std::vector< const SMDS_MeshNode* > pathNodes2;
+ std::vector< const SMDS_MeshElement* > pathEdges2;
+ pathNodes2.reserve( pathNodes.size() * 2 );
+ pathEdges2.reserve( pathEdges.size() * 2 );
+ for ( size_t i = 0; i < pathEdges.size(); ++i )
+ {
+ pathNodes2.push_back( pathNodes[i] );
+ pathEdges2.push_back( pathEdges[i] );
+ if ( pathEdges[i]->IsQuadratic() )
+ {
+ pathNodes2.push_back( pathEdges[i]->GetNode(2) );
+ pathEdges2.push_back( pathEdges[i] );
}
}
- list< list<SMESH_MeshEditor_PathPoint> >::iterator itLLPP = LLPPs.begin();
- list<SMESH_MeshEditor_PathPoint>& firstList = *itLLPP;
- fullList.splice( fullList.end(), firstList );
-
- SMESH_MeshEditor_PathPoint PP1 = fullList.back();
- fullList.pop_back();
- itLLPP++;
- for(; itLLPP!=LLPPs.end(); itLLPP++) {
- list<SMESH_MeshEditor_PathPoint>& currList = *itLLPP;
- SMESH_MeshEditor_PathPoint PP2 = currList.front();
- gp_Dir D1 = PP1.Tangent();
- gp_Dir D2 = PP2.Tangent();
- gp_Dir Dnew( D1.XYZ() + D2.XYZ() );
- PP1.SetTangent(Dnew);
- fullList.push_back(PP1);
- fullList.splice( fullList.end(), currList, ++currList.begin(), currList.end() );
- PP1 = fullList.back();
- fullList.pop_back();
- }
- // if wire not closed
- fullList.push_back(PP1);
- // else ???
- }
- else {
- return EXTR_BAD_PATH_SHAPE;
+ pathNodes2.push_back( pathNodes.back() );
+ pathEdges.swap( pathEdges2 );
+ pathNodes.swap( pathNodes2 );
}
- return makeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation,
- theHasRefPoint, theRefPoint, theMakeGroups);
-}
+ // 3. Get path data at pathNodes
+ std::vector< ExtrusParam::PathPoint > points( pathNodes.size() );
-//=======================================================================
-//function : makeEdgePathPoints
-//purpose : auxiliary for ExtrusionAlongTrack
-//=======================================================================
-SMESH_MeshEditor::Extrusion_Error
-SMESH_MeshEditor::makeEdgePathPoints(std::list<double>& aPrms,
- const TopoDS_Edge& aTrackEdge,
- bool FirstIsStart,
- list<SMESH_MeshEditor_PathPoint>& LPP)
-{
- Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2;
- aTolVec=1.e-7;
- aTolVec2=aTolVec*aTolVec;
- double aT1, aT2;
- TopoDS_Vertex aV1, aV2;
- TopExp::Vertices( aTrackEdge, aV1, aV2 );
- aT1=BRep_Tool::Parameter( aV1, aTrackEdge );
- aT2=BRep_Tool::Parameter( aV2, aTrackEdge );
- // 2. Collect parameters on the track edge
- aPrms.push_front( aT1 );
- aPrms.push_back( aT2 );
- // sort parameters
- aPrms.sort();
- if( FirstIsStart ) {
- if ( aT1 > aT2 ) {
- aPrms.reverse();
- }
- }
- else {
- if ( aT2 > aT1 ) {
- aPrms.reverse();
- }
- }
- // 3. Path Points
- SMESH_MeshEditor_PathPoint aPP;
- Handle(Geom_Curve) aC3D = BRep_Tool::Curve( aTrackEdge, aTx1, aTx2 );
- std::list<double>::iterator aItD = aPrms.begin();
- for(; aItD != aPrms.end(); ++aItD) {
- double aT = *aItD;
- gp_Pnt aP3D;
- gp_Vec aVec;
- aC3D->D1( aT, aP3D, aVec );
- aL2 = aVec.SquareMagnitude();
- if ( aL2 < aTolVec2 )
- return EXTR_CANT_GET_TANGENT;
- gp_Dir aTgt( FirstIsStart ? aVec : -aVec );
- aPP.SetPnt( aP3D );
- aPP.SetTangent( aTgt );
- aPP.SetParameter( aT );
- LPP.push_back(aPP);
- }
- return EXTR_OK;
-}
+ if ( theAngleVariation )
+ linearAngleVariation( points.size()-1, theAngles );
+ if ( theScaleVariation )
+ linearScaleVariation( points.size()-1, theScales );
+ theAngles.push_front( 0 ); // for the 1st point that is not transformed
+ std::list<double>::iterator angle = theAngles.begin();
-//=======================================================================
-//function : makeExtrElements
-//purpose : auxiliary for ExtrusionAlongTrack
-//=======================================================================
-SMESH_MeshEditor::Extrusion_Error
-SMESH_MeshEditor::makeExtrElements(TIDSortedElemSet theElemSets[2],
- list<SMESH_MeshEditor_PathPoint>& fullList,
- const bool theHasAngles,
- list<double>& theAngles,
- const bool theLinearVariation,
- const bool theHasRefPoint,
- const gp_Pnt& theRefPoint,
- const bool theMakeGroups)
-{
- const int aNbTP = fullList.size();
+ SMESHDS_Mesh* pathMeshDS = theTrackMesh->GetMeshDS();
- // Angles
- if( theHasAngles && !theAngles.empty() && theLinearVariation )
- linearAngleVariation(aNbTP-1, theAngles);
+ std::map< int, double > edgeID2OriFactor; // orientation of EDGEs
+ std::map< int, double >::iterator id2factor;
+ SMESH_MesherHelper pathHelper( *theTrackMesh );
+ gp_Pnt p; gp_Vec tangent;
+ const double tol2 = gp::Resolution() * gp::Resolution();
- // fill vector of path points with angles
- vector<SMESH_MeshEditor_PathPoint> aPPs;
- list<SMESH_MeshEditor_PathPoint>::iterator itPP = fullList.begin();
- list<double>::iterator itAngles = theAngles.begin();
- aPPs.push_back( *itPP++ );
- for( ; itPP != fullList.end(); itPP++) {
- aPPs.push_back( *itPP );
- if ( theHasAngles && itAngles != theAngles.end() )
- aPPs.back().SetAngle( *itAngles++ );
- }
+ for ( size_t i = 0; i < pathNodes.size(); ++i )
+ {
+ ExtrusParam::PathPoint & point = points[ i ];
- TNodeOfNodeListMap mapNewNodes;
- TElemOfVecOfNnlmiMap mapElemNewNodes;
- TTElemOfElemListMap newElemsMap;
- TIDSortedElemSet::iterator itElem;
- // source elements for each generated one
- SMESH_SequenceOfElemPtr srcElems, srcNodes;
+ point.myPnt = SMESH_NodeXYZ( pathNodes[ i ]);
- // 3. Center of rotation aV0
- gp_Pnt aV0 = theRefPoint;
- if ( !theHasRefPoint )
- {
- gp_XYZ aGC( 0.,0.,0. );
- TIDSortedElemSet newNodes;
+ if ( angle != theAngles.end() )
+ point.myAngle = *angle++;
- for ( int is2ndSet = 0; is2ndSet < 2; ++is2ndSet )
+ tangent.SetCoord( 0,0,0 );
+ const int shapeID = pathNodes[ i ]->GetShapeID();
+ const TopoDS_Shape& shape = pathMeshDS->IndexToShape( shapeID );
+ TopAbs_ShapeEnum shapeType = shape.IsNull() ? TopAbs_SHAPE : shape.ShapeType();
+ switch ( shapeType )
+ {
+ case TopAbs_EDGE:
{
- TIDSortedElemSet& theElements = theElemSets[ is2ndSet ];
- itElem = theElements.begin();
- for ( ; itElem != theElements.end(); itElem++ )
+ TopoDS_Edge edge = TopoDS::Edge( shape );
+ id2factor = edgeID2OriFactor.insert( std::make_pair( shapeID, 0 )).first;
+ if ( id2factor->second == 0 )
{
- const SMDS_MeshElement* elem = *itElem;
- SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- while ( itN->more() ) {
- const SMDS_MeshElement* node = itN->next();
- if ( newNodes.insert( node ).second )
- aGC += SMESH_TNodeXYZ( node );
- }
+ if ( i ) id2factor->second = getOriFactor( edge, pathNodes[i-1], pathNodes[i], pathHelper );
+ else id2factor->second = getOriFactor( edge, pathNodes[i], pathNodes[i+1], pathHelper );
}
+ double u = pathHelper.GetNodeU( edge, pathNodes[i] ), u0, u1;
+ Handle(Geom_Curve) curve = BRep_Tool::Curve( edge, u0, u1 );
+ curve->D1( u, p, tangent );
+ tangent *= id2factor->second;
+ break;
}
- aGC /= newNodes.size();
- aV0.SetXYZ( aGC );
- } // if (!theHasRefPoint) {
-
- // 4. Processing the elements
- SMESHDS_Mesh* aMesh = GetMeshDS();
- list<const SMDS_MeshNode*> emptyList;
-
- setElemsFirst( theElemSets );
- for ( int is2ndSet = 0; is2ndSet < 2; ++is2ndSet )
- {
- TIDSortedElemSet& theElements = theElemSets[ is2ndSet ];
- for ( itElem = theElements.begin(); itElem != theElements.end(); itElem++ )
+ case TopAbs_VERTEX:
{
- const SMDS_MeshElement* elem = *itElem;
-
- vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
- newNodesItVec.reserve( elem->NbNodes() );
-
- // loop on elem nodes
- int nodeIndex = -1;
- SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- while ( itN->more() )
+ int nbEdges = 0;
+ PShapeIteratorPtr shapeIt = pathHelper.GetAncestors( shape, *theTrackMesh, TopAbs_EDGE );
+ while ( const TopoDS_Shape* edgePtr = shapeIt->next() )
{
- ++nodeIndex;
- // check if a node has been already processed
- const SMDS_MeshNode* node = cast2Node( itN->next() );
- TNodeOfNodeListMap::iterator nIt = mapNewNodes.insert( make_pair( node, emptyList )).first;
- list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
- if ( listNewNodes.empty() )
+ int edgeID = pathMeshDS->ShapeToIndex( *edgePtr );
+ for ( int di = -1; di <= 0; ++di )
{
- // make new nodes
- Standard_Real aAngle1x, aAngleT1T0, aTolAng;
- gp_Pnt aP0x, aP1x, aPN0, aPN1, aV0x, aV1x;
- gp_Ax1 anAx1, anAxT1T0;
- gp_Dir aDT1x, aDT0x, aDT1T0;
-
- aTolAng=1.e-4;
-
- aV0x = aV0;
- aPN0 = SMESH_TNodeXYZ( node );
-
- const SMESH_MeshEditor_PathPoint& aPP0 = aPPs[0];
- aP0x = aPP0.Pnt();
- aDT0x= aPP0.Tangent();
-
- for ( int j = 1; j < aNbTP; ++j ) {
- const SMESH_MeshEditor_PathPoint& aPP1 = aPPs[j];
- aP1x = aPP1.Pnt();
- aDT1x = aPP1.Tangent();
- aAngle1x = aPP1.Angle();
-
- gp_Trsf aTrsf, aTrsfRot, aTrsfRotT1T0;
- // Translation
- gp_Vec aV01x( aP0x, aP1x );
- aTrsf.SetTranslation( aV01x );
-
- // traslated point
- aV1x = aV0x.Transformed( aTrsf );
- aPN1 = aPN0.Transformed( aTrsf );
-
- // rotation 1 [ T1,T0 ]
- aAngleT1T0=-aDT1x.Angle( aDT0x );
- if (fabs(aAngleT1T0) > aTolAng)
+ size_t j = i + di;
+ if ( j < pathEdges.size() && edgeID == pathEdges[ j ]->GetShapeID() )
+ {
+ TopoDS_Edge edge = TopoDS::Edge( *edgePtr );
+ id2factor = edgeID2OriFactor.insert( std::make_pair( edgeID, 0 )).first;
+ if ( id2factor->second == 0 )
{
- aDT1T0=aDT1x^aDT0x;
- anAxT1T0.SetLocation( aV1x );
- anAxT1T0.SetDirection( aDT1T0 );
- aTrsfRotT1T0.SetRotation( anAxT1T0, aAngleT1T0 );
-
- aPN1 = aPN1.Transformed( aTrsfRotT1T0 );
- }
-
- // rotation 2
- if ( theHasAngles ) {
- anAx1.SetLocation( aV1x );
- anAx1.SetDirection( aDT1x );
- aTrsfRot.SetRotation( anAx1, aAngle1x );
-
- aPN1 = aPN1.Transformed( aTrsfRot );
+ if ( j < i )
+ id2factor->second = getOriFactor( edge, pathNodes[i-1], pathNodes[i], pathHelper );
+ else
+ id2factor->second = getOriFactor( edge, pathNodes[i], pathNodes[i+1], pathHelper );
}
-
- // make new node
- if ( elem->IsQuadratic() && !elem->IsMediumNode(node) )
+ double u = pathHelper.GetNodeU( edge, pathNodes[i] ), u0, u1;
+ Handle(Geom_Curve) curve = BRep_Tool::Curve( edge, u0, u1 );
+ gp_Vec du;
+ curve->D1( u, p, du );
+ double size2 = du.SquareMagnitude();
+ if ( du.SquareMagnitude() > tol2 )
{
- // create additional node
- gp_XYZ midP = 0.5 * ( aPN1.XYZ() + aPN0.XYZ() );
- const SMDS_MeshNode* newNode = aMesh->AddNode( midP.X(), midP.Y(), midP.Z() );
- myLastCreatedNodes.Append(newNode);
- srcNodes.Append( node );
- listNewNodes.push_back( newNode );
+ tangent += du.Divided( Sqrt( size2 )) * id2factor->second;
+ nbEdges++;
}
- const SMDS_MeshNode* newNode = aMesh->AddNode( aPN1.X(), aPN1.Y(), aPN1.Z() );
- myLastCreatedNodes.Append(newNode);
- srcNodes.Append( node );
- listNewNodes.push_back( newNode );
-
- aPN0 = aPN1;
- aP0x = aP1x;
- aV0x = aV1x;
- aDT0x = aDT1x;
+ break;
}
}
- else if( elem->IsQuadratic() && !elem->IsMediumNode(node) )
+ }
+ if ( nbEdges > 0 )
+ break;
+ }
+ default:
+ {
+ for ( int di = -1; di <= 1; di += 2 )
+ {
+ size_t j = i + di;
+ if ( j < pathNodes.size() )
{
- // if current elem is quadratic and current node is not medium
- // we have to check - may be it is needed to insert additional nodes
- list< const SMDS_MeshNode* > & listNewNodes = nIt->second;
- if ((int) listNewNodes.size() == aNbTP-1 )
- {
- vector<const SMDS_MeshNode*> aNodes(2*(aNbTP-1));
- gp_XYZ P(node->X(), node->Y(), node->Z());
- list< const SMDS_MeshNode* >::iterator it = listNewNodes.begin();
- int i;
- for(i=0; i<aNbTP-1; i++) {
- const SMDS_MeshNode* N = *it;
- double x = ( N->X() + P.X() )/2.;
- double y = ( N->Y() + P.Y() )/2.;
- double z = ( N->Z() + P.Z() )/2.;
- const SMDS_MeshNode* newN = aMesh->AddNode(x,y,z);
- srcNodes.Append( node );
- myLastCreatedNodes.Append(newN);
- aNodes[2*i] = newN;
- aNodes[2*i+1] = N;
- P = gp_XYZ(N->X(),N->Y(),N->Z());
- }
- listNewNodes.clear();
- for(i=0; i<2*(aNbTP-1); i++) {
- listNewNodes.push_back(aNodes[i]);
- }
- }
+ gp_Vec dir( point.myPnt, SMESH_NodeXYZ( pathNodes[ j ]));
+ double size2 = dir.SquareMagnitude();
+ if ( size2 > tol2 )
+ tangent += dir.Divided( Sqrt( size2 )) * di;
}
-
- newNodesItVec.push_back( nIt );
}
-
- // make new elements
- sweepElement( elem, newNodesItVec, newElemsMap[elem], aNbTP-1, srcElems );
}
- }
+ } // switch ( shapeType )
+
+ if ( tangent.SquareMagnitude() < tol2 )
+ return EXTR_CANT_GET_TANGENT;
- makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElemSets[0], aNbTP-1, srcElems );
+ point.myTgt = tangent;
- if ( theMakeGroups )
- generateGroups( srcNodes, srcElems, "extruded");
+ } // loop on pathNodes
+
+
+ ExtrusParam nodeMaker( points, theRefPoint, theScales, theMakeGroups );
+ TTElemOfElemListMap newElemsMap;
+
+ ExtrusionSweep( theElements, nodeMaker, newElemsMap );
return EXTR_OK;
}
-
//=======================================================================
//function : linearAngleVariation
//purpose : spread values over nbSteps
}
}
+//=======================================================================
+//function : linearScaleVariation
+//purpose : spread values over nbSteps
+//=======================================================================
+
+void SMESH_MeshEditor::linearScaleVariation(const int theNbSteps,
+ std::list<double>& theScales)
+{
+ int nbScales = theScales.size();
+ std::vector<double> myScales;
+ myScales.reserve( theNbSteps );
+ std::list<double>::const_iterator scale = theScales.begin();
+ double prevScale = 1.0;
+ for ( int iSc = 1; scale != theScales.end(); ++scale, ++iSc )
+ {
+ int iStep = int( iSc / double( nbScales ) * theNbSteps + 0.5 );
+ int stDelta = Max( 1, iStep - myScales.size());
+ double scDelta = ( *scale - prevScale ) / stDelta;
+ for ( int iStep = 0; iStep < stDelta; ++iStep )
+ {
+ myScales.push_back( prevScale + scDelta );
+ prevScale = myScales.back();
+ }
+ prevScale = *scale;
+ }
+ theScales.assign( myScales.begin(), myScales.end() );
+}
//================================================================================
/*!
const bool theMakeGroups,
SMESH_Mesh* theTargetMesh)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
+ myLastCreatedElems.reserve( theElems.size() );
bool needReverse = false;
string groupPostfix;
if ( theTargetMesh ) {
const SMDS_MeshNode * newNode = aTgtMesh->AddNode( coord[0], coord[1], coord[2] );
n2n_isnew.first->second = newNode;
- myLastCreatedNodes.Append(newNode);
- srcNodes.Append( node );
+ myLastCreatedNodes.push_back(newNode);
+ srcNodes.push_back( node );
}
else if ( theCopy ) {
const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
n2n_isnew.first->second = newNode;
- myLastCreatedNodes.Append(newNode);
- srcNodes.Append( node );
+ myLastCreatedNodes.push_back(newNode);
+ srcNodes.push_back( node );
}
else {
aMesh->MoveNode( node, coord[0], coord[1], coord[2] );
if ( geomType == SMDSGeom_POLYHEDRA ) // ------------------ polyhedral volume
{
- const SMDS_VtkVolume* aPolyedre = dynamic_cast<const SMDS_VtkVolume*>( elem );
- if (!aPolyedre)
+ const SMDS_MeshVolume* aPolyedre = SMDS_Mesh::DownCast< SMDS_MeshVolume >( elem );
+ if ( !aPolyedre )
continue;
nodes.clear();
bool allTransformed = true;
if ( editor ) {
// copy in this or a new mesh
if ( editor->AddElement( nodes, elemType.Init( elem, /*basicOnly=*/false )))
- srcElems.Append( elem );
+ srcElems.push_back( elem );
}
else {
// reverse element as it was reversed by transformation
} // loop on elements
if ( editor && editor != this )
- myLastCreatedElems = editor->myLastCreatedElems;
+ myLastCreatedElems.swap( editor->myLastCreatedElems );
PGroupIDs newGroupIDs;
return newGroupIDs;
}
+//================================================================================
+/*!
+ * \brief Make an offset mesh from a source 2D mesh
+ * \param [in] theElements - source faces
+ * \param [in] theValue - offset value
+ * \param [out] theTgtMesh - a mesh to add offset elements to
+ * \param [in] theMakeGroups - to generate groups
+ * \return PGroupIDs - IDs of created groups
+ */
+//================================================================================
+
+SMESH_MeshEditor::PGroupIDs SMESH_MeshEditor::Offset( TIDSortedElemSet & theElements,
+ const double theValue,
+ SMESH_Mesh* theTgtMesh,
+ const bool theMakeGroups,
+ const bool theCopyElements,
+ const bool theFixSelfIntersection)
+{
+ SMESHDS_Mesh* meshDS = GetMeshDS();
+ SMESHDS_Mesh* tgtMeshDS = theTgtMesh->GetMeshDS();
+ SMESH_MeshEditor tgtEditor( theTgtMesh );
+
+ SMDS_ElemIteratorPtr eIt;
+ if ( theElements.empty() ) eIt = meshDS->elementsIterator( SMDSAbs_Face );
+ else eIt = SMESHUtils::elemSetIterator( theElements );
+
+ SMESH_MeshAlgos::TElemIntPairVec new2OldFaces;
+ SMESH_MeshAlgos::TNodeIntPairVec new2OldNodes;
+ std::unique_ptr< SMDS_Mesh > offsetMesh
+ ( SMESH_MeshAlgos::MakeOffset( eIt, *meshDS, theValue,
+ theFixSelfIntersection,
+ new2OldFaces, new2OldNodes ));
+ if ( offsetMesh->NbElements() == 0 )
+ return PGroupIDs(); // MakeOffset() failed
+
+
+ if ( theTgtMesh == myMesh && !theCopyElements )
+ {
+ // clear the source elements
+ if ( theElements.empty() ) eIt = meshDS->elementsIterator( SMDSAbs_Face );
+ else eIt = SMESHUtils::elemSetIterator( theElements );
+ while ( eIt->more() )
+ meshDS->RemoveFreeElement( eIt->next(), 0 );
+ }
+
+ // offsetMesh->Modified();
+ // offsetMesh->CompactMesh(); // make IDs start from 1
+
+ // source elements for each generated one
+ SMESH_SequenceOfElemPtr srcElems, srcNodes;
+ srcElems.reserve( new2OldFaces.size() );
+ srcNodes.reserve( new2OldNodes.size() );
+
+ ClearLastCreated();
+ myLastCreatedElems.reserve( new2OldFaces.size() );
+ myLastCreatedNodes.reserve( new2OldNodes.size() );
+
+ // copy offsetMesh to theTgtMesh
+
+ int idShift = meshDS->MaxNodeID();
+ for ( size_t i = 0; i < new2OldNodes.size(); ++i )
+ if ( const SMDS_MeshNode* n = new2OldNodes[ i ].first )
+ {
+#ifndef _DEBUG_
+ if ( n->NbInverseElements() > 0 )
+#endif
+ {
+ const SMDS_MeshNode* n2 =
+ tgtMeshDS->AddNodeWithID( n->X(), n->Y(), n->Z(), idShift + n->GetID() );
+ myLastCreatedNodes.push_back( n2 );
+ srcNodes.push_back( meshDS->FindNode( new2OldNodes[ i ].second ));
+ }
+ }
+
+ ElemFeatures elemType;
+ for ( size_t i = 0; i < new2OldFaces.size(); ++i )
+ if ( const SMDS_MeshElement* f = new2OldFaces[ i ].first )
+ {
+ elemType.Init( f );
+ elemType.myNodes.clear();
+ for ( SMDS_NodeIteratorPtr nIt = f->nodeIterator(); nIt->more(); )
+ {
+ const SMDS_MeshNode* n2 = nIt->next();
+ elemType.myNodes.push_back( tgtMeshDS->FindNode( idShift + n2->GetID() ));
+ }
+ tgtEditor.AddElement( elemType.myNodes, elemType );
+ srcElems.push_back( meshDS->FindElement( new2OldFaces[ i ].second ));
+ }
+
+ myLastCreatedElems.swap( tgtEditor.myLastCreatedElems );
+
+ PGroupIDs newGroupIDs;
+ if ( theMakeGroups )
+ newGroupIDs = generateGroups( srcNodes, srcElems, "offset", theTgtMesh, false );
+
+ return newGroupIDs;
+}
+
//=======================================================================
/*!
* \brief Create groups of elements made during transformation
* \param nodeGens - nodes making corresponding myLastCreatedNodes
* \param elemGens - elements making corresponding myLastCreatedElems
- * \param postfix - to append to names of new groups
+ * \param postfix - to push_back to names of new groups
* \param targetMesh - mesh to create groups in
- * \param topPresent - is there "top" elements that are created by sweeping
+ * \param topPresent - is there are "top" elements that are created by sweeping
*/
//=======================================================================
{
const SMESH_SequenceOfElemPtr& gens = isNodes ? nodeGens : elemGens;
const SMESH_SequenceOfElemPtr& elems = isNodes ? myLastCreatedNodes : myLastCreatedElems;
- if ( gens.Length() != elems.Length() )
+ if ( gens.size() != elems.size() )
throw SALOME_Exception("SMESH_MeshEditor::generateGroups(): invalid args");
// loop on created elements
- for (int iElem = 1; iElem <= elems.Length(); ++iElem )
+ for (size_t iElem = 0; iElem < elems.size(); ++iElem )
{
- const SMDS_MeshElement* sourceElem = gens( iElem );
+ const SMDS_MeshElement* sourceElem = gens[ iElem ];
if ( !sourceElem ) {
MESSAGE("generateGroups(): NULL source element");
continue;
}
list< TOldNewGroup > & groupsOldNew = groupsByType[ sourceElem->GetType() ];
if ( groupsOldNew.empty() ) { // no groups of this type at all
- while ( iElem < gens.Length() && gens( iElem+1 ) == sourceElem )
+ while ( iElem+1 < gens.size() && gens[ iElem+1 ] == sourceElem )
++iElem; // skip all elements made by sourceElem
continue;
}
// collect all elements made by the iElem-th sourceElem
resultElems.clear();
- if ( const SMDS_MeshElement* resElem = elems( iElem ))
+ if ( const SMDS_MeshElement* resElem = elems[ iElem ])
if ( resElem != sourceElem )
resultElems.push_back( resElem );
- while ( iElem < gens.Length() && gens( iElem+1 ) == sourceElem )
- if ( const SMDS_MeshElement* resElem = elems( ++iElem ))
+ while ( iElem+1 < gens.size() && gens[ iElem+1 ] == sourceElem )
+ if ( const SMDS_MeshElement* resElem = elems[ ++iElem ])
if ( resElem != sourceElem )
resultElems.push_back( resElem );
{
SMDS_MeshGroup & newTopGroup = gOldNew->get<2>()->SMDSGroup();
newTopGroup.Add( topElem );
- }
+ }
}
}
} // loop on created elements
TListOfListOfNodes & theGroupsOfNodes,
bool theSeparateCornersAndMedium)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
if ( myMesh->NbEdges ( ORDER_QUADRATIC ) +
myMesh->NbFaces ( ORDER_QUADRATIC ) +
if ( theNodes.empty() ) // get all nodes in the mesh
{
TIDSortedNodeSet* nodes[2] = { &corners, &medium };
- SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator(/*idInceasingOrder=*/true);
+ SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator();
if ( theSeparateCornersAndMedium )
while ( nIt->more() )
{
void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes,
const bool theAvoidMakingHoles)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
SMESHDS_Mesh* mesh = GetMeshDS();
const SMDS_MeshNode* nToKeep = nnIt->second;
TNodeNodeMap::iterator nnIt_i = nodeNodeMap.find( nToKeep );
while ( nnIt_i != nodeNodeMap.end() && nnIt_i->second != nnIt->second )
+ {
nToKeep = nnIt_i->second;
- nnIt->second = nToKeep;
+ nnIt->second = nToKeep;
+ nnIt_i = nodeNodeMap.find( nToKeep );
+ }
}
if ( theAvoidMakingHoles )
AddToSameGroups( nToKeep, nToRemove, mesh );
// set _alwaysComputed to a sub-mesh of VERTEX to enable further mesh computing
// w/o creating node in place of merged ones.
- const SMDS_PositionPtr& pos = nToRemove->GetPosition();
+ SMDS_PositionPtr pos = nToRemove->GetPosition();
if ( pos && pos->GetTypeOfPosition() == SMDS_TOP_VERTEX )
if ( SMESH_subMesh* sm = myMesh->GetSubMeshContaining( nToRemove->getshapeId() ))
sm->SetIsAlwaysComputed( true );
if ( nbUniqueNodes >= 4 )
{
// each face has to be analyzed in order to check volume validity
- if ( const SMDS_VtkVolume* aPolyedre = dynamic_cast<const SMDS_VtkVolume*>( elem ))
+ if ( const SMDS_MeshVolume* aPolyedre = SMDS_Mesh::DownCast< SMDS_MeshVolume >( elem ))
{
int nbFaces = aPolyedre->NbFaces();
// ========================================================
-// class : SortableElement
-// purpose : allow sorting elements basing on their nodes
+// class : ComparableElement
+// purpose : allow comparing elements basing on their nodes
// ========================================================
-class SortableElement : public set <const SMDS_MeshElement*>
+
+class ComparableElement : public boost::container::flat_set< int >
{
+ typedef boost::container::flat_set< int > int_set;
+
+ const SMDS_MeshElement* myElem;
+ int mySumID;
+ mutable int myGroupID;
+
public:
- SortableElement( const SMDS_MeshElement* theElem )
+ ComparableElement( const SMDS_MeshElement* theElem ):
+ myElem ( theElem ), mySumID( 0 ), myGroupID( -1 )
{
- myElem = theElem;
- SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator();
- while ( nodeIt->more() )
- this->insert( nodeIt->next() );
+ this->reserve( theElem->NbNodes() );
+ for ( SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator(); nodeIt->more(); )
+ {
+ int id = nodeIt->next()->GetID();
+ mySumID += id;
+ this->insert( id );
+ }
}
- const SMDS_MeshElement* Get() const
- { return myElem; }
+ const SMDS_MeshElement* GetElem() const { return myElem; }
+
+ int& GroupID() const { return myGroupID; }
+ //int& GroupID() const { return const_cast< int& >( myGroupID ); }
+
+ ComparableElement( const ComparableElement& theSource ) // move copy
+ {
+ ComparableElement& src = const_cast< ComparableElement& >( theSource );
+ (int_set&) (*this ) = boost::move( src );
+ myElem = src.myElem;
+ mySumID = src.mySumID;
+ myGroupID = src.myGroupID;
+ }
+
+ static int HashCode(const ComparableElement& se, int limit )
+ {
+ return ::HashCode( se.mySumID, limit );
+ }
+ static Standard_Boolean IsEqual(const ComparableElement& se1, const ComparableElement& se2 )
+ {
+ return ( se1 == se2 );
+ }
-private:
- mutable const SMDS_MeshElement* myElem;
};
//=======================================================================
// Search among theElements or in the whole mesh if theElements is empty
//=======================================================================
-void SMESH_MeshEditor::FindEqualElements(TIDSortedElemSet & theElements,
- TListOfListOfElementsID & theGroupsOfElementsID)
+void SMESH_MeshEditor::FindEqualElements( TIDSortedElemSet & theElements,
+ TListOfListOfElementsID & theGroupsOfElementsID )
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
-
- typedef map< SortableElement, int > TMapOfNodeSet;
- typedef list<int> TGroupOfElems;
+ ClearLastCreated();
SMDS_ElemIteratorPtr elemIt;
if ( theElements.empty() ) elemIt = GetMeshDS()->elementsIterator();
- else elemIt = elemSetIterator( theElements );
+ else elemIt = SMESHUtils::elemSetIterator( theElements );
- vector< TGroupOfElems > arrayOfGroups;
- TGroupOfElems groupOfElems;
- TMapOfNodeSet mapOfNodeSet;
+ typedef NCollection_Map< ComparableElement, ComparableElement > TMapOfElements;
+ typedef std::list<int> TGroupOfElems;
+ TMapOfElements mapOfElements;
+ std::vector< TGroupOfElems > arrayOfGroups;
+ TGroupOfElems groupOfElems;
- for ( int iGroup = 0; elemIt->more(); )
+ while ( elemIt->more() )
{
const SMDS_MeshElement* curElem = elemIt->next();
- SortableElement SE(curElem);
+ ComparableElement compElem = curElem;
// check uniqueness
- pair< TMapOfNodeSet::iterator, bool> pp = mapOfNodeSet.insert(make_pair(SE, iGroup));
- if ( !pp.second ) { // one more coincident elem
- TMapOfNodeSet::iterator& itSE = pp.first;
- int iG = itSE->second;
+ const ComparableElement& elemInSet = mapOfElements.Added( compElem );
+ if ( elemInSet.GetElem() != curElem ) // coincident elem
+ {
+ int& iG = elemInSet.GroupID();
+ if ( iG < 0 )
+ {
+ iG = arrayOfGroups.size();
+ arrayOfGroups.push_back( groupOfElems );
+ arrayOfGroups[ iG ].push_back( elemInSet.GetElem()->GetID() );
+ }
arrayOfGroups[ iG ].push_back( curElem->GetID() );
}
- else {
- arrayOfGroups.push_back( groupOfElems );
- arrayOfGroups.back().push_back( curElem->GetID() );
- iGroup++;
- }
}
groupOfElems.clear();
- vector< TGroupOfElems >::iterator groupIt = arrayOfGroups.begin();
+ std::vector< TGroupOfElems >::iterator groupIt = arrayOfGroups.begin();
for ( ; groupIt != arrayOfGroups.end(); ++groupIt )
{
if ( groupIt->size() > 1 ) {
- //groupOfElems.sort(); -- theElements is sorted already
- theGroupsOfElementsID.push_back( groupOfElems );
- theGroupsOfElementsID.back().splice( theGroupsOfElementsID.back().end(), *groupIt );
+ //groupOfElems.sort(); -- theElements are sorted already
+ theGroupsOfElementsID.emplace_back( *groupIt );
}
}
}
void SMESH_MeshEditor::MergeElements(TListOfListOfElementsID & theGroupsOfElementsID)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
typedef list<int> TListOfIDs;
TListOfIDs rmElemIds; // IDs of elems to remove
TIDSortedElemSet aMeshElements; /* empty input ==
to merge equal elements in the whole mesh */
TListOfListOfElementsID aGroupsOfElementsID;
- FindEqualElements(aMeshElements, aGroupsOfElementsID);
- MergeElements(aGroupsOfElementsID);
+ FindEqualElements( aMeshElements, aGroupsOfElementsID );
+ MergeElements( aGroupsOfElementsID );
}
//=======================================================================
theNodes.push_back( theSecondNode );
const SMDS_MeshNode *nIgnore = theFirstNode, *nStart = theSecondNode;
- TIDSortedElemSet foundElems;
+ //TIDSortedElemSet foundElems;
bool needTheLast = ( theLastNode != 0 );
+ vector<const SMDS_MeshNode*> nodes;
+
while ( nStart != theLastNode ) {
if ( nStart == theFirstNode )
return !needTheLast;
- // find all free border faces sharing form nStart
+ // find all free border faces sharing nStart
list< const SMDS_MeshElement* > curElemList;
list< const SMDS_MeshNode* > nStartList;
SMDS_ElemIteratorPtr invElemIt = nStart->GetInverseElementIterator(SMDSAbs_Face);
while ( invElemIt->more() ) {
const SMDS_MeshElement* e = invElemIt->next();
- if ( e == curElem || foundElems.insert( e ).second ) {
+ //if ( e == curElem || foundElems.insert( e ).second ) // e can encounter twice in border
+ {
// get nodes
- int iNode = 0, nbNodes = e->NbNodes();
- vector<const SMDS_MeshNode*> nodes(nbNodes+1);
-
- if ( e->IsQuadratic() ) {
- const SMDS_VtkFace* F =
- dynamic_cast<const SMDS_VtkFace*>(e);
- if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
- // use special nodes iterator
- SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
- while( anIter->more() ) {
- nodes[ iNode++ ] = cast2Node(anIter->next());
- }
- }
- else {
- SMDS_ElemIteratorPtr nIt = e->nodesIterator();
- while ( nIt->more() )
- nodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
- }
- nodes[ iNode ] = nodes[ 0 ];
+ nodes.assign( SMDS_MeshElement::iterator( e->interlacedNodesIterator() ),
+ SMDS_MeshElement::iterator() );
+ nodes.push_back( nodes[ 0 ]);
+
// check 2 links
+ int iNode = 0, nbNodes = nodes.size() - 1;
for ( iNode = 0; iNode < nbNodes; iNode++ )
- if (((nodes[ iNode ] == nStart && nodes[ iNode + 1] != nIgnore ) ||
- (nodes[ iNode + 1] == nStart && nodes[ iNode ] != nIgnore )) &&
- ControlFreeBorder( &nodes[ iNode ], e->GetID() ))
+ if ((( nodes[ iNode ] == nStart && nodes[ iNode + 1] != nIgnore ) ||
+ ( nodes[ iNode + 1] == nStart && nodes[ iNode ] != nIgnore )) &&
+ ( ControlFreeBorder( &nodes[ iNode ], e->GetID() )))
{
- nStartList.push_back( nodes[ iNode + ( nodes[ iNode ] == nStart ? 1 : 0 )]);
+ nStartList.push_back( nodes[ iNode + ( nodes[ iNode ] == nStart )]);
curElemList.push_back( e );
}
}
else if ( !contNodes[0].empty() && !contNodes[1].empty() ) {
// choice: clear a worse one
int iLongest = ( contNodes[0].size() < contNodes[1].size() ? 1 : 0 );
- int iWorse = ( needTheLast ? 1 - iLongest : iLongest );
+ int iWorse = ( needTheLast ? 1 - iLongest : iLongest );
contNodes[ iWorse ].clear();
contFaces[ iWorse ].clear();
}
if ( contNodes[0].empty() && contNodes[1].empty() )
return false;
- // append the best free border
+ // push_back the best free border
cNL = & contNodes[ contNodes[0].empty() ? 1 : 0 ];
cFL = & contFaces[ contFaces[0].empty() ? 1 : 0 ];
- theNodes.pop_back(); // remove nIgnore
+ //theNodes.pop_back(); // remove nIgnore
theNodes.pop_back(); // remove nStart
- theFaces.pop_back(); // remove curElem
- list< const SMDS_MeshNode* >::iterator nIt = cNL->begin();
- list< const SMDS_MeshElement* >::iterator fIt = cFL->begin();
- for ( ; nIt != cNL->end(); nIt++ ) theNodes.push_back( *nIt );
- for ( ; fIt != cFL->end(); fIt++ ) theFaces.push_back( *fIt );
+ //theFaces.pop_back(); // remove curElem
+ theNodes.splice( theNodes.end(), *cNL );
+ theFaces.splice( theFaces.end(), *cFL );
return true;
} // several continuations found
const bool toCreatePolygons,
const bool toCreatePolyedrs)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
Sew_Error aResult = SEW_OK;
const SMDS_MeshNode** nodes = isVolume ? volume.GetNodes() : & faceNodes[0];
if ( isVolume ) // --volume
hasVolumes = true;
- else if ( elem->GetType()==SMDSAbs_Face ) { // --face
+ else if ( elem->GetType() == SMDSAbs_Face ) { // --face
// retrieve all face nodes and find iPrevNode - an index of the prevSideNode
- if(elem->IsQuadratic()) {
- const SMDS_VtkFace* F =
- dynamic_cast<const SMDS_VtkFace*>(elem);
- if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
- // use special nodes iterator
- SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
- while( anIter->more() ) {
- nodes[ iNode ] = cast2Node(anIter->next());
- if ( nodes[ iNode++ ] == prevSideNode )
- iPrevNode = iNode - 1;
- }
- }
- else {
- SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
- while ( nIt->more() ) {
- nodes[ iNode ] = cast2Node( nIt->next() );
- if ( nodes[ iNode++ ] == prevSideNode )
- iPrevNode = iNode - 1;
- }
+ SMDS_NodeIteratorPtr nIt = elem->interlacedNodesIterator();
+ while ( nIt->more() ) {
+ nodes[ iNode ] = cast2Node( nIt->next() );
+ if ( nodes[ iNode++ ] == prevSideNode )
+ iPrevNode = iNode - 1;
}
// there are 2 links to check
nbNodes = 2;
nIt[0] = nSide[0].begin(); eIt[0] = eSide[0].begin();
nIt[1] = nSide[1].begin(); eIt[1] = eSide[1].begin();
+ // element can be split while iterating on border if it has two edges in the border
+ std::map< const SMDS_MeshElement* , const SMDS_MeshElement* > elemReplaceMap;
+ std::map< const SMDS_MeshElement* , const SMDS_MeshElement* >::iterator elemReplaceMapIt;
+
TElemOfNodeListMap insertMap;
TElemOfNodeListMap::iterator insertMapIt;
// insertMap is
const SMDS_MeshNode* nIns = *nIt [ 1 - intoBord ];
if ( intoBord == 1 ) {
// move node of the border to be on a link of elem of the side
- gp_XYZ p1 (n1->X(), n1->Y(), n1->Z());
- gp_XYZ p2 (n2->X(), n2->Y(), n2->Z());
+ SMESH_NodeXYZ p1( n1 ), p2( n2 );
double ratio = du / ( param[ 1 ][ i[1] ] - param[ 1 ][ i[1]-1 ]);
gp_XYZ p = p2 * ( 1 - ratio ) + p1 * ratio;
GetMeshDS()->MoveNode( nIns, p.X(), p.Y(), p.Z() );
}
+ elemReplaceMapIt = elemReplaceMap.find( elem );
+ if ( elemReplaceMapIt != elemReplaceMap.end() )
+ elem = elemReplaceMapIt->second;
+
insertMapIt = insertMap.find( elem );
bool notFound = ( insertMapIt == insertMap.end() );
bool otherLink = ( !notFound && (*insertMapIt).second.front() != n1 );
UpdateVolumes(n12, n22, nodeList);
}
// 3. find an element appeared on n1 and n2 after the insertion
- insertMap.erase( elem );
- elem = findAdjacentFace( n1, n2, 0 );
+ insertMap.erase( insertMapIt );
+ const SMDS_MeshElement* elem2 = findAdjacentFace( n1, n2, 0 );
+ elemReplaceMap.insert( std::make_pair( elem, elem2 ));
+ elem = elem2;
}
if ( notFound || otherLink ) {
// add element and nodes of the side into the insertMap
{
const SMDS_MeshElement* elem = (*insertMapIt).first;
list<const SMDS_MeshNode*> & nodeList = (*insertMapIt).second;
+ if ( nodeList.size() < 3 ) continue;
const SMDS_MeshNode* n1 = nodeList.front(); nodeList.pop_front();
const SMDS_MeshNode* n2 = nodeList.front(); nodeList.pop_front();
// get new segments
TIDSortedElemSet segments;
SMESH_SequenceOfElemPtr newFaces;
- for ( int i = 1; i <= myLastCreatedElems.Length(); ++i )
+ for ( size_t i = 0; i < myLastCreatedElems.size(); ++i )
{
- if ( !myLastCreatedElems(i) ) continue;
- if ( myLastCreatedElems(i)->GetType() == SMDSAbs_Edge )
- segments.insert( segments.end(), myLastCreatedElems(i) );
+ if ( !myLastCreatedElems[i] ) continue;
+ if ( myLastCreatedElems[i]->GetType() == SMDSAbs_Edge )
+ segments.insert( segments.end(), myLastCreatedElems[i] );
else
- newFaces.Append( myLastCreatedElems(i) );
+ newFaces.push_back( myLastCreatedElems[i] );
}
// get segments adjacent to merged nodes
TListOfListOfNodes::iterator groupIt = nodeGroupsToMerge.begin();
for ( ; groupIt != nodeGroupsToMerge.end(); groupIt++ )
{
const list<const SMDS_MeshNode*>& nodes = *groupIt;
+ if ( nodes.front()->IsNull() ) continue;
SMDS_ElemIteratorPtr segIt = nodes.front()->GetInverseElementIterator( SMDSAbs_Edge );
while ( segIt->more() )
segments.insert( segIt->next() );
myLastCreatedElems = newFaces;
TIDSortedElemSet::iterator seg = segments.begin();
for ( ; seg != segments.end(); ++seg )
- myLastCreatedElems.Append( *seg );
+ myLastCreatedElems.push_back( *seg );
}
return aResult;
if ( newElems[i] )
{
aMesh->SetMeshElementOnShape( newElems[i], theElement->getshapeId() );
- myLastCreatedElems.Append( newElems[i] );
+ myLastCreatedElems.push_back( newElems[i] );
}
ReplaceElemInGroups( theElement, newElems, aMesh );
aMesh->RemoveElement( theElement );
// add nodes of face up to first node of link
bool isFLN = false;
-
- if ( theFace->IsQuadratic() ) {
- const SMDS_VtkFace* F = dynamic_cast<const SMDS_VtkFace*>(theFace);
- if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
- // use special nodes iterator
- SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
- while( anIter->more() && !isFLN ) {
- const SMDS_MeshNode* n = cast2Node(anIter->next());
- poly_nodes[iNode++] = n;
- if (n == nodes[il1]) {
- isFLN = true;
- }
- }
- // add nodes to insert
- list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
- for (; nIt != aNodesToInsert.end(); nIt++) {
- poly_nodes[iNode++] = *nIt;
- }
- // add nodes of face starting from last node of link
- while ( anIter->more() ) {
- poly_nodes[iNode++] = cast2Node(anIter->next());
- }
+ SMDS_NodeIteratorPtr nodeIt = theFace->interlacedNodesIterator();
+ while ( nodeIt->more() && !isFLN ) {
+ const SMDS_MeshNode* n = nodeIt->next();
+ poly_nodes[iNode++] = n;
+ isFLN = ( n == nodes[il1] );
}
- else {
- SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator();
- while ( nodeIt->more() && !isFLN ) {
- const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
- poly_nodes[iNode++] = n;
- if (n == nodes[il1]) {
- isFLN = true;
- }
- }
- // add nodes to insert
- list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
- for (; nIt != aNodesToInsert.end(); nIt++) {
- poly_nodes[iNode++] = *nIt;
- }
- // add nodes of face starting from last node of link
- while ( nodeIt->more() ) {
- const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
- poly_nodes[iNode++] = n;
- }
+ // add nodes to insert
+ list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
+ for (; nIt != aNodesToInsert.end(); nIt++) {
+ poly_nodes[iNode++] = *nIt;
+ }
+ // add nodes of face starting from last node of link
+ while ( nodeIt->more() ) {
+ const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+ poly_nodes[iNode++] = n;
}
// make a new face
if ( newElems[i] )
{
aMesh->SetMeshElementOnShape( newElems[i], theFace->getshapeId() );
- myLastCreatedElems.Append( newElems[i] );
+ myLastCreatedElems.push_back( newElems[i] );
}
ReplaceElemInGroups( theFace, newElems, aMesh );
aMesh->RemoveElement(theFace);
const SMDS_MeshNode* theBetweenNode2,
list<const SMDS_MeshNode*>& theNodesToInsert)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
SMDS_ElemIteratorPtr invElemIt = theBetweenNode1->GetInverseElementIterator(SMDSAbs_Volume);
while (invElemIt->more()) { // loop on inverse elements of theBetweenNode1
if ( SMDS_MeshElement* newElem = aMesh->AddPolyhedralVolume( poly_nodes, quantities ))
{
aMesh->SetMeshElementOnShape( newElem, elem->getshapeId() );
- myLastCreatedElems.Append( newElem );
+ myLastCreatedElems.push_back( newElem );
ReplaceElemInGroups( elem, newElem, aMesh );
}
aMesh->RemoveElement( elem );
const int nbNodes = elem->NbCornerNodes();
nodes.assign(elem->begin_nodes(), elem->end_nodes());
if ( aGeomType == SMDSEntity_Polyhedra )
- nbNodeInFaces = static_cast<const SMDS_VtkVolume* >( elem )->GetQuantities();
+ nbNodeInFaces = static_cast<const SMDS_MeshVolume* >( elem )->GetQuantities();
else if ( aGeomType == SMDSEntity_Hexagonal_Prism )
volumeToPolyhedron( elem, nodes, nbNodeInFaces );
switch( aType )
{
case SMDSAbs_Edge :
- {
- NewElem = theHelper.AddEdge(nodes[0], nodes[1], id, theForce3d);
- break;
- }
+ {
+ NewElem = theHelper.AddEdge(nodes[0], nodes[1], id, theForce3d);
+ break;
+ }
case SMDSAbs_Face :
+ {
+ switch(nbNodes)
{
- switch(nbNodes)
- {
- case 3:
- NewElem = theHelper.AddFace(nodes[0], nodes[1], nodes[2], id, theForce3d);
- break;
- case 4:
- NewElem = theHelper.AddFace(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d);
- break;
- default:
- NewElem = theHelper.AddPolygonalFace(nodes, id, theForce3d);
- }
+ case 3:
+ NewElem = theHelper.AddFace(nodes[0], nodes[1], nodes[2], id, theForce3d);
break;
+ case 4:
+ NewElem = theHelper.AddFace(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d);
+ break;
+ default:
+ NewElem = theHelper.AddPolygonalFace(nodes, id, theForce3d);
}
+ break;
+ }
case SMDSAbs_Volume :
+ {
+ switch( aGeomType )
{
- switch( aGeomType )
- {
- case SMDSEntity_Tetra:
- NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d);
- break;
- case SMDSEntity_Pyramid:
- NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], id, theForce3d);
- break;
- case SMDSEntity_Penta:
- case SMDSEntity_Quad_Penta:
- case SMDSEntity_BiQuad_Penta:
- NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d);
- break;
- case SMDSEntity_Hexa:
- case SMDSEntity_Quad_Hexa:
- case SMDSEntity_TriQuad_Hexa:
- NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
- nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
- break;
- case SMDSEntity_Hexagonal_Prism:
- default:
- NewElem = theHelper.AddPolyhedralVolume(nodes, nbNodeInFaces, id, theForce3d);
- }
+ case SMDSEntity_Tetra:
+ NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d);
+ break;
+ case SMDSEntity_Pyramid:
+ NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], id, theForce3d);
+ break;
+ case SMDSEntity_Penta:
+ case SMDSEntity_Quad_Penta:
+ case SMDSEntity_BiQuad_Penta:
+ NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d);
break;
+ case SMDSEntity_Hexa:
+ case SMDSEntity_Quad_Hexa:
+ case SMDSEntity_TriQuad_Hexa:
+ NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
+ nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
+ break;
+ case SMDSEntity_Hexagonal_Prism:
+ default:
+ NewElem = theHelper.AddPolyhedralVolume(nodes, nbNodeInFaces, id, theForce3d);
}
+ break;
+ }
default :
continue;
}
const int id = volume->GetID();
vector<const SMDS_MeshNode *> nodes (volume->begin_nodes(), volume->end_nodes());
if ( type == SMDSEntity_Polyhedra )
- nbNodeInFaces = static_cast<const SMDS_VtkVolume* >(volume)->GetQuantities();
+ nbNodeInFaces = static_cast<const SMDS_MeshVolume* >(volume)->GetQuantities();
else if ( type == SMDSEntity_Hexagonal_Prism )
volumeToPolyhedron( volume, nodes, nbNodeInFaces );
if( newElem && smDS )
smDS->AddElement( newElem );
- // remove central nodes
+ // remove central nodes
for ( size_t i = nodes.size() - nbCentralNodes; i < nodes.size(); ++i )
if ( nodes[i]->NbInverseElements() == 0 )
meshDS->RemoveFreeNode( nodes[i], smDS, /*fromGroups=*/true );
}
// replace given elements by linear ones
- SMDS_ElemIteratorPtr elemIt = elemSetIterator( theElements );
+ SMDS_ElemIteratorPtr elemIt = SMESHUtils::elemSetIterator( theElements );
removeQuadElem( /*theSm=*/0, elemIt, /*theShapeID=*/0 );
// we need to convert remaining elements whose all medium nodes are in mediumNodeIDs
}
}
}
- elemIt = elemSetIterator( moreElemsToConvert );
+ elemIt = SMESHUtils::elemSetIterator( moreElemsToConvert );
removeQuadElem( /*theSm=*/0, elemIt, /*theShapeID=*/0 );
}
const SMDS_MeshNode* theSecondNode1,
const SMDS_MeshNode* theSecondNode2)
{
- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
+ ClearLastCreated();
if ( theSide1.size() != theSide2.size() )
return SEW_DIFF_NB_OF_ELEMENTS;
if ( faceSet1.size() != faceSet2.size() ) {
// delete temporary faces: they are in reverseElements of actual nodes
-// SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator();
-// while ( tmpFaceIt->more() )
-// aTmpFacesMesh.RemoveElement( tmpFaceIt->next() );
-// list<const SMDS_MeshElement* >::iterator tmpFaceIt = tempFaceList.begin();
-// for (; tmpFaceIt !=tempFaceList.end(); ++tmpFaceIt)
-// aMesh->RemoveElement(*tmpFaceIt);
+ // SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator();
+ // while ( tmpFaceIt->more() )
+ // aTmpFacesMesh.RemoveElement( tmpFaceIt->next() );
+ // list<const SMDS_MeshElement* >::iterator tmpFaceIt = tempFaceList.begin();
+ // for (; tmpFaceIt !=tempFaceList.end(); ++tmpFaceIt)
+ // aMesh->RemoveElement(*tmpFaceIt);
MESSAGE("Diff nb of faces");
return SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
}
//cout << " F " << face[ iSide]->GetID() <<endl;
faceSetPtr[ iSide ]->erase( face[ iSide ]);
// put face nodes to fnodes
- if ( face[ iSide ]->IsQuadratic() )
- {
- // use interlaced nodes iterator
- const SMDS_VtkFace* F = dynamic_cast<const SMDS_VtkFace*>( face[ iSide ]);
- if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
- SMDS_ElemIteratorPtr nIter = F->interlacedNodesElemIterator();
- while ( nIter->more() )
- fnodes[ iSide ].push_back( cast2Node( nIter->next() ));
- }
- else
- {
- fnodes[ iSide ].assign( face[ iSide ]->begin_nodes(),
- face[ iSide ]->end_nodes() );
- }
+ SMDS_MeshElement::iterator nIt( face[ iSide ]->interlacedNodesIterator() ), nEnd;
+ fnodes[ iSide ].assign( nIt, nEnd );
fnodes[ iSide ].push_back( fnodes[ iSide ].front());
}
}
if ( aResult == SEW_OK &&
( //linkIt[0] != linkList[0].end() ||
- !faceSetPtr[0]->empty() || !faceSetPtr[1]->empty() )) {
+ !faceSetPtr[0]->empty() || !faceSetPtr[1]->empty() )) {
MESSAGE( (linkIt[0] != linkList[0].end()) <<" "<< (faceSetPtr[0]->empty()) <<
" " << (faceSetPtr[1]->empty()));
aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
// ====================================================================
// delete temporary faces
-// SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator();
-// while ( tmpFaceIt->more() )
-// aTmpFacesMesh.RemoveElement( tmpFaceIt->next() );
+ // SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator();
+ // while ( tmpFaceIt->more() )
+ // aTmpFacesMesh.RemoveElement( tmpFaceIt->next() );
list<const SMDS_MeshElement* >::iterator tmpFaceIt = tempFaceList.begin();
for (; tmpFaceIt !=tempFaceList.end(); ++tmpFaceIt)
aMesh->RemoveElement(*tmpFaceIt);
if ( mesh->GetMeshInfo().NbElements( types[i] ))
{
type = types[i];
+ elemIt = mesh->elementsIterator( type );
break;
}
- elemIt = mesh->elementsIterator( type );
}
else
{
- type = (*theElements.begin())->GetType();
- elemIt = elemSetIterator( theElements );
+ //type = (*theElements.begin())->GetType();
+ elemIt = SMESHUtils::elemSetIterator( theElements );
}
// un-mark all elements to avoid duplicating just created elements
while ( elemIt->more() )
{
const SMDS_MeshElement* elem = elemIt->next();
- if ( elem->GetType() != type || elem->isMarked() )
+ if (( type != SMDSAbs_All && elem->GetType() != type ) ||
+ ( elem->isMarked() ))
continue;
elemType.Init( elem, /*basicOnly=*/false );
aNewNode = theMeshDS->AddNode( aCurrNode->X(), aCurrNode->Y(), aCurrNode->Z() );
copyPosition( aCurrNode, aNewNode );
theNodeNodeMap[ aCurrNode ] = aNewNode;
- myLastCreatedNodes.Append( aNewNode );
+ myLastCreatedNodes.push_back( aNewNode );
}
isDuplicate |= (aCurrNode != aNewNode);
newNodes[ ind++ ] = aNewNode;
{
copyPosition( aNode, aNewNode );
anOldNodeToNewNode[ aNode ] = aNewNode;
- myLastCreatedNodes.Append( aNewNode );
+ myLastCreatedNodes.push_back( aNewNode );
}
}
//================================================================================
/*!
- \brief Check if element located inside shape
- \return TRUE if IN or ON shape, FALSE otherwise
+ \brief Check if element located inside shape
+ \return TRUE if IN or ON shape, FALSE otherwise
*/
//================================================================================
const double theTol)
{
gp_XYZ centerXYZ (0, 0, 0);
- SMDS_ElemIteratorPtr aNodeItr = theElem->nodesIterator();
- while ( aNodeItr->more() )
+ for ( SMDS_ElemIteratorPtr aNodeItr = theElem->nodesIterator(); aNodeItr->more(); )
centerXYZ += SMESH_NodeXYZ( aNodeItr->next() );
gp_Pnt aPnt = centerXYZ / theElem->NbNodes();
else
{
const double aTol = Precision::Confusion();
- auto_ptr< BRepClass3d_SolidClassifier> bsc3d;
- auto_ptr<_FaceClassifier> aFaceClassifier;
+ std::unique_ptr< BRepClass3d_SolidClassifier> bsc3d;
+ std::unique_ptr<_FaceClassifier> aFaceClassifier;
if ( theShape.ShapeType() == TopAbs_SOLID )
{
bsc3d.reset( new BRepClass3d_SolidClassifier(theShape));;
SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS();
meshDS->BuildDownWardConnectivity(true);
CHRONO(50);
- SMDS_UnstructuredGrid *grid = meshDS->getGrid();
+ SMDS_UnstructuredGrid *grid = meshDS->GetGrid();
// --- build the list of faces shared by 2 domains (group of elements), with their domain and volume indexes
// build the list of cells with only a node or an edge on the border, with their domain and volume indexes
const SMDS_MeshElement* anElem = *elemItr;
if (!anElem)
continue;
- int vtkId = anElem->getVtkId();
+ int vtkId = anElem->GetVtkID();
//MESSAGE(" vtkId " << vtkId << " smdsId " << anElem->GetID());
int neighborsVtkIds[NBMAXNEIGHBORS];
int downIds[NBMAXNEIGHBORS];
int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId);
for (int n = 0; n < nbNeighbors; n++)
{
- int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]);
+ int smdsId = meshDS->FromVtkToSmds(neighborsVtkIds[n]);
const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
if (elem && ! domain.count(elem)) // neighbor is in another domain : face is shared
{
for (int i=0; i<l.ncells; i++)
{
int vtkId = l.cells[i];
- const SMDS_MeshElement* anElem = GetMeshDS()->FindElement(GetMeshDS()->fromVtkToSmds(vtkId));
+ const SMDS_MeshElement* anElem = GetMeshDS()->FindElement(GetMeshDS()->FromVtkToSmds(vtkId));
if (!domain.count(anElem))
continue;
int vtkType = grid->GetCellType(vtkId);
double *coords = grid->GetPoint(oldId);
SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]);
copyPosition( meshDS->FindNodeVtk( oldId ), newNode );
- int newId = newNode->getVtkId();
+ int newId = newNode->GetVtkID();
nodeDomains[oldId][idom] = newId; // cloned node for other domains
//MESSAGE("-+-+-c oldNode " << oldId << " domain " << idomain << " newNode " << newId << " domain " << idom << " size=" <<nodeDomains[oldId].size());
}
gp_Pnt p1(coords[0], coords[1], coords[2]);
gp_Pnt gref;
int vtkVolIds[1000]; // an edge can belong to a lot of volumes
- map<int, SMDS_VtkVolume*> domvol; // domain --> a volume with the edge
+ map<int, SMDS_MeshVolume*> domvol; // domain --> a volume with the edge
map<int, double> angleDom; // oriented angles between planes defined by edge and volume centers
int nbvol = grid->GetParentVolumes(vtkVolIds, downEdgeIds[ie], edgeType[ie]);
for ( size_t id = 0; id < doms.size(); id++ )
const TIDSortedElemSet& domain = (idom == iRestDom) ? theRestDomElems : theElems[idom];
for ( int ivol = 0; ivol < nbvol; ivol++ )
{
- int smdsId = meshDS->fromVtkToSmds(vtkVolIds[ivol]);
- SMDS_MeshElement* elem = (SMDS_MeshElement*)meshDS->FindElement(smdsId);
+ int smdsId = meshDS->FromVtkToSmds(vtkVolIds[ivol]);
+ const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
if (domain.count(elem))
{
- SMDS_VtkVolume* svol = dynamic_cast<SMDS_VtkVolume*>(elem);
- domvol[idom] = svol;
+ const SMDS_MeshVolume* svol = SMDS_Mesh::DownCast<SMDS_MeshVolume>(elem);
+ domvol[idom] = (SMDS_MeshVolume*) svol;
//MESSAGE(" domain " << idom << " volume " << elem->GetID());
- double values[3];
+ double values[3] = { 0,0,0 };
vtkIdType npts = 0;
vtkIdType* pts = 0;
grid->GetCellPoints(vtkVolIds[ivol], npts, pts);
- SMDS_VtkVolume::gravityCenter(grid, pts, npts, values);
- if (id ==0)
+ for ( vtkIdType i = 0; i < npts; ++i )
{
- gref.SetXYZ(gp_XYZ(values[0], values[1], values[2]));
+ double *coords = grid->GetPoint( pts[i] );
+ for ( int j = 0; j < 3; ++j )
+ values[j] += coords[j] / npts;
+ }
+ if ( id == 0 )
+ {
+ gref.SetCoord( values[0], values[1], values[2] );
angleDom[idom] = 0;
}
else
{
- gp_Pnt g(values[0], values[1], values[2]);
+ gp_Pnt g( values[0], values[1], values[2] );
angleDom[idom] = OrientedAngle(p0, p1, gref, g); // -pi<angle<+pi
//MESSAGE(" angle=" << angleDom[idom]);
}
//MESSAGE(".. Creation of elements: simple junction");
if (createJointElems)
{
- int idg;
string joints2DName = "joints2D";
- mapOfJunctionGroups[joints2DName] = this->myMesh->AddGroup(SMDSAbs_Face, joints2DName.c_str(), idg);
+ mapOfJunctionGroups[joints2DName] = this->myMesh->AddGroup(SMDSAbs_Face, joints2DName.c_str());
SMESHDS_Group *joints2DGrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[joints2DName]->GetGroupDS());
string joints3DName = "joints3D";
- mapOfJunctionGroups[joints3DName] = this->myMesh->AddGroup(SMDSAbs_Volume, joints3DName.c_str(), idg);
+ mapOfJunctionGroups[joints3DName] = this->myMesh->AddGroup(SMDSAbs_Volume, joints3DName.c_str());
SMESHDS_Group *joints3DGrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[joints3DName]->GetGroupDS());
itface = faceDomains.begin();
grpname << dom2 << "_" << dom1;
string namegrp = grpname.str();
if (!mapOfJunctionGroups.count(namegrp))
- mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(vol->GetType(), namegrp.c_str(), idg);
+ mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(vol->GetType(), namegrp.c_str());
SMESHDS_Group *sgrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[namegrp]->GetGroupDS());
if (sgrp)
sgrp->Add(vol->GetID());
stringstream grpname;
grpname << "m2j_";
grpname << 0 << "_" << 0;
- int idg;
string namegrp = grpname.str();
if (!mapOfJunctionGroups.count(namegrp))
- mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Face, namegrp.c_str(), idg);
+ mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Face, namegrp.c_str());
SMESHDS_Group *sgrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[namegrp]->GetGroupDS());
if (sgrp)
sgrp->Add(face->GetID());
orderedNodes.push_back( nodeDomains[ nodes[ ino ]][ orderDom[ idom ]]);
SMDS_MeshVolume* vol = this->GetMeshDS()->AddVolumeFromVtkIds(orderedNodes);
- int idg;
string namegrp = "jointsMultiples";
if (!mapOfJunctionGroups.count(namegrp))
- mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str(), idg);
+ mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str());
SMESHDS_Group *sgrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[namegrp]->GetGroupDS());
if (sgrp)
sgrp->Add(vol->GetID());
feDom[vtkId] = idomain;
faceOrEdgeDom[aCell] = emptyMap;
faceOrEdgeDom[aCell][idomain] = vtkId; // affect face or edge to the first domain only
- //MESSAGE("affect cell " << this->GetMeshDS()->fromVtkToSmds(vtkId) << " domain " << idomain
+ //MESSAGE("affect cell " << this->GetMeshDS()->FromVtkToSmds(vtkId) << " domain " << idomain
// << " type " << vtkType << " downId " << downId);
}
}
{
int idom = itdom->first;
int vtkVolId = itdom->second;
- //MESSAGE("modify nodes of cell " << this->GetMeshDS()->fromVtkToSmds(vtkVolId) << " domain " << idom);
+ //MESSAGE("modify nodes of cell " << this->GetMeshDS()->FromVtkToSmds(vtkVolId) << " domain " << idom);
localClonedNodeIds.clear();
for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn)
{
TIDSortedElemSet::const_iterator elemItr = domain.begin();
for ( ; elemItr != domain.end(); ++elemItr )
{
- SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr;
- SMDS_MeshFace* aFace = dynamic_cast<SMDS_MeshFace*> (anElem);
+ const SMDS_MeshFace* aFace = meshDS->DownCast<SMDS_MeshFace> ( *elemItr );
if (!aFace)
continue;
// MESSAGE("aFace=" << aFace->GetID());
// --- clone the nodes, create intermediate nodes for non medium nodes of a quad face
- SMDS_ElemIteratorPtr nodeIt = aFace->nodesIterator();
+ SMDS_NodeIteratorPtr nodeIt = aFace->nodeIterator();
while (nodeIt->more())
{
- const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*> (nodeIt->next());
- bool isMedium = isQuad && (aFace->IsMediumNode(node));
+ const SMDS_MeshNode* node = nodeIt->next();
+ bool isMedium = ( isQuad && aFace->IsMediumNode( node ));
if (isMedium)
ln2.push_back(node);
else
stringstream grpname;
grpname << "jf_";
grpname << idom;
- int idg;
string namegrp = grpname.str();
if (!mapOfJunctionGroups.count(namegrp))
- mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str(), idg);
+ mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str());
SMESHDS_Group *sgrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[namegrp]->GetGroupDS());
if (sgrp)
sgrp->Add(vol->GetID());
// --- modify the face
- aFace->ChangeNodes(&ln[0], ln.size());
+ const_cast<SMDS_MeshFace*>( aFace )->ChangeNodes( &ln[0], ln.size() );
}
}
return true;
// --- define groups to build
- int idg; // --- group of SMDS volumes
+ // --- group of SMDS volumes
string grpvName = groupName;
grpvName += "_vol";
- SMESH_Group *grp = this->myMesh->AddGroup(SMDSAbs_Volume, grpvName.c_str(), idg);
+ SMESH_Group *grp = this->myMesh->AddGroup(SMDSAbs_Volume, grpvName.c_str());
if (!grp)
{
MESSAGE("group not created " << grpvName);
}
SMESHDS_Group *sgrp = dynamic_cast<SMESHDS_Group*>(grp->GetGroupDS());
- int idgs; // --- group of SMDS faces on the skin
+ // --- group of SMDS faces on the skin
string grpsName = groupName;
grpsName += "_skin";
- SMESH_Group *grps = this->myMesh->AddGroup(SMDSAbs_Face, grpsName.c_str(), idgs);
+ SMESH_Group *grps = this->myMesh->AddGroup(SMDSAbs_Face, grpsName.c_str());
if (!grps)
{
MESSAGE("group not created " << grpsName);
}
SMESHDS_Group *sgrps = dynamic_cast<SMESHDS_Group*>(grps->GetGroupDS());
- int idgi; // --- group of SMDS faces internal (several shapes)
+ // --- group of SMDS faces internal (several shapes)
string grpiName = groupName;
grpiName += "_internalFaces";
- SMESH_Group *grpi = this->myMesh->AddGroup(SMDSAbs_Face, grpiName.c_str(), idgi);
+ SMESH_Group *grpi = this->myMesh->AddGroup(SMDSAbs_Face, grpiName.c_str());
if (!grpi)
{
MESSAGE("group not created " << grpiName);
}
SMESHDS_Group *sgrpi = dynamic_cast<SMESHDS_Group*>(grpi->GetGroupDS());
- int idgei; // --- group of SMDS faces internal (several shapes)
+ // --- group of SMDS faces internal (several shapes)
string grpeiName = groupName;
grpeiName += "_internalEdges";
- SMESH_Group *grpei = this->myMesh->AddGroup(SMDSAbs_Edge, grpeiName.c_str(), idgei);
+ SMESH_Group *grpei = this->myMesh->AddGroup(SMDSAbs_Edge, grpeiName.c_str());
if (!grpei)
{
MESSAGE("group not created " << grpeiName);
SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS();
meshDS->BuildDownWardConnectivity(true);
- SMDS_UnstructuredGrid* grid = meshDS->getGrid();
+ SMDS_UnstructuredGrid* grid = meshDS->GetGrid();
// --- set of volumes detected inside
while (volItr->more())
{
vol = (SMDS_MeshElement*)volItr->next();
- setOfInsideVol.insert(vol->getVtkId());
+ setOfInsideVol.insert(vol->GetVtkID());
sgrp->Add(vol->GetID());
}
}
while (volItr->more())
{
startVol = (SMDS_MeshElement*)volItr->next();
- setOfVolToCheck.insert(startVol->getVtkId());
+ setOfVolToCheck.insert(startVol->GetVtkID());
}
if (setOfVolToCheck.empty())
{
{
std::set<int>::iterator it = setOfVolToCheck.begin();
int vtkId = *it;
- //MESSAGE("volume to check, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
+ //MESSAGE("volume to check, vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId));
bool volInside = false;
vtkIdType npts = 0;
vtkIdType* pts = 0;
if (distance2 < radius2)
{
volInside = true; // one or more nodes inside the domain
- sgrp->Add(meshDS->fromVtkToSmds(vtkId));
+ sgrp->Add(meshDS->FromVtkToSmds(vtkId));
break;
}
}
if (volInside)
{
setOfInsideVol.insert(vtkId);
- //MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
+ //MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId));
int neighborsVtkIds[NBMAXNEIGHBORS];
int downIds[NBMAXNEIGHBORS];
unsigned char downTypes[NBMAXNEIGHBORS];
else
{
setOfOutsideVol.insert(vtkId);
- //MESSAGE(" volume outside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
+ //MESSAGE(" volume outside, vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId));
}
setOfVolToCheck.erase(vtkId);
}
int vtkId = *it;
if (grid->GetCellType(vtkId) == VTK_HEXAHEDRON)
{
- //MESSAGE("volume to recheck, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
+ //MESSAGE("volume to recheck, vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId));
int countInside = 0;
int neighborsVtkIds[NBMAXNEIGHBORS];
int downIds[NBMAXNEIGHBORS];
//MESSAGE("countInside " << countInside);
if (countInside > 1)
{
- //MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
+ //MESSAGE(" volume inside, vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId));
setOfInsideVol.insert(vtkId);
- sgrp->Add(meshDS->fromVtkToSmds(vtkId));
+ sgrp->Add(meshDS->FromVtkToSmds(vtkId));
addedInside = true;
}
else
for (; it != setOfInsideVol.end(); ++it)
{
int vtkId = *it;
- //MESSAGE(" vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
+ //MESSAGE(" vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId));
int neighborsVtkIds[NBMAXNEIGHBORS];
int downIds[NBMAXNEIGHBORS];
unsigned char downTypes[NBMAXNEIGHBORS];
int vtkFaceId = grid->getDownArray(downTypes[n])->getVtkCellId(downIds[n]);
if (vtkFaceId >= 0)
{
- sgrpi->Add(meshDS->fromVtkToSmds(vtkFaceId));
+ sgrpi->Add(meshDS->FromVtkToSmds(vtkFaceId));
// find also the smds edges on this face
int nbEdges = grid->getDownArray(downTypes[n])->getNumberOfDownCells(downIds[n]);
const int* dEdges = grid->getDownArray(downTypes[n])->getDownCells(downIds[n]);
{
int vtkEdgeId = grid->getDownArray(dTypes[i])->getVtkCellId(dEdges[i]);
if (vtkEdgeId >= 0)
- sgrpei->Add(meshDS->fromVtkToSmds(vtkEdgeId));
+ sgrpei->Add(meshDS->FromVtkToSmds(vtkEdgeId));
}
}
}
skinFaces[face] = vtkId;
int vtkFaceId = grid->getDownArray(downTypes[n])->getVtkCellId(downIds[n]);
if (vtkFaceId >= 0)
- sgrps->Add(meshDS->fromVtkToSmds(vtkFaceId));
+ sgrps->Add(meshDS->FromVtkToSmds(vtkFaceId));
}
}
}
{
const SMDS_MeshElement *elem = itelem->next();
int shapeId = elem->getshapeId();
- int vtkId = elem->getVtkId();
+ int vtkId = elem->GetVtkID();
if (!shapeIdToVtkIdSet.count(shapeId))
{
shapeIdToVtkIdSet[shapeId] = emptySet;
{
if (neighborsVtkIds[n]<0) // only smds faces are considered as neighbors here
continue;
- int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]);
+ int smdsId = meshDS->FromVtkToSmds(neighborsVtkIds[n]);
const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
if ( shapeIds.count(elem->getshapeId()) && !sgrps->Contains(elem)) // edge : neighbor in the set of shape, not in the group
{
// add new face based on volume nodes
if (aMesh->FindElement( nodes, SMDSAbs_Face, /*noMedium=*/false) )
{
- nbExisted++; // face already exsist
+ nbExisted++; // face already exists
}
else
{
SMDS_ElemIteratorPtr eIt;
if (elements.empty()) eIt = aMesh->elementsIterator(elemType);
- else eIt = elemSetIterator( elements );
+ else eIt = SMESHUtils::elemSetIterator( elements );
- while (eIt->more())
+ while ( eIt->more() )
{
const SMDS_MeshElement* elem = eIt->next();
const int iQuad = elem->IsQuadratic();
else if ( elem->GetType() == SMDSAbs_Face ) // elem is a face ------------------------
{
avoidSet.clear(), avoidSet.insert( elem );
- elemNodes.assign( SMDS_MeshElement::iterator( elem->interlacedNodesElemIterator() ),
+ elemNodes.assign( SMDS_MeshElement::iterator( elem->interlacedNodesIterator() ),
SMDS_MeshElement::iterator() );
elemNodes.push_back( elemNodes[0] );
nodes.resize( 2 + iQuad );
tgtNodes.resize( srcNodes.size() );
for ( inode = 0; inode < srcNodes.size(); ++inode )
tgtNodes[inode] = getNodeWithSameID( tgtMeshDS, srcNodes[inode] );
- if ( aroundElements && tgtEditor.GetMeshDS()->FindElement( tgtNodes,
+ if ( /*aroundElements && */tgtEditor.GetMeshDS()->FindElement( tgtNodes,
missType,
/*noMedium=*/false))
continue;
for ( size_t i = 0; i < missingBndElems.size(); ++i )
{
TConnectivity& nodes = missingBndElems[ i ];
- if ( aroundElements && tgtEditor.GetMeshDS()->FindElement( nodes,
+ if ( /*aroundElements && */tgtEditor.GetMeshDS()->FindElement( nodes,
missType,
/*noMedium=*/false))
continue;
else // store present elements to add them to a group
for ( size_t i = 0 ; i < presentBndElems.size(); ++i )
{
- presentEditor->myLastCreatedElems.Append( presentBndElems[ i ]);
+ presentEditor->myLastCreatedElems.push_back( presentBndElems[ i ]);
}
} // loop on given elements
if ( group )
{
if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>( group->GetGroupDS() ))
- for ( int i = 0; i < tgtEditor.myLastCreatedElems.Size(); ++i )
- g->SMDSGroup().Add( tgtEditor.myLastCreatedElems( i+1 ));
+ for ( size_t i = 0; i < tgtEditor.myLastCreatedElems.size(); ++i )
+ g->SMDSGroup().Add( tgtEditor.myLastCreatedElems[ i ]);
}
- tgtEditor.myLastCreatedElems.Clear();
- tgtEditor2.myLastCreatedElems.Clear();
+ tgtEditor.myLastCreatedElems.clear();
+ tgtEditor2.myLastCreatedElems.clear();
// -----------------------
// 5. Copy given elements
if ( toCopyElements && targetMesh != myMesh )
{
if (elements.empty()) eIt = aMesh->elementsIterator(elemType);
- else eIt = elemSetIterator( elements );
+ else eIt = SMESHUtils::elemSetIterator( elements );
while (eIt->more())
{
const SMDS_MeshElement* elem = eIt->next();
tgtNodes[inode] = getNodeWithSameID( tgtMeshDS, elem->GetNode(inode) );
tgtEditor.AddElement( tgtNodes, elemToCopy.Init( elem ));
- tgtEditor.myLastCreatedElems.Clear();
+ tgtEditor.myLastCreatedElems.clear();
}
}
return nbAddedBnd;
case SMDS_TOP_FACE:
{
- const SMDS_FacePosition* fPos = static_cast< const SMDS_FacePosition* >( pos );
+ SMDS_FacePositionPtr fPos = pos;
GetMeshDS()->SetNodeOnFace( to, from->getshapeId(),
fPos->GetUParameter(), fPos->GetVParameter() );
break;
case SMDS_TOP_EDGE:
{
// WARNING: it is dangerous to set equal nodes on one EDGE!!!!!!!!
- const SMDS_EdgePosition* ePos = static_cast< const SMDS_EdgePosition* >( pos );
+ SMDS_EdgePositionPtr ePos = pos;
GetMeshDS()->SetNodeOnEdge( to, from->getshapeId(), ePos->GetUParameter() );
break;
}
default:;
}
}
-
-namespace // utils for MakePolyLine
-{
- //================================================================================
- /*!
- * \brief Sequence of found points and a current point data
- */
- struct Path
- {
- std::vector< gp_XYZ > myPoints;
- double myLength;
-
- int mySrcPntInd; //!< start point index
- const SMDS_MeshElement* myFace;
- SMESH_NodeXYZ myNode1;
- SMESH_NodeXYZ myNode2;
- int myNodeInd1;
- int myNodeInd2;
- double myDot1;
- double myDot2;
- TIDSortedElemSet myElemSet, myAvoidSet;
-
- Path(): myLength(0.0), myFace(0) {}
-
- bool SetCutAtCorner( const SMESH_NodeXYZ& cornerNode,
- const SMDS_MeshElement* face,
- const gp_XYZ& plnNorm,
- const gp_XYZ& plnOrig );
-
- void AddPoint( const gp_XYZ& p );
-
- bool Extend( const gp_XYZ& plnNorm, const gp_XYZ& plnOrig );
-
- bool ReachSamePoint( const Path& other );
-
- static void Remove( std::vector< Path > & paths, size_t& i );
- };
-
- //================================================================================
- /*!
- * \brief Return true if this Path meats another
- */
- //================================================================================
-
- bool Path::ReachSamePoint( const Path& other )
- {
- return ( mySrcPntInd != other.mySrcPntInd &&
- myFace == other.myFace );
- }
-
- //================================================================================
- /*!
- * \brief Remove a path from a vector
- */
- //================================================================================
-
- void Path::Remove( std::vector< Path > & paths, size_t& i )
- {
- if ( paths.size() > 1 )
- {
- size_t j = paths.size() - 1; // last item to be removed
- if ( i < j )
- {
- paths[ i ].myPoints.swap( paths[ j ].myPoints );
- paths[ i ].myLength = paths[ j ].myLength;
- paths[ i ].mySrcPntInd = paths[ j ].mySrcPntInd;
- paths[ i ].myFace = paths[ j ].myFace;
- paths[ i ].myNode1 = paths[ j ].myNode1;
- paths[ i ].myNode2 = paths[ j ].myNode2;
- paths[ i ].myNodeInd1 = paths[ j ].myNodeInd1;
- paths[ i ].myNodeInd2 = paths[ j ].myNodeInd2;
- paths[ i ].myDot1 = paths[ j ].myDot1;
- paths[ i ].myDot2 = paths[ j ].myDot2;
- }
- }
- paths.pop_back();
- if ( i > 0 )
- --i;
- }
-
- //================================================================================
- /*!
- * \brief Store a point that is at a node of a face if the face is intersected by plane.
- * Return false if the node is a sole intersection point of the face and the plane
- */
- //================================================================================
-
- bool Path::SetCutAtCorner( const SMESH_NodeXYZ& cornerNode,
- const SMDS_MeshElement* face,
- const gp_XYZ& plnNorm,
- const gp_XYZ& plnOrig )
- {
- if ( face == myFace )
- return false;
- myNodeInd1 = face->GetNodeIndex( cornerNode._node );
- myNodeInd2 = ( myNodeInd1 + 1 ) % face->NbCornerNodes();
- int ind3 = ( myNodeInd1 + 2 ) % face->NbCornerNodes();
- myNode1.Set( face->GetNode( ind3 ));
- myNode2.Set( face->GetNode( myNodeInd2 ));
-
- myDot1 = plnNorm * ( myNode1 - plnOrig );
- myDot2 = plnNorm * ( myNode2 - plnOrig );
-
- bool ok = ( myDot1 * myDot2 < 0 );
- if ( !ok && myDot1 * myDot2 == 0 )
- {
- ok = ( myDot1 != myDot2 );
- if ( ok && myFace )
- ok = ( myFace->GetNodeIndex(( myDot1 == 0 ? myNode1 : myNode2 )._node ) < 0 );
- }
- if ( ok )
- {
- myFace = face;
- myDot1 = 0;
- AddPoint( cornerNode );
- }
- return ok;
- }
-
- //================================================================================
- /*!
- * \brief Store a point and update myLength
- */
- //================================================================================
-
- void Path::AddPoint( const gp_XYZ& p )
- {
- if ( !myPoints.empty() )
- myLength += ( p - myPoints.back() ).Modulus();
- else
- myLength = 0;
- myPoints.push_back( p );
- }
-
- //================================================================================
- /*!
- * \brief Try to find the next point
- * \param [in] plnNorm - cutting plane normal
- * \param [in] plnOrig - cutting plane origin
- */
- //================================================================================
-
- bool Path::Extend( const gp_XYZ& plnNorm, const gp_XYZ& plnOrig )
- {
- int nodeInd3 = ( myNodeInd1 + 1 ) % myFace->NbCornerNodes();
- if ( myNodeInd2 == nodeInd3 )
- nodeInd3 = ( myNodeInd1 + 2 ) % myFace->NbCornerNodes();
-
- SMESH_NodeXYZ node3 = myFace->GetNode( nodeInd3 );
- double dot3 = plnNorm * ( node3 - plnOrig );
-
- if ( dot3 * myDot1 < 0. )
- {
- myNode2 = node3;
- myNodeInd2 = nodeInd3;
- myDot2 = dot3;
- }
- else if ( dot3 * myDot2 < 0. )
- {
- myNode1 = node3;
- myNodeInd1 = nodeInd3;
- myDot1 = dot3;
- }
- else if ( dot3 == 0. )
- {
- SMDS_ElemIteratorPtr fIt = node3._node->GetInverseElementIterator(SMDSAbs_Face);
- while ( fIt->more() )
- if ( SetCutAtCorner( node3, fIt->next(), plnNorm, plnOrig ))
- return true;
- return false;
- }
- else if ( myDot2 == 0. )
- {
- SMESH_NodeXYZ node2 = myNode2; // copy as myNode2 changes in SetCutAtCorner()
- SMDS_ElemIteratorPtr fIt = node2._node->GetInverseElementIterator(SMDSAbs_Face);
- while ( fIt->more() )
- if ( SetCutAtCorner( node2, fIt->next(), plnNorm, plnOrig ))
- return true;
- return false;
- }
-
- double r = Abs( myDot1 / ( myDot2 - myDot1 ));
- AddPoint( myNode1 * ( 1 - r ) + myNode2 * r );
-
- myAvoidSet.clear();
- myAvoidSet.insert( myFace );
- myFace = SMESH_MeshAlgos::FindFaceInSet( myNode1._node, myNode2._node,
- myElemSet, myAvoidSet,
- &myNodeInd1, &myNodeInd2 );
- return myFace;
- }
-
- //================================================================================
- /*!
- * \brief Compute a path between two points of PolySegment
- */
- struct PolyPathCompute
- {
- SMESH_MeshEditor::TListOfPolySegments& mySegments; //!< inout PolySegment's
- std::vector< Path >& myPaths; //!< path of each of segments to compute
- SMESH_Mesh* myMesh;
- mutable std::vector< std::string > myErrors;
-
- PolyPathCompute( SMESH_MeshEditor::TListOfPolySegments& theSegments,
- std::vector< Path >& thePaths,
- SMESH_Mesh* theMesh):
- mySegments( theSegments ),
- myPaths( thePaths ),
- myMesh( theMesh ),
- myErrors( theSegments.size() )
- {
- }
-#undef SMESH_CAUGHT
-#define SMESH_CAUGHT myErrors[i] =
- void operator() ( const int i ) const
- {
- SMESH_TRY;
- const_cast< PolyPathCompute* >( this )->Compute( i );
- SMESH_CATCH( SMESH::returnError );
- }
-#undef SMESH_CAUGHT
- //================================================================================
- /*!
- * \brief Compute a path of a given segment
- */
- //================================================================================
-
- void Compute( const int iSeg )
- {
- SMESH_MeshEditor::PolySegment& polySeg = mySegments[ iSeg ];
-
- // get a cutting plane
-
- gp_XYZ p1 = SMESH_NodeXYZ( polySeg.myNode1[0] );
- gp_XYZ p2 = SMESH_NodeXYZ( polySeg.myNode1[1] );
- if ( polySeg.myNode2[0] ) p1 = 0.5 * ( p1 + SMESH_NodeXYZ( polySeg.myNode2[0] ));
- if ( polySeg.myNode2[1] ) p2 = 0.5 * ( p2 + SMESH_NodeXYZ( polySeg.myNode2[1] ));
-
- gp_XYZ plnNorm = ( p1 - p2 ) ^ polySeg.myVector.XYZ();
- gp_XYZ plnOrig = p2;
-
- // find paths connecting the 2 end points of polySeg
-
- std::vector< Path > paths; paths.reserve(10);
-
- // initialize paths
-
- for ( int iP = 0; iP < 2; ++iP ) // loop on the polySeg end points
- {
- Path path;
- path.mySrcPntInd = iP;
- size_t nbPaths = paths.size();
-
- if ( polySeg.myNode2[ iP ] && polySeg.myNode2[ iP ] != polySeg.myNode1[ iP ] )
- {
- while (( path.myFace = SMESH_MeshAlgos::FindFaceInSet( polySeg.myNode1[ iP ],
- polySeg.myNode2[ iP ],
- path.myElemSet,
- path.myAvoidSet,
- &path.myNodeInd1,
- &path.myNodeInd2 )))
- {
- path.myNode1.Set( polySeg.myNode1[ iP ]);
- path.myNode2.Set( polySeg.myNode2[ iP ]);
- path.myDot1 = plnNorm * ( path.myNode1 - plnOrig );
- path.myDot2 = plnNorm * ( path.myNode2 - plnOrig );
- path.myPoints.clear();
- path.AddPoint( 0.5 * ( path.myNode1 + path.myNode2 ));
- path.myAvoidSet.insert( path.myFace );
- paths.push_back( path );
- }
- if ( nbPaths == paths.size() )
- throw SALOME_Exception ( SMESH_Comment("No face edge found by point ") << iP+1
- << " in a PolySegment " << iSeg );
- }
- else // an end point is at node
- {
- std::set<const SMDS_MeshNode* > nodes;
- SMDS_ElemIteratorPtr fIt = polySeg.myNode1[ iP ]->GetInverseElementIterator(SMDSAbs_Face);
- while ( fIt->more() )
- {
- path.myPoints.clear();
- if ( path.SetCutAtCorner( polySeg.myNode1[ iP ], fIt->next(), plnNorm, plnOrig ))
- {
- if (( path.myDot1 * path.myDot2 != 0 ) ||
- ( nodes.insert( path.myDot1 == 0 ? path.myNode1._node : path.myNode2._node ).second ))
- paths.push_back( path );
- }
- }
- }
-
- // look for a one-segment path
- for ( size_t i = 0; i < nbPaths; ++i )
- for ( size_t j = nbPaths; j < paths.size(); ++j )
- if ( paths[i].myFace == paths[j].myFace )
- {
- myPaths[ iSeg ].myPoints.push_back( paths[i].myPoints[0] );
- myPaths[ iSeg ].myPoints.push_back( paths[j].myPoints[0] );
- paths.clear();
- }
- }
-
- // extend paths
-
- myPaths[ iSeg ].myLength = 1e100;
-
- while ( paths.size() >= 2 )
- {
- for ( size_t i = 0; i < paths.size(); ++i )
- {
- Path& path = paths[ i ];
- if ( !path.Extend( plnNorm, plnOrig ) || // path reached a mesh boundary
- path.myLength > myPaths[ iSeg ].myLength ) // path is longer than others
- {
- Path::Remove( paths, i );
- continue;
- }
-
- // join paths that reach same point
- for ( size_t j = 0; j < paths.size(); ++j )
- {
- if ( i != j && paths[i].ReachSamePoint( paths[j] ))
- {
- double distLast = ( paths[i].myPoints.back() - paths[j].myPoints.back() ).Modulus();
- double fullLength = ( paths[i].myLength + paths[j].myLength + distLast );
- if ( fullLength < myPaths[ iSeg ].myLength )
- {
- myPaths[ iSeg ].myLength = fullLength;
- std::vector< gp_XYZ > & allPoints = myPaths[ iSeg ].myPoints;
- allPoints.swap( paths[i].myPoints );
- allPoints.insert( allPoints.end(),
- paths[j].myPoints.rbegin(),
- paths[j].myPoints.rend() );
- }
- Path::Remove( paths, i );
- Path::Remove( paths, j );
- }
- }
- }
- if ( !paths.empty() && (int) paths[0].myPoints.size() > myMesh->NbFaces() )
- throw SALOME_Exception(LOCALIZED( "Infinite loop in MakePolyLine()"));
- }
-
- if ( myPaths[ iSeg ].myPoints.empty() )
- throw SALOME_Exception( SMESH_Comment("Can't find a full path for PolySegment #") << iSeg );
-
- } // PolyPathCompute::Compute()
-
- }; // struct PolyPathCompute
-
-} // namespace
-
-//=======================================================================
-//function : MakePolyLine
-//purpose : Create a polyline consisting of 1D mesh elements each lying on a 2D element of
-// the initial mesh
-//=======================================================================
-
-void SMESH_MeshEditor::MakePolyLine( TListOfPolySegments& theSegments,
- SMESHDS_Group* theGroup,
- SMESH_ElementSearcher* theSearcher)
-{
- std::vector< Path > segPaths( theSegments.size() ); // path of each of segments
-
- SMESH_ElementSearcher* searcher = theSearcher;
- SMESHUtils::Deleter<SMESH_ElementSearcher> delSearcher;
- if ( !searcher )
- {
- searcher = SMESH_MeshAlgos::GetElementSearcher( *GetMeshDS() );
- delSearcher._obj = searcher;
- }
-
- // get cutting planes
-
- std::vector< bool > isVectorOK( theSegments.size(), true );
- const double planarCoef = 0.333; // plane height in planar case
-
- for ( size_t iSeg = 0; iSeg < theSegments.size(); ++iSeg )
- {
- PolySegment& polySeg = theSegments[ iSeg ];
-
- gp_XYZ p1 = SMESH_NodeXYZ( polySeg.myNode1[0] );
- gp_XYZ p2 = SMESH_NodeXYZ( polySeg.myNode1[1] );
- if ( polySeg.myNode2[0] ) p1 = 0.5 * ( p1 + SMESH_NodeXYZ( polySeg.myNode2[0] ));
- if ( polySeg.myNode2[1] ) p2 = 0.5 * ( p2 + SMESH_NodeXYZ( polySeg.myNode2[1] ));
-
- gp_XYZ plnNorm = ( p1 - p2 ) ^ polySeg.myVector.XYZ();
-
- isVectorOK[ iSeg ] = ( plnNorm.Modulus() > std::numeric_limits<double>::min() );
- if ( !isVectorOK[ iSeg ])
- {
- gp_XYZ pMid = 0.5 * ( p1 + p2 );
- const SMDS_MeshElement* face;
- polySeg.myMidProjPoint = searcher->Project( pMid, SMDSAbs_Face, &face );
- polySeg.myVector = polySeg.myMidProjPoint.XYZ() - pMid;
-
- gp_XYZ faceNorm;
- SMESH_MeshAlgos::FaceNormal( face, faceNorm );
-
- if ( polySeg.myVector.Magnitude() < Precision::Confusion() ||
- polySeg.myVector * faceNorm < Precision::Confusion() )
- {
- polySeg.myVector = faceNorm;
- polySeg.myMidProjPoint = pMid + faceNorm * ( p1 - p2 ).Modulus() * planarCoef;
- }
- }
- else
- {
- polySeg.myVector = plnNorm ^ ( p1 - p2 );
- }
- }
-
- // assure that inverse elements are constructed, avoid their concurrent building in threads
- GetMeshDS()->nodesIterator()->next()->NbInverseElements();
-
- // find paths
-
- PolyPathCompute algo( theSegments, segPaths, myMesh );
- OSD_Parallel::For( 0, theSegments.size(), algo, theSegments.size() == 1 );
-
- for ( size_t iSeg = 0; iSeg < theSegments.size(); ++iSeg )
- if ( !algo.myErrors[ iSeg ].empty() )
- throw SALOME_Exception( algo.myErrors[ iSeg ].c_str() );
-
- // create an 1D mesh
-
- const SMDS_MeshNode *n, *nPrev = 0;
- SMESHDS_Mesh* mesh = GetMeshDS();
-
- for ( size_t iSeg = 0; iSeg < theSegments.size(); ++iSeg )
- {
- const Path& path = segPaths[iSeg];
- if ( path.myPoints.size() < 2 )
- continue;
-
- double tol = path.myLength / path.myPoints.size() / 1000.;
- if ( !nPrev || ( SMESH_NodeXYZ( nPrev ) - path.myPoints[0] ).SquareModulus() > tol*tol )
- {
- nPrev = mesh->AddNode( path.myPoints[0].X(), path.myPoints[0].Y(), path.myPoints[0].Z() );
- myLastCreatedNodes.Append( nPrev );
- }
- for ( size_t iP = 1; iP < path.myPoints.size(); ++iP )
- {
- n = mesh->AddNode( path.myPoints[iP].X(), path.myPoints[iP].Y(), path.myPoints[iP].Z() );
- myLastCreatedNodes.Append( n );
-
- const SMDS_MeshElement* elem = mesh->AddEdge( nPrev, n );
- myLastCreatedElems.Append( elem );
- if ( theGroup )
- theGroup->Add( elem );
-
- nPrev = n;
- }
-
- // return a vector
-
- gp_XYZ pMid = 0.5 * ( path.myPoints[0] + path.myPoints.back() );
- if ( isVectorOK[ iSeg ])
- {
- // find the most distance point of a path
- double maxDist = 0;
- for ( size_t iP = 1; iP < path.myPoints.size(); ++iP )
- {
- double dist = Abs( theSegments[iSeg].myVector * ( path.myPoints[iP] - path.myPoints[0] ));
- if ( dist > maxDist )
- {
- maxDist = dist;
- theSegments[iSeg].myMidProjPoint = path.myPoints[iP];
- }
- }
- if ( maxDist < Precision::Confusion() ) // planar case
- theSegments[iSeg].myMidProjPoint =
- pMid + theSegments[iSeg].myVector.XYZ().Normalized() * path.myLength * planarCoef;
- }
- theSegments[iSeg].myVector = gp_Vec( pMid, theSegments[iSeg].myMidProjPoint );
- }
-
- return;
-}