return false;
SMESHDS_SubMesh * eSubMesh = theMesh->MeshElements( theEdge );
- if ( !eSubMesh || ( eSubMesh->NbElements()==0 && eSubMesh->NbNodes() == 0))
+ if ( !eSubMesh || ( /*eSubMesh->NbElements()==0 && */ eSubMesh->NbNodes() == 0))
return false; // edge is not meshed
int nbNodes = 0;
#define smdsNode( elem ) static_cast<const SMDS_MeshNode*>( elem )
-//=======================================================================
-//function : SMESH_Pattern
-//purpose :
-//=======================================================================
-
-SMESH_Pattern::SMESH_Pattern ()
+namespace
{
-}
+
//=======================================================================
//function : getInt
//purpose :
//=======================================================================
-static inline int getInt( const char * theSring )
+inline int getInt( const char * theSring )
{
if ( *theSring < '0' || *theSring > '9' )
return -1;
//purpose :
//=======================================================================
-static inline double getDouble( const char * theSring )
+inline double getDouble( const char * theSring )
{
char *ptr;
return strtod( theSring, &ptr );
// Return the number of the found tokens
//=======================================================================
-static int readLine (list <const char*> & theFields,
- const char* & theLineBeg,
- const bool theClearFields )
+int readLine (list <const char*> & theFields,
+ const char* & theLineBeg,
+ const bool theClearFields )
{
if ( theClearFields )
theFields.clear();
return nbRead;
}
+//=======================================================================
+//function : isRealSeam
+//purpose : return true if an EDGE encounters twice in a FACE
+//=======================================================================
+
+// bool isRealSeam( const TopoDS_Edge& e, const TopoDS_Face& f )
+// {
+// if ( BRep_Tool::IsClosed( e, f ))
+// {
+// int nb = 0;
+// for (TopExp_Explorer exp( f, TopAbs_EDGE ); exp.More(); exp.Next())
+// if ( exp.Current().IsSame( e ))
+// if ( ++nb == 2 )
+// return true;
+// }
+// return false;
+// }
+
+//=======================================================================
+//function : loadVE
+//purpose : load VERTEXes and EDGEs in a map. Return nb loaded VERTEXes
+//=======================================================================
+
+int loadVE( const list< TopoDS_Edge > & eList,
+ TopTools_IndexedMapOfOrientedShape & map )
+{
+ list< TopoDS_Edge >::const_iterator eIt = eList.begin();
+ // vertices
+ int nbV;
+ for ( eIt = eList.begin(); eIt != eList.end(); eIt++ )
+ {
+ nbV = map.Extent();
+ map.Add( TopExp::FirstVertex( *eIt, true ));
+ bool added = ( nbV < map.Extent() );
+ if ( !added ) { // vertex encountered twice
+ // a seam vertex have two corresponding key points
+ map.Add( TopExp::FirstVertex( *eIt, true ).Reversed());
+ }
+ }
+ nbV = map.Extent();
+
+ // edges
+ for ( eIt = eList.begin(); eIt != eList.end(); eIt++ )
+ map.Add( *eIt );
+
+ return nbV;
+}
+
+} // namespace
+
+//=======================================================================
+//function : SMESH_Pattern
+//purpose :
+//=======================================================================
+
+SMESH_Pattern::SMESH_Pattern ()
+{
+}
+
//=======================================================================
//function : Load
//purpose : Load a pattern from <theFile>
// Load shapes in the consequent order and count nb of points
- // vertices
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ ) {
- int nbV = myShapeIDMap.Extent();
- myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ));
- bool added = ( nbV < myShapeIDMap.Extent() );
- if ( !added ) { // vertex encountered twice
- // a seam vertex have two corresponding key points
- myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ).Reversed());
- ++nbNodes;
- }
+ loadVE( eList, myShapeIDMap );
+ myShapeIDMap.Add( face );
+
+ nbNodes += myShapeIDMap.Extent() - 1;
+
+ for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
if ( SMESHDS_SubMesh * eSubMesh = aMeshDS->MeshElements( *elIt ))
nbNodes += eSubMesh->NbNodes() + 1;
- }
- // edges
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
- myShapeIDMap.Add( *elIt );
- // the face
- myShapeIDMap.Add( face );
myPoints.resize( nbNodes );
// Load U of points on edges
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
+ list<int>::iterator nbEinW = myNbKeyPntInBoundary.begin();
+ int iE = 0;
+ vector< TopoDS_Edge > eVec;
+ for ( elIt = eList.begin(); elIt != eList.end(); elIt++, iE++ )
{
+ if ( isClosed && ( iE == 0 || iE == *nbEinW ))
+ {
+ // new wire begins; put EDGEs in eVec
+ list<TopoDS_Edge>::iterator eEnd = elIt;
+ std::advance( eEnd, *nbEinW );
+ eVec.assign( elIt, eEnd );
+ if ( iE > 0 )
+ ++nbEinW;
+ iE = 0;
+ }
TopoDS_Edge & edge = *elIt;
list< TPoint* > & ePoints = getShapePoints( edge );
double f, l;
TopoDS_Shape & v = is2 ? v2 : v1;
if ( helper.IsRealSeam( v ) ) {
// reverse or not depending on orientation of adjacent seam
- TopoDS_Edge seam;
- list<TopoDS_Edge>::iterator eIt2 = elIt;
- if ( is2 )
- seam = ( ++eIt2 == eList.end() ? eList.front() : *eIt2 );
- else
- seam = ( eIt2 == eList.begin() ? eList.back() : *(--eIt2) );
- if ( seam.Orientation() == TopAbs_REVERSED )
+ int iSeam = helper.WrapIndex( iE + ( is2 ? +1 : -1 ), eVec.size() );
+ if ( eVec[ iSeam ].Orientation() == TopAbs_REVERSED )
v.Reverse();
}
}
BRep_Tool::CurveOnSurface( theEdge, TopoDS::Face( myShape ), f, l );
ePoints.back()->myInitU = 1.0;
+ //ePoints.front()->myInitU = 0.0; //myUV = C2d->Value( isForward ? f : l ).XY();
list< TPoint* >::const_iterator pIt = ePoints.begin();
for ( pIt++; pIt != ePoints.end(); pIt++ )
{
}
// here shapes get IDs, for the outer wire IDs are OK
- list<TopoDS_Edge>::iterator elIt = eList.begin();
- for ( ; elIt != eList.end(); elIt++ ) {
- myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ));
- bool isClosed1 = BRep_Tool::IsClosed( *elIt, theFace );
- // BEGIN: jfa for bug 0019943
- if (isClosed1) {
- isClosed1 = false;
- for (TopExp_Explorer expw (theFace, TopAbs_WIRE); expw.More() && !isClosed1; expw.Next()) {
- const TopoDS_Wire& wire = TopoDS::Wire(expw.Current());
- int nbe = 0;
- for (BRepTools_WireExplorer we (wire, theFace); we.More() && !isClosed1; we.Next()) {
- if (we.Current().IsSame(*elIt)) {
- nbe++;
- if (nbe == 2) isClosed1 = true;
- }
- }
- }
- }
- // END: jfa for bug 0019943
- if (isClosed1)
- myShapeIDMap.Add( TopExp::LastVertex( *elIt, true ));// vertex orienation is REVERSED
- }
- int nbVertices = myShapeIDMap.Extent();
-
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
- myShapeIDMap.Add( *elIt );
-
+ int nbVertices = loadVE( eList, myShapeIDMap );
myShapeIDMap.Add( face );
if ( myShapeIDToPointsMap.size() != myShapeIDMap.Extent() ) {
list< list< TPoint* > > edgesPointsList;
edgesPointsList.push_back( list< TPoint* >() );
list< TPoint* > * edgesPoints = & edgesPointsList.back();
- list< TPoint* >::iterator pIt;
+ list< TPoint* >::iterator pIt, pEnd;
// compute UV of points on the outer wire
int iE, nbEdgesInOuterWire = nbVertexInWires.front();
+ list< TopoDS_Edge >::iterator elIt;
for (iE = 0, elIt = eList.begin();
iE < nbEdgesInOuterWire && elIt != eList.end();
iE++, elIt++ )
// re-fill myShapeIDMap - all shapes get good IDs
myShapeIDMap.Clear();
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
- myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ));
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
- myShapeIDMap.Add( *elIt );
+ nbVertices = loadVE( eList, myShapeIDMap );
myShapeIDMap.Add( face );
} // there are inner wires
+ // Set XYZ of on-vertex points
+
+ // for ( int iV = 1; iV <= nbVertices; ++iV )
+ // {
+ // const TopoDS_Vertex& V = TopoDS::Vertex( myShapeIDMap( iV ));
+ // list< TPoint* > & vPoints = getShapePoints( iV );
+ // if ( !vPoints.empty() )
+ // {
+ // //vPoints.front()->myUV = BRep_Tool::Parameters( V, theFace ).XY();
+ // vPoints.front()->myXYZ = BRep_Tool::Pnt( V );
+ // }
+ // }
+
// Compute XYZ of on-edge points
TopLoc_Location loc;
{
BRepAdaptor_Curve C3d( *elIt );
list< TPoint* > & ePoints = getShapePoints( iE++ );
- pIt = ePoints.begin();
- for ( pIt++; pIt != ePoints.end(); pIt++ )
+ for ( pIt = ++ePoints.begin(), pEnd = ePoints.end(); pIt != pEnd; pIt++ )
{
TPoint* point = *pIt;
point->myXYZ = C3d.Value( point->myU );
}
}
+//=======================================================================
+//function : findExistingNodes
+//purpose : fills nodes vector with nodes existing on a given shape (IMP 22368)
+// Returns true if all nodes for all points on S are found
+//=======================================================================
+
+bool SMESH_Pattern::findExistingNodes( SMESH_Mesh* mesh,
+ const TopoDS_Shape& S,
+ const std::list< TPoint* > & points,
+ vector< const SMDS_MeshNode* > & nodesVector)
+{
+ if ( S.IsNull() || points.empty() )
+ return false;
+
+ SMESHDS_Mesh* aMeshDS = mesh->GetMeshDS();
+
+ switch ( S.ShapeType() )
+ {
+ case TopAbs_VERTEX:
+ {
+ int pIndex = points.back() - &myPoints[0];
+ if ( !nodesVector[ pIndex ] )
+ nodesVector[ pIndex ] = SMESH_Algo::VertexNode( TopoDS::Vertex( S ), aMeshDS );
+ return nodesVector[ pIndex ];
+ }
+ case TopAbs_EDGE:
+ {
+ const TopoDS_Edge& edge = TopoDS::Edge( S );
+ map< double, const SMDS_MeshNode* > paramsOfNodes;
+ if ( !SMESH_Algo::GetSortedNodesOnEdge( aMeshDS, edge,
+ /*ignoreMediumNodes=*/false,
+ paramsOfNodes )
+ || paramsOfNodes.size() < 3 )
+ break;
+ // points on VERTEXes are included with wrong myU
+ list< TPoint* >::const_reverse_iterator pItR = ++points.rbegin();
+ list< TPoint* >::const_iterator pItF = ++points.begin();
+ const bool isForward = ( (*pItF)->myU < (*pItR)->myU );
+ map< double, const SMDS_MeshNode* >::iterator u2n = ++paramsOfNodes.begin();
+ map< double, const SMDS_MeshNode* >::iterator u2nEnd = --paramsOfNodes.end();
+ TPoint* p;
+ if ( paramsOfNodes.size() == points.size() )
+ {
+ for ( ; u2n != u2nEnd; ++u2n )
+ {
+ p = ( isForward ? *pItF : *pItR );
+ int pIndex = p - &myPoints[0];
+ if ( !nodesVector [ pIndex ] )
+ nodesVector [ pIndex ] = u2n->second;
+ ++pItF;
+ ++pItR;
+ }
+ return true;
+ }
+ else
+ {
+ const double tolFact = 0.05;
+ while ( u2n != u2nEnd && pItF != points.end() )
+ {
+ const double u = u2n->first;
+ const SMDS_MeshNode* n = u2n->second;
+ const double tol = ( (++u2n)->first - u ) * tolFact;
+ do
+ {
+ p = ( isForward ? *pItF : *pItR );
+ if ( Abs( u - p->myU ) < tol )
+ {
+ int pIndex = p - &myPoints[0];
+ if ( !nodesVector [ pIndex ] )
+ nodesVector [ pIndex ] = n;
+ ++pItF;
+ ++pItR;
+ break;
+ }
+ }
+ while ( p->myU < u && ( ++pItF, ++pItR != points.rend() ));
+ }
+ }
+ break;
+ } // case TopAbs_EDGE:
+
+ default:;
+ } // switch ( S.ShapeType() )
+
+ return false;
+}
+
//=======================================================================
//function : MakeMesh
//purpose : Create nodes and elements in <theMesh> using nodes
// coordinates computed by either of Apply...() methods
-// WARNING : StdMeshers_Projection_... relies on MakeMesh() behavior: that
-// it does not care of nodes and elements already existing on
-// sub-shapes. DO NOT MERGE them or modify also StdMeshers_Projection_..
//=======================================================================
bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh,
{
nodesVector.resize( myPoints.size(), 0 );
- // find existing nodes on EDGEs and VERTEXes (IMP 22368)
- map< int, list< TPoint* > >::iterator idPointIt = myShapeIDToPointsMap.begin();
- if ( !myShapeIDMap.IsEmpty() && aMeshDS->NbNodes() > 0 )
-
- for ( ; idPointIt != myShapeIDToPointsMap.end(); idPointIt++ )
- {
- const TopoDS_Shape& S = myShapeIDMap( idPointIt->first );
- list< TPoint* > & points = idPointIt->second;
- if ( points.empty() )
- continue;
-
- switch ( S.ShapeType() )
- {
- case TopAbs_VERTEX:
- {
- int pIndex = points.back() - &myPoints[0];
- if ( !nodesVector[ pIndex ] )
- nodesVector[ pIndex ] = SMESH_Algo::VertexNode( TopoDS::Vertex( S ), aMeshDS );
- break;
- }
- case TopAbs_EDGE:
- {
- const TopoDS_Edge& edge = TopoDS::Edge( S );
- map< double, const SMDS_MeshNode* > paramsOfNodes;
- if ( !SMESH_Algo::GetSortedNodesOnEdge( aMeshDS, edge,
- /*ignoreMediumNodes=*/false,
- paramsOfNodes )
- || paramsOfNodes.size() < 3 )
- break;
- // points on VERTEXes are included with wrong myU
- list< TPoint* >::reverse_iterator pItR = ++points.rbegin();
- list< TPoint* >::iterator pItF = ++points.begin();
- const bool isForward = ( (*pItF)->myU < (*pItR)->myU );
- map< double, const SMDS_MeshNode* >::iterator u2n = ++paramsOfNodes.begin();
- map< double, const SMDS_MeshNode* >::iterator u2nEnd = --paramsOfNodes.end();
- TPoint* p;
- if ( paramsOfNodes.size() == points.size() )
- {
- for ( ; u2n != u2nEnd; ++u2n )
- {
- p = ( isForward ? *pItF : *pItR );
- int pIndex = p - &myPoints[0];
- if ( !nodesVector [ pIndex ] )
- nodesVector [ pIndex ] = u2n->second;
- ++pItF;
- ++pItR;
- }
- }
- else
- {
- const double tolFact = 0.05;
- while ( u2n != u2nEnd && pItF != points.end() )
- {
- const double u = u2n->first;
- const SMDS_MeshNode* n = u2n->second;
- const double tol = ( (++u2n)->first - u ) * tolFact;
- do
- {
- p = ( isForward ? *pItF : *pItR );
- if ( Abs( u - p->myU ) < tol )
- {
- int pIndex = p - &myPoints[0];
- if ( !nodesVector [ pIndex ] )
- nodesVector [ pIndex ] = n;
- ++pItF;
- ++pItR;
- break;
- }
- }
- while ( p->myU < u && ( ++pItF, ++pItR != points.rend() ));
- }
- }
- break;
- }
- default:;
- }
- } // end of "find existing nodes on EDGEs and VERTEXes"
-
// loop on sub-shapes of myShape: create nodes
- idPointIt = myShapeIDToPointsMap.begin();
+ map< int, list< TPoint* > >::iterator idPointIt = myShapeIDToPointsMap.begin();
for ( ; idPointIt != myShapeIDToPointsMap.end(); idPointIt++ )
{
+ list< TPoint* > & points = idPointIt->second;
TopoDS_Shape S;
- if ( !myShapeIDMap.IsEmpty() ) {
+ if ( !myShapeIDMap.IsEmpty() )
S = myShapeIDMap( idPointIt->first );
- }
- list< TPoint* > & points = idPointIt->second;
+
+ // find existing nodes on EDGEs and VERTEXes
+ if ( findExistingNodes( theMesh, S, points, nodesVector ))
+ continue;
+
list< TPoint* >::iterator pIt = points.begin();
for ( ; pIt != points.end(); pIt++ )
{
TPoint* point = *pIt;
- //int pIndex = pointIndex[ point ];
int pIndex = point - &myPoints[0];
if ( nodesVector [ pIndex ] )
continue;
point->myXYZ.Z());
nodesVector [ pIndex ] = node;
- if ( !S.IsNull() /*subMeshDS*/ ) {
- // !!!!! do not merge new nodes with ones existing on submeshes (see method comment)
+ if ( !S.IsNull() ) {
+
switch ( S.ShapeType() ) {
case TopAbs_VERTEX: {
aMeshDS->SetNodeOnVertex( node, TopoDS::Vertex( S )); break;
TopTools_MapOfShape seamVertices;
TopoDS_Face face = TopoDS::Face( theShape );
TopExp_Explorer eExp( theShape, TopAbs_EDGE );
- for ( ; eExp.More() && nbNodeOnSeamEdge == 0; eExp.Next() ) {
+ for ( ; eExp.More() /*&& nbNodeOnSeamEdge == 0*/; eExp.Next() ) {
const TopoDS_Edge& ee = TopoDS::Edge(eExp.Current());
if ( BRep_Tool::IsClosed(ee, face) ) {
// seam edge and vertices encounter twice in theFace
void clearMesh(SMESH_Mesh* theMesh) const;
// clear mesh elements existing on myShape in theMesh
+ bool findExistingNodes( SMESH_Mesh* mesh,
+ const TopoDS_Shape& S,
+ const std::list< TPoint* > & points,
+ std::vector< const SMDS_MeshNode* > & nodes);
+ // fills nodes vector with nodes existing on a given shape
+
static SMESHDS_SubMesh * getSubmeshWithElements(SMESH_Mesh* theMesh,
const TopoDS_Shape& theShape);
// return submesh containing elements bound to theShape in theMesh
long nbElements = 0;
if ( !memoryLack )
{
- // List of objects that will be updated automatically
+ // List of objects that will be updated automatically
QList< QPair< SMESH::SMESH_IDSource_var, _PTR(SObject) > > aListToUpdate;
SMESH::SMESH_IDSource_var aMeshObj = SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( aMeshSObj );
// put Mesh into list
// update mesh, sub-mesh and groups, if it's possible
QList< QPair< SMESH::SMESH_IDSource_var, _PTR(SObject) > >::iterator anIter;
for( anIter = aListToUpdate.begin(); anIter != aListToUpdate.end(); anIter++ ) {
- SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( (*anIter).second ));
- if ( getSMESHGUI()->automaticUpdate( (*anIter).first, &entities, &limitExceeded, &hidden, &nbElements ) )
- {
- try {
+ SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( (*anIter).second ));
+ if ( getSMESHGUI()->automaticUpdate( (*anIter).first, &entities, &limitExceeded, &hidden, &nbElements ) )
+ {
+ try {
#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
- OCC_CATCH_SIGNALS;
+ OCC_CATCH_SIGNALS;
#endif
- bool toDisplay = false;
-
- if ( !aMesh->_is_nil() ) { // display a mesh only
- toDisplay = true;
- SMESH_Actor *anActor = SMESH::FindActorByObject( aMesh );
- if ( !anActor ) anActor = SMESH::CreateActor( (*anIter).second->GetStudy(), (*anIter).second->GetID().c_str(), true );
- if ( anActor ) // actor is not created for an empty mesh
- {
- anActor->SetEntityMode( entities );
- SMESH::DisplayActor( SMESH::GetActiveWindow(), anActor );
- }
- }
- Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
- ( (*anIter).second->GetID().c_str(), "SMESH", (*anIter).second->GetName().c_str() );
- SMESH::Update(anIO, toDisplay);
-
- if ( limitExceeded && !aMesh->_is_nil() )
- {
- QStringList hiddenMsg;
- if ( hidden & SMESH_Actor::e0DElements ) hiddenMsg << tr( "SMESH_ELEMS0D" );
- if ( hidden & SMESH_Actor::eEdges ) hiddenMsg << tr( "SMESH_EDGES" );
- if ( hidden & SMESH_Actor::eFaces ) hiddenMsg << tr( "SMESH_FACES" );
- if ( hidden & SMESH_Actor::eVolumes ) hiddenMsg << tr( "SMESH_VOLUMES" );
- if ( hidden & SMESH_Actor::eBallElem ) hiddenMsg << tr( "SMESH_BALLS" );
- SUIT_MessageBox::warning( desktop(),
- tr( "SMESH_WRN_WARNING" ),
- tr( "SMESH_WRN_SIZE_INC_LIMIT_EXCEEDED" ).arg( nbElements ).arg( limitSize ).arg( hiddenMsg.join(", ") ) );
- }
- }
- catch (...) {
+ bool toDisplay = false;
+
+ if ( !aMesh->_is_nil() ) { // display a mesh only
+ toDisplay = true;
+ SMESH_Actor *anActor = SMESH::FindActorByObject( aMesh );
+ if ( !anActor ) anActor = SMESH::CreateActor( (*anIter).second->GetStudy(), (*anIter).second->GetID().c_str(), true );
+ if ( anActor ) // actor is not created for an empty mesh
+ {
+ anActor->SetEntityMode( entities );
+ SMESH::DisplayActor( SMESH::GetActiveWindow(), anActor );
+ }
+ }
+ Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
+ ( (*anIter).second->GetID().c_str(), "SMESH", (*anIter).second->GetName().c_str() );
+ SMESH::Update(anIO, toDisplay);
+
+ if ( limitExceeded && !aMesh->_is_nil() )
+ {
+ QStringList hiddenMsg;
+ if ( hidden & SMESH_Actor::e0DElements ) hiddenMsg << tr( "SMESH_ELEMS0D" );
+ if ( hidden & SMESH_Actor::eEdges ) hiddenMsg << tr( "SMESH_EDGES" );
+ if ( hidden & SMESH_Actor::eFaces ) hiddenMsg << tr( "SMESH_FACES" );
+ if ( hidden & SMESH_Actor::eVolumes ) hiddenMsg << tr( "SMESH_VOLUMES" );
+ if ( hidden & SMESH_Actor::eBallElem ) hiddenMsg << tr( "SMESH_BALLS" );
+ SUIT_MessageBox::warning( desktop(),
+ tr( "SMESH_WRN_WARNING" ),
+ tr( "SMESH_WRN_SIZE_INC_LIMIT_EXCEEDED" ).arg( nbElements ).arg( limitSize ).arg( hiddenMsg.join(", ") ) );
+ }
+ }
+ catch (...) {
#ifdef _DEBUG_
- MESSAGE ( "Exception thrown during mesh visualization" );
+ MESSAGE ( "Exception thrown during mesh visualization" );
#endif
- if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning?
- SMESH::OnVisuException();
- }
- else {
- memoryLack = true;
- }
- }
- }
- else if ( limitExceeded && !aMesh->_is_nil() )
- {
- SUIT_MessageBox::warning( desktop(),
- tr( "SMESH_WRN_WARNING" ),
- tr( "SMESH_WRN_SIZE_LIMIT_EXCEEDED" ).arg( nbElements ).arg( limitSize ) );
- }
+ if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning?
+ SMESH::OnVisuException();
+ }
+ else {
+ memoryLack = true;
+ }
+ }
+ }
+ else if ( limitExceeded && !aMesh->_is_nil() )
+ {
+ SUIT_MessageBox::warning( desktop(),
+ tr( "SMESH_WRN_WARNING" ),
+ tr( "SMESH_WRN_SIZE_LIMIT_EXCEEDED" ).arg( nbElements ).arg( limitSize ) );
+ }
}
}
LightApp_SelectionMgr *Sel = selectionMgr();
/*!
* \brief Return number of wires and a list of oredered edges.
* \param theFace - the face to process
- * \param theEdges - all ordered edges of theFace (outer edges goes first).
+ * \param theEdges - all ordered edges of theFace (outer edges go first).
* \param theNbEdgesInWires - nb of edges (== nb of vertices in closed wire) in each wire
* \param theFirstVertex - the vertex of the outer wire to set first in the returned
* list ( theFirstVertex may be NULL )
TShapePairsList::iterator s1_s2 = shapesQueue.begin();
for ( ; s1_s2 != shapesQueue.end(); ++s1_s2 )
{
+ if ( theMap.IsBound( s1_s2->first )) // avoid re-binding for a seam edge
+ continue; // to avoid this: Forward seam -> Reversed seam
InsertAssociation( s1_s2->first, s1_s2->second, theMap );
TopoDS_Iterator s1It( s1_s2->first), s2It( s1_s2->second );
for ( ; s1It.More(); s1It.Next(), s2It.Next() )
SMESH_Mesh * srcMesh,
const TAssocTool::TShapeShapeMap& shape2ShapeMap)
{
- MESSAGE("projectPartner");
- const double tol = 1.e-7*srcMesh->GetMeshDS()->getMaxDim();
+ SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
+ SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
+
+ const double tol = 1.e-7 * srcMeshDS->getMaxDim();
gp_Trsf trsf; // transformation to get location of target nodes from source ones
if ( tgtFace.IsPartner( srcFace ))
else
pOK = (( tgtP.Distance( tgtPP[0] ) > tol*tol ) &&
( tgtPP.size() == 1 || tgtP.Distance( tgtPP[1] ) > tol*tol ));
- //cout << "V - nS " << p._node->GetID() << " - nT " << SMESH_Algo::VertexNode(TopoDS::Vertex( tgtShape),tgtMesh->GetMeshDS())->GetID() << endl;
+ //cout << "V - nS " << p._node->GetID() << " - nT " << SMESH_Algo::VertexNode(TopoDS::Vertex( tgtShape),tgtMeshDS)->GetID() << endl;
}
else if ( tgtPP.size() > 0 )
{
- if ( SMESHDS_SubMesh* tgtSmds = tgtMesh->GetMeshDS()->MeshElements( tgtShape ))
+ if ( SMESHDS_SubMesh* tgtSmds = tgtMeshDS->MeshElements( tgtShape ))
{
double srcDist = srcPP[0].Distance( p );
double eTol = BRep_Tool::Tolerance( TopoDS::Edge( tgtShape ));
map<const SMDS_MeshNode* , const SMDS_MeshNode*> src2tgtNodes;
map<const SMDS_MeshNode* , const SMDS_MeshNode*>::iterator srcN_tgtN;
- for ( TopExp_Explorer srcEdge( srcFace, TopAbs_EDGE); srcEdge.More(); srcEdge.Next() )
+ for ( TopExp_Explorer srcExp( srcFace, TopAbs_EDGE); srcExp.More(); srcExp.Next() )
{
- const TopoDS_Shape& tgtEdge = shape2ShapeMap( srcEdge.Current(), /*isSrc=*/true );
+ const TopoDS_Shape& srcEdge = srcExp.Current();
+ const TopoDS_Shape& tgtEdge = shape2ShapeMap( srcEdge, /*isSrc=*/true );
+ if ( srcMesh->GetSubMesh( srcEdge )->IsEmpty() ||
+ tgtMesh->GetSubMesh( tgtEdge )->IsEmpty() )
+ continue;
map< double, const SMDS_MeshNode* > srcNodes, tgtNodes;
- if ( !SMESH_Algo::GetSortedNodesOnEdge( srcMesh->GetMeshDS(),
- TopoDS::Edge( srcEdge.Current() ),
- /*ignoreMediumNodes = */true,
- srcNodes )
+ if (( ! SMESH_Algo::GetSortedNodesOnEdge( srcMeshDS,
+ TopoDS::Edge( srcEdge ),
+ /*ignoreMediumNodes = */true,
+ srcNodes ))
||
- !SMESH_Algo::GetSortedNodesOnEdge( tgtMesh->GetMeshDS(),
- TopoDS::Edge( tgtEdge ),
- /*ignoreMediumNodes = */true,
- tgtNodes )
+ ( ! SMESH_Algo::GetSortedNodesOnEdge( tgtMeshDS,
+ TopoDS::Edge( tgtEdge ),
+ /*ignoreMediumNodes = */true,
+ tgtNodes ))
||
- srcNodes.size() != tgtNodes.size())
+ (( srcNodes.size() != tgtNodes.size() ) && tgtNodes.size() > 0 )
+ )
return false;
- if ( !tgtEdge.IsPartner( srcEdge.Current() ))
+ if ( !tgtEdge.IsPartner( srcEdge ))
{
+ if ( tgtNodes.empty() )
+ return false;
// check that transformation is OK by three nodes
gp_Pnt p0S = SMESH_TNodeXYZ( (srcNodes.begin()) ->second);
gp_Pnt p1S = SMESH_TNodeXYZ( (srcNodes.rbegin()) ->second);
return false;
}
}
-
- map< double, const SMDS_MeshNode* >::iterator u_tn = tgtNodes.begin();
- map< double, const SMDS_MeshNode* >::iterator u_sn = srcNodes.begin();
- for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn)
- src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second ));
+ if ( !tgtNodes.empty() )
+ {
+ map< double, const SMDS_MeshNode* >::iterator u_tn = tgtNodes.begin();
+ map< double, const SMDS_MeshNode* >::iterator u_sn = srcNodes.begin();
+ for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn)
+ src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second ));
+ }
}
// Make new faces
SMESH_MesherHelper helper( *tgtMesh );
helper.SetSubShape( tgtFace );
helper.IsQuadraticSubMesh( tgtFace );
- helper.SetElementsOnShape( true );
SMESH_MesherHelper srcHelper( *srcMesh );
srcHelper.SetSubShape( srcFace );
const SMDS_MeshNode* nullNode = 0;
// indices of nodes to create properly oriented faces
+ bool isReverse = ( trsf.Form() != gp_Identity );
int tri1 = 1, tri2 = 2, quad1 = 1, quad3 = 3;
- if ( trsf.Form() != gp_Identity )
+ if ( isReverse )
std::swap( tri1, tri2 ), std::swap( quad1, quad3 );
- SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace );
+ SMESHDS_SubMesh* srcSubDS = srcMeshDS->MeshElements( srcFace );
SMDS_ElemIteratorPtr elemIt = srcSubDS->GetElements();
vector< const SMDS_MeshNode* > tgtNodes;
while ( elemIt->more() ) // loop on all mesh faces on srcFace
const SMDS_MeshElement* elem = elemIt->next();
const int nbN = elem->NbCornerNodes();
tgtNodes.resize( nbN );
+ helper.SetElementsOnShape( false );
for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element
{
const SMDS_MeshNode* srcNode = elem->GetNode(i);
if ( srcN_tgtN->second == nullNode )
{
// create a new node
- gp_Pnt tgtP = gp_Pnt(srcNode->X(),srcNode->Y(),srcNode->Z()).Transformed( trsf );
+ gp_Pnt tgtP = gp_Pnt( SMESH_TNodeXYZ( srcNode )).Transformed( trsf );
SMDS_MeshNode* n = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
srcN_tgtN->second = n;
-
- gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode,
- elem->GetNode( helper.WrapIndex(i+1,nbN)));
- n->SetPosition( new SMDS_FacePosition( srcUV.X(), srcUV.Y() ));
+ switch ( srcNode->GetPosition()->GetTypeOfPosition() )
+ {
+ case SMDS_TOP_FACE:
+ {
+ gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode );
+ tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), srcUV.X(), srcUV.Y() );
+ break;
+ }
+ case SMDS_TOP_EDGE:
+ {
+ const TopoDS_Shape & srcE = srcMeshDS->IndexToShape( srcNode->getshapeId() );
+ const TopoDS_Shape & tgtE = shape2ShapeMap( srcE, /*isSrc=*/true );
+ double srcU = srcHelper.GetNodeU( TopoDS::Edge( srcE ), srcNode );
+ tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtE ), srcU );
+ break;
+ }
+ case SMDS_TOP_VERTEX:
+ {
+ const TopoDS_Shape & srcV = srcMeshDS->IndexToShape( srcNode->getshapeId() );
+ const TopoDS_Shape & tgtV = shape2ShapeMap( srcV, /*isSrc=*/true );
+ tgtMeshDS->SetNodeOnVertex( n, TopoDS::Vertex( tgtV ));
+ break;
+ }
+ default:;
+ }
}
tgtNodes[i] = srcN_tgtN->second;
}
// create a new face
+ helper.SetElementsOnShape( true );
switch ( nbN )
{
case 3: helper.AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break;
case 4: helper.AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break;
+ default:
+ if ( isReverse ) std::reverse( tgtNodes.begin(), tgtNodes.end() );
+ helper.AddPolygonalFace( tgtNodes );
+ }
+ }
+
+ // check node positions
+
+ if ( !tgtFace.IsPartner( srcFace ) )
+ {
+ int nbOkPos = 0;
+ const double tol2d = 1e-12;
+ srcN_tgtN = src2tgtNodes.begin();
+ for ( ; srcN_tgtN != src2tgtNodes.end(); ++srcN_tgtN )
+ {
+ const SMDS_MeshNode* n = srcN_tgtN->second;
+ switch ( n->GetPosition()->GetTypeOfPosition() )
+ {
+ case SMDS_TOP_FACE:
+ {
+ gp_XY uv = helper.GetNodeUV( tgtFace, n ), uvBis = uv;
+ if (( helper.CheckNodeUV( tgtFace, n, uv, tol )) &&
+ (( uv - uvBis ).SquareModulus() < tol2d ) &&
+ ( ++nbOkPos > 10 ))
+ return true;
+ else
+ nbOkPos = 0;
+ break;
+ }
+ case SMDS_TOP_EDGE:
+ {
+ const TopoDS_Edge & tgtE = TopoDS::Edge( tgtMeshDS->IndexToShape( n->getshapeId() ));
+ double u = helper.GetNodeU( tgtE, n ), uBis = u;
+ if (( !helper.CheckNodeU( tgtE, n, u, tol )) ||
+ (( u - uBis ) < tol2d ))
+ nbOkPos = 0;
+ break;
+ }
+ default:;
+ }
}
}
+
return true;
} // bool projectPartner()
+ //================================================================================
+ /*!
+ * \brief Check if two consecutive EDGEs are connected in 2D
+ * \param [in] E1 - a well oriented non-seam EDGE
+ * \param [in] E2 - a possibly well oriented seam EDGE
+ * \param [in] F - a FACE
+ * \return bool - result
+ */
+ //================================================================================
+
+ bool are2dConnected( const TopoDS_Edge & E1,
+ const TopoDS_Edge & E2,
+ const TopoDS_Face & F )
+ {
+ double f,l;
+ Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( E1, F, f, l );
+ gp_Pnt2d uvLast1 = c1->Value( E1.Orientation() == TopAbs_REVERSED ? f : l );
+
+ Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( E2, F, f, l );
+ gp_Pnt2d uvFirst2 = c2->Value( f );
+ gp_Pnt2d uvLast2 = c2->Value( l );
+ double tol2 = 1e-5 * uvLast2.SquareDistance( uvFirst2 );
+
+ return (( uvLast1.SquareDistance( uvFirst2 ) < tol2 ) ||
+ ( uvLast1.SquareDistance( uvLast2 ) < tol2 ));
+ }
+
//================================================================================
/*!
* \brief Preform projection in case if the faces are similar in 2D space
// make corresponding sequence of tgt EDGEs
TSideVector tgtWires( srcWires.size() );
- for ( unsigned iW = 0; iW < srcWires.size(); ++iW )
+ for ( size_t iW = 0; iW < srcWires.size(); ++iW )
{
list< TopoDS_Edge > tgtEdges;
StdMeshers_FaceSidePtr srcWire = srcWires[iW];
TopTools_IndexedMapOfShape edgeMap; // to detect seam edges
for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
{
- tgtEdges.push_back( TopoDS::Edge( shape2ShapeMap( srcWire->Edge( iE ), /*isSrc=*/true)));
+ TopoDS_Edge E = TopoDS::Edge( shape2ShapeMap( srcWire->Edge( iE ), /*isSrc=*/true));
// reverse a seam edge encountered for the second time
- const int oldExtent = edgeMap.Extent();
- edgeMap.Add( tgtEdges.back() );
- if ( oldExtent == edgeMap.Extent() )
- tgtEdges.back().Reverse();
+ const int index = edgeMap.Add( E );
+ if ( index < edgeMap.Extent() ) // E is a seam
+ {
+ // check which of edges to reverse, E or one already being in tgtEdges
+ if ( are2dConnected( tgtEdges.back(), E, tgtFace ))
+ {
+ list< TopoDS_Edge >::iterator eIt = tgtEdges.begin();
+ std::advance( eIt, index-1 );
+ eIt->Reverse();
+ }
+ else
+ {
+ E.Reverse();
+ }
+ }
+ tgtEdges.push_back( E );
}
tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh,
/*theIsForward = */ true,
if ( SMESH_Algo::isDegenerated( e )) continue;
TopExp::Vertices( e, VV[0], VV[1], /*CumOri=*/true );
if ( VV[1].IsSame( fromV )) {
+ nbEdges += edges[ 0 ].IsNull();
edges[ 0 ] = e;
- nbEdges++;
}
else if ( VV[0].IsSame( fromV )) {
+ nbEdges += edges[ 1 ].IsNull();
edges[ 1 ] = e;
- nbEdges++;
}
}
}
}
else if ( nbEdges == 1 )
{
- dir = getFaceDir( faceFrw, edges[0], node, helper, ok );
+ dir = getFaceDir( faceFrw, edges[ edges[0].IsNull() ], node, helper, ok );
if ( cosin ) *cosin = 1.;
}
else