23068: [CEA 1505] Be able to keep meshing in 2D after having merged the nodes in 1D

This commit is contained in:
eap 2015-07-07 17:33:01 +03:00
parent ff644361c8
commit 0e017d4c87
12 changed files with 596 additions and 282 deletions

View File

@ -432,16 +432,14 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theM
const SMDS_EdgePosition* epos =
static_cast<const SMDS_EdgePosition*>(node->GetPosition());
theNodes.insert( theNodes.end(), make_pair( epos->GetUParameter(), node ));
//MESSAGE("U " << epos->GetUParameter() << " ID " << node->GetID());
++nbNodes;
}
}
// add vertex nodes
TopoDS_Vertex v1, v2;
TopExp::Vertices(theEdge, v1, v2);
const SMDS_MeshNode* n1 = VertexNode( v1, (SMESHDS_Mesh*) theMesh );
const SMDS_MeshNode* n2 = VertexNode( v2, (SMESHDS_Mesh*) theMesh );
//MESSAGE("Vertices ID " << n1->GetID() << " " << n2->GetID());
const SMDS_MeshNode* n1 = VertexNode( v1, eSubMesh, 0 );
const SMDS_MeshNode* n2 = VertexNode( v2, eSubMesh, 0 );
Standard_Real f, l;
BRep_Tool::Range(theEdge, f, l);
if ( v1.Orientation() != TopAbs_FORWARD )
@ -614,6 +612,118 @@ const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V,
return 0;
}
//=======================================================================
/*!
* \brief Return the node built on a vertex.
* A node moved to other geometry by MergeNodes() is also returned.
* \param V - the vertex
* \param mesh - mesh
* \retval const SMDS_MeshNode* - found node or NULL
*/
//=======================================================================
const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V,
const SMESH_Mesh* mesh)
{
const SMDS_MeshNode* node = VertexNode( V, mesh->GetMeshDS() );
if ( !node && mesh->HasModificationsToDiscard() )
{
PShapeIteratorPtr edgeIt = SMESH_MesherHelper::GetAncestors( V, *mesh, TopAbs_EDGE );
while ( const TopoDS_Shape* edge = edgeIt->next() )
if ( SMESHDS_SubMesh* edgeSM = mesh->GetMeshDS()->MeshElements( *edge ))
if ( edgeSM->NbElements() > 0 )
return VertexNode( V, edgeSM, mesh, /*checkV=*/false );
}
return node;
}
//=======================================================================
/*!
* \brief Return the node built on a vertex.
* A node moved to other geometry by MergeNodes() is also returned.
* \param V - the vertex
* \param edgeSM - sub-mesh of a meshed EDGE sharing the vertex
* \param checkV - if \c true, presence of a node on the vertex is checked
* \retval const SMDS_MeshNode* - found node or NULL
*/
//=======================================================================
const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V,
const SMESHDS_SubMesh* edgeSM,
const SMESH_Mesh* mesh,
const bool checkV)
{
const SMDS_MeshNode* node = checkV ? VertexNode( V, edgeSM->GetParent() ) : 0;
if ( !node && edgeSM )
{
// find nodes not shared by mesh segments
typedef set< const SMDS_MeshNode* > TNodeSet;
typedef map< const SMDS_MeshNode*, const SMDS_MeshNode* > TNodeMap;
TNodeMap notSharedNodes;
TNodeSet otherShapeNodes;
vector< const SMDS_MeshNode* > segNodes(3);
SMDS_ElemIteratorPtr segIt = edgeSM->GetElements();
while ( segIt->more() )
{
const SMDS_MeshElement* seg = segIt->next();
if ( seg->GetType() != SMDSAbs_Edge )
return node;
segNodes.assign( seg->begin_nodes(), seg->end_nodes() );
for ( int i = 0; i < 2; ++i )
{
const SMDS_MeshNode* n1 = segNodes[i];
const SMDS_MeshNode* n2 = segNodes[1-i];
pair<TNodeMap::iterator, bool> it2new = notSharedNodes.insert( make_pair( n1, n2 ));
if ( !it2new.second ) // n encounters twice
notSharedNodes.erase( it2new.first );
if ( n1->getshapeId() != edgeSM->GetID() )
otherShapeNodes.insert( n1 );
}
}
if ( otherShapeNodes.size() == 1 && notSharedNodes.empty() ) // a closed EDGE
return *otherShapeNodes.begin();
if ( notSharedNodes.size() == 2 ) // two end nodes found
{
SMESHDS_Mesh* meshDS = edgeSM->GetParent();
const TopoDS_Shape& E = meshDS->IndexToShape( edgeSM->GetID() );
if ( E.IsNull() || E.ShapeType() != TopAbs_EDGE )
return node;
const SMDS_MeshNode* n1 = notSharedNodes.begin ()->first;
const SMDS_MeshNode* n2 = notSharedNodes.rbegin()->first;
TopoDS_Shape S1 = SMESH_MesherHelper::GetSubShapeByNode( n1, meshDS );
if ( S1.ShapeType() == TopAbs_VERTEX && SMESH_MesherHelper::IsSubShape( S1, E ))
return n2;
TopoDS_Shape S2 = SMESH_MesherHelper::GetSubShapeByNode( n2, meshDS );
if ( S2.ShapeType() == TopAbs_VERTEX && SMESH_MesherHelper::IsSubShape( S2, E ))
return n1;
if ( edgeSM->NbElements() <= 2 || !mesh ) // one-two segments
{
gp_Pnt pV = BRep_Tool::Pnt( V );
double dist1 = pV.SquareDistance( SMESH_TNodeXYZ( n1 ));
double dist2 = pV.SquareDistance( SMESH_TNodeXYZ( n2 ));
return dist1 < dist2 ? n1 : n2;
}
if ( mesh )
{
SMESH_MesherHelper helper( const_cast<SMESH_Mesh&>( *mesh ));
const SMDS_MeshNode* n1i = notSharedNodes.begin ()->second;
const SMDS_MeshNode* n2i = notSharedNodes.rbegin()->second;
const TopoDS_Edge& edge = TopoDS::Edge( E );
bool posOK = true;
double pos1 = helper.GetNodeU( edge, n1i, n2i, &posOK );
double pos2 = helper.GetNodeU( edge, n2i, n1i, &posOK );
double posV = BRep_Tool::Parameter( V, edge );
if ( Abs( pos1 - posV ) < Abs( pos2 - posV )) return n1;
else return n2;
}
}
}
return node;
}
//=======================================================================
//function : GetMeshError
//purpose : Finds topological errors of a sub-mesh

View File

@ -313,6 +313,7 @@ public:
* \param theEdge - The geometrical edge of interest
* \param theParams - The resulting vector of sorted node parameters
* \retval bool - false if not all parameters are OK
* \warning Nodes moved to other geometry by MergeNodes() are NOT returned.
*/
static bool GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh,
const TopoDS_Edge& theEdge,
@ -325,17 +326,14 @@ public:
* \param ignoreMediumNodes - to store medium nodes of quadratic elements or not
* \param typeToCheck - type of elements to check for medium nodes
* \retval bool - false if not all parameters are OK
* \warning Nodes moved to other geometry by MergeNodes() are NOT returned.
*/
static bool GetSortedNodesOnEdge(const SMESHDS_Mesh* theMesh,
const TopoDS_Edge& theEdge,
const bool ignoreMediumNodes,
std::map< double, const SMDS_MeshNode* > & theNodes,
const SMDSAbs_ElementType typeToCheck = SMDSAbs_All);
/*!
* Moved to SMESH_MesherHelper
*/
// static bool IsReversedSubMesh (const TopoDS_Face& theFace,
// SMESHDS_Mesh* theMeshDS);
/*!
* \brief Compute length of an edge
* \param E - the edge
@ -343,7 +341,6 @@ public:
*/
static double EdgeLength(const TopoDS_Edge & E);
//static int NumberOfWires(const TopoDS_Shape& S);
int NumberOfPoints(SMESH_Mesh& aMesh,const TopoDS_Wire& W);
/*!
@ -372,11 +369,34 @@ public:
/*!
* \brief Return the node built on a vertex
* \param V - the vertex
* \param meshDS - mesh
* \param meshDS - mesh data structure
* \retval const SMDS_MeshNode* - found node or NULL
*/
static const SMDS_MeshNode* VertexNode(const TopoDS_Vertex& V, const SMESHDS_Mesh* meshDS);
/*!
* \brief Return the node built on a vertex.
* A node moved to other geometry by MergeNodes() is also returned.
* \param V - the vertex
* \param mesh - mesh
* \retval const SMDS_MeshNode* - found node or NULL
*/
static const SMDS_MeshNode* VertexNode(const TopoDS_Vertex& V, const SMESH_Mesh* mesh);
/*!
* \brief Return the node built on a vertex.
* A node moved to other geometry by MergeNodes() is also returned.
* \param V - the vertex
* \param edgeSM - sub-mesh of a meshed EDGE sharing the vertex
* \param mesh - the mesh
* \param checkV - if \c true, presence of a node on the vertex is checked
* \retval const SMDS_MeshNode* - found node or NULL
*/
static const SMDS_MeshNode* VertexNode(const TopoDS_Vertex& V,
const SMESHDS_SubMesh* edgeSM,
const SMESH_Mesh* mesh,
const bool checkV=true);
enum EMeshError { MEr_OK = 0, MEr_HOLES, MEr_BAD_ORI, MEr_EMPTY };
/*!

View File

@ -1117,7 +1117,7 @@ throw(SALOME_Exception)
//================================================================================
/*!
* \brief Return submeshes of groups containing the given sub-shape
* \brief Return sub-meshes of groups containing the given sub-shape
*/
//================================================================================
@ -1131,8 +1131,8 @@ SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const
if ( !subMesh )
return found;
// submeshes of groups have max IDs, so search from the map end
SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) );
// sub-meshes of groups have max IDs, so search from the map end
SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) );
while ( smIt->more() ) {
SMESH_subMesh* sm = smIt->next();
SMESHDS_SubMesh * ds = sm->GetSubMeshDS();
@ -1158,6 +1158,12 @@ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) )
found.push_back( mainSM );
}
}
else // issue 0023068
{
if ( SMESH_subMesh * mainSM = GetSubMeshContaining(1) )
if ( mainSM->GetSubShape().ShapeType() == TopAbs_COMPOUND )
found.push_back( mainSM );
}
return found;
}
//=======================================================================

View File

@ -191,8 +191,8 @@ bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh)
}
}
if ( nbOldLinks == myTLinkNodeMap.size() )
myCreateQuadratic = false;
// if ( nbOldLinks == myTLinkNodeMap.size() ) -- 0023068
// myCreateQuadratic = false;
if(!myCreateQuadratic) {
myTLinkNodeMap.clear();

View File

@ -455,7 +455,8 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
*/
//================================================================================
namespace {
namespace
{
int dependsOnMapKey( const SMESH_subMesh* sm )
{
int type = sm->GetSubShape().ShapeType();
@ -479,6 +480,8 @@ void SMESH_subMesh::insertDependence(const TopoDS_Shape aShape,
for ( ; sub.More(); sub.Next() )
{
SMESH_subMesh *aSubMesh = _father->GetSubMesh( sub.Current() );
if ( aSubMesh->GetId() == 0 )
continue; // not a sub-shape of the shape to mesh
int cle = dependsOnMapKey( aSubMesh );
if ( _mapDepend.find( cle ) == _mapDepend.end())
{
@ -597,6 +600,7 @@ SMESH_Hypothesis::Hypothesis_Status
// le retour des evenement father n'indiquent pas que add ou remove fait
SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK;
if ( _Id == 0 ) return ret; // not a sub-shape of the shape to mesh
SMESHDS_Mesh* meshDS =_father->GetMeshDS();
SMESH_Algo* algo = 0;
@ -1003,8 +1007,8 @@ SMESH_Hypothesis::Hypothesis_Status
// detect algorithm hiding
//
if ( ret == SMESH_Hypothesis::HYP_OK &&
( event == ADD_ALGO || event == ADD_FATHER_ALGO ) &&
if ( ret == SMESH_Hypothesis::HYP_OK &&
( event == ADD_ALGO || event == ADD_FATHER_ALGO ) && algo &&
algo->GetName() == anHyp->GetName() )
{
// is algo hidden?

View File

@ -68,22 +68,22 @@ SMESHDS_Mesh * SMESHDS_Document::NewMesh(bool theIsEmbeddedMode, int MeshID)
//=======================================================================
//function : GetMesh
//purpose :
//purpose :
//=======================================================================
SMESHDS_Mesh *SMESHDS_Document::GetMesh(int MeshID)
{
map<int,SMESHDS_Mesh*>::iterator it=myMeshes.find(MeshID);
if (it==myMeshes.end())
{
MESSAGE("SMESHDS_Document::GetMesh : ID not found");
return NULL;
}
else return (*it).second;
map<int,SMESHDS_Mesh*>::iterator it=myMeshes.find(MeshID);
if (it==myMeshes.end())
{
MESSAGE("SMESHDS_Document::GetMesh : ID not found");
return NULL;
}
else return (*it).second;
}
//=======================================================================
//function : RemoveMesh
//purpose :
//purpose :
//=======================================================================
void SMESHDS_Document::RemoveMesh(int MeshID)
{
@ -107,99 +107,99 @@ void SMESHDS_Document::AddHypothesis(SMESHDS_Hypothesis * H)
//=======================================================================
SMESHDS_Hypothesis * SMESHDS_Document::GetHypothesis(int HypID)
{
map<int,SMESHDS_Hypothesis*>::iterator it=myHypothesis.find(HypID);
if (it==myHypothesis.end())
{
MESSAGE("SMESHDS_Document::GetHypothesis : ID not found");
return NULL;
}
else return (*it).second;
map<int,SMESHDS_Hypothesis*>::iterator it=myHypothesis.find(HypID);
if (it==myHypothesis.end())
{
MESSAGE("SMESHDS_Document::GetHypothesis : ID not found");
return NULL;
}
else return (*it).second;
}
//=======================================================================
//function : RemoveHypothesis
//purpose :
//purpose :
//=======================================================================
void SMESHDS_Document::RemoveHypothesis(int HypID)
{
map<int,SMESHDS_Hypothesis*>::iterator it=myHypothesis.find(HypID);
if (it==myHypothesis.end())
MESSAGE("SMESHDS_Document::RemoveHypothesis : ID not found");
myHypothesis.erase(it);
map<int,SMESHDS_Hypothesis*>::iterator it=myHypothesis.find(HypID);
if (it==myHypothesis.end())
MESSAGE("SMESHDS_Document::RemoveHypothesis : ID not found");
myHypothesis.erase(it);
}
//=======================================================================
//function : NbMeshes
//purpose :
//purpose :
//=======================================================================
int SMESHDS_Document::NbMeshes()
{
return myMeshes.size();
return myMeshes.size();
}
//=======================================================================
//function : NbHypothesis
//purpose :
//purpose :
//=======================================================================
int SMESHDS_Document::NbHypothesis()
{
return myHypothesis.size();
return myHypothesis.size();
}
//=======================================================================
//function : InitMeshesIterator
//purpose :
//purpose :
//=======================================================================
void SMESHDS_Document::InitMeshesIterator()
{
myMeshesIt=myMeshes.begin();
myMeshesIt=myMeshes.begin();
}
//=======================================================================
//function : NextMesh
//purpose :
//purpose :
//=======================================================================
SMESHDS_Mesh * SMESHDS_Document::NextMesh()
{
SMESHDS_Mesh * toReturn=(*myMeshesIt).second;
myMeshesIt++;
return toReturn;
SMESHDS_Mesh * toReturn=(*myMeshesIt).second;
myMeshesIt++;
return toReturn;
}
//=======================================================================
//function : MoreMesh
//purpose :
//purpose :
//=======================================================================
bool SMESHDS_Document::MoreMesh()
{
return myMeshesIt!=myMeshes.end();
return myMeshesIt!=myMeshes.end();
}
//=======================================================================
//function : InitHypothesisIterator
//purpose :
//purpose :
//=======================================================================
void SMESHDS_Document::InitHypothesisIterator()
{
myHypothesisIt=myHypothesis.begin();
myHypothesisIt=myHypothesis.begin();
}
//=======================================================================
//function : NextMesh
//purpose :
//purpose :
//=======================================================================
SMESHDS_Hypothesis * SMESHDS_Document::NextHypothesis()
{
SMESHDS_Hypothesis * toReturn=(*myHypothesisIt).second;
myHypothesisIt++;
return toReturn;
SMESHDS_Hypothesis * toReturn=(*myHypothesisIt).second;
myHypothesisIt++;
return toReturn;
}
//=======================================================================
//function : MoreMesh
//purpose :
//purpose :
//=======================================================================
bool SMESHDS_Document::MoreHypothesis()
{
return myHypothesisIt!=myHypothesis.end();
return myHypothesisIt!=myHypothesis.end();
}

View File

@ -73,8 +73,8 @@ class SMESHDS_EXPORT SMESHDS_SubMesh
int getSize();
void compactList();
SMESHDS_Mesh *GetParent() { return myParent; }
int GetID() const { return myIndex; }
SMESHDS_Mesh* GetParent() const { return const_cast< SMESHDS_Mesh*>( myParent ); }
int GetID() const { return myIndex; }
private:
SMESHDS_Mesh * myParent;

View File

@ -79,8 +79,6 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
//================================================================================
/*!
* \brief Constructor of a side of several edges
* \param theFace - the face
* \param theEdge - the edge
*/
//================================================================================
@ -101,6 +99,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
myNormPar.resize ( nbEdges );
myEdgeLength.resize( nbEdges );
myIsUniform.resize ( nbEdges, true );
myFace = theFace;
myLength = 0;
myNbPonits = myNbSegments = 0;
myProxyMesh = theProxyMesh;
@ -121,7 +120,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
myEdgeLength[i] = SMESH_Algo::EdgeLength( *edge );
if ( myEdgeLength[i] < DBL_MIN ) nbDegen++;
myLength += myEdgeLength[i];
myEdge[i] = *edge;
myEdge [i] = *edge;
myEdgeID[i] = meshDS->ShapeToIndex( *edge );
if ( !theIsForward ) myEdge[i].Reverse();
@ -132,34 +131,16 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
if ( myEdge[i].Orientation() == TopAbs_REVERSED )
std::swap( myFirst[i], myLast[i] );
if ( const SMESHDS_SubMesh* sm = myProxyMesh->GetSubMesh( *edge )) {
int nbN = sm->NbNodes();
if ( theIgnoreMediumNodes ) {
SMDS_ElemIteratorPtr elemIt = sm->GetElements();
if ( elemIt->more() && elemIt->next()->IsQuadratic() )
nbN -= sm->NbElements();
}
myNbPonits += nbN;
myNbSegments += sm->NbElements();
}
// TopExp::FirstVertex() and TopExp::LastVertex() return NULL from INTERNAL edge
vExp.Initialize( *edge );
if ( vExp.Value().Orientation() == TopAbs_REVERSED ) vExp.Next();
if ( SMESH_Algo::VertexNode( TopoDS::Vertex( vExp.Value()), meshDS ))
myNbPonits += 1; // for the first end
else
myMissingVertexNodes = true;
// check if the edge has a non-uniform parametrization (issue 0020705)
if ( !myC2d[i].IsNull() )
{
if ( myEdgeLength[i] > DBL_MIN)
if ( myEdgeLength[i] > DBL_MIN )
{
Geom2dAdaptor_Curve A2dC( myC2d[i],
std::min( myFirst[i], myLast[i] ),
std::max( myFirst[i], myLast[i] ));
double p2 = myFirst[i]+(myLast[i]-myFirst[i])/2., p4 = myFirst[i]+(myLast[i]-myFirst[i])/4.;
double p2 = myFirst[i]+(myLast[i]-myFirst[i])/2.;
double p4 = myFirst[i]+(myLast[i]-myFirst[i])/4.;
double d2 = GCPnts_AbscissaPoint::Length( A2dC, myFirst[i], p2 );
double d4 = GCPnts_AbscissaPoint::Length( A2dC, myFirst[i], p4 );
//cout<<"len = "<<len<<" d2 = "<<d2<<" fabs(2*d2/len-1.0) = "<<fabs(2*d2/len-1.0)<<endl;
@ -174,21 +155,15 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
myC3dAdaptor[i].Load( C3d, 0, 0.5 * BRep_Tool::Tolerance( V ));
}
}
// reverse a proxy submesh
// reverse a proxy sub-mesh
if ( !theIsForward )
reverseProxySubmesh( myEdge[i] );
} // loop on edges
vExp.Initialize( theEdges.back() );
if ( vExp.Value().Orientation() != TopAbs_REVERSED ) vExp.Next();
if ( vExp.More() )
{
if ( SMESH_Algo::VertexNode( TopoDS::Vertex( vExp.Value()), meshDS ))
myNbPonits++; // for the last end
else
myMissingVertexNodes = true;
}
// count nodes and segments
NbPoints( /*update=*/true );
if ( nbEdges > 1 && myLength > DBL_MIN ) {
const double degenNormLen = 1.e-5;
double totLength = myLength;
@ -209,8 +184,6 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
//================================================================================
/*!
* \brief Constructor of a side for vertex using data from other FaceSide
* \param theVertex - the vertex
* \param theSide - the side
*/
//================================================================================
@ -271,6 +244,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(UVPtStructVec& theSideNodes,
myMissingVertexNodes = myIgnoreMediumNodes = false;
myDefaultPnt2d.SetCoord( 1e100, 1e100 );
myFace = theFace;
myPoints = theSideNodes;
myNbPonits = myPoints.size();
myNbSegments = myNbPonits + 1;
@ -332,21 +306,27 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(UVPtStructVec& theSideNodes,
const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
double constValue) const
{
if ( myPoints.empty() ) {
if ( myPoints.empty() )
{
if ( NbEdges() == 0 ) return myPoints;
SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
SMESH_MesherHelper helper(*myProxyMesh->GetMesh());
StdMeshers_FaceSide* me = const_cast< StdMeshers_FaceSide* >( this );
SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
SMESH_MesherHelper helper( *myProxyMesh->GetMesh() );
bool paramOK;
double eps = 1e-100;
// sort nodes of all edges putting them into a map
map< double, const SMDS_MeshNode*> u2node;
vector< const SMESH_ProxyMesh::SubMesh* > proxySubMesh( myEdge.size());
map< double, const SMDS_MeshNode*> u2node;
vector< pair< double, const SMDS_MeshNode*> > u2nodeVec;
vector<const SMDS_MeshNode*> nodes;
set<const SMDS_MeshNode*> vertexNodes;
vector< const SMESH_ProxyMesh::SubMesh* > proxySubMesh( myEdge.size() );
int nbProxyNodes = 0;
for ( size_t iE = 0; iE < myEdge.size(); ++iE )
size_t iE;
for ( iE = 0; iE < myEdge.size(); ++iE )
{
proxySubMesh[iE] = myProxyMesh->GetProxySubMesh( myEdge[iE] );
if ( proxySubMesh[iE] )
@ -361,75 +341,87 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
continue;
}
}
// Put 1st vertex node of a current edge
TopoDS_Vertex VV[2]; // TopExp::FirstVertex() returns NULL for INTERNAL edge
VV[0] = SMESH_MesherHelper::IthVertex( 0, myEdge[iE]);
VV[1] = SMESH_MesherHelper::IthVertex( 1, myEdge[iE]);
const SMDS_MeshNode* node = SMESH_Algo::VertexNode( VV[0], meshDS );
double prevNormPar = ( iE == 0 ? 0 : myNormPar[ iE-1 ]); // normalized param
if ( node ) { // nodes on internal vertices may be missing
u2node.insert( u2node.end(), make_pair( prevNormPar, node ));
// Add 1st vertex node of a current edge
const SMDS_MeshNode* node = VertexNode( iE );
const double prevNormPar = ( iE == 0 ? 0 : myNormPar[ iE-1 ]); // normalized param
if ( node ) // nodes on internal vertices may be missing
{
if ( vertexNodes.insert( node ).second )
u2node.insert( u2node.end(), make_pair( prevNormPar, node ));
}
else if ( iE == 0 ) {
MESSAGE(" NO NODE on VERTEX" );
return myPoints;
else if ( iE == 0 )
{
if ( nodes.empty() ) {
for ( ++iE; iE < myEdge.size(); ++iE )
if (( node = VertexNode( iE ))) {
u2node.insert( make_pair( prevNormPar, node ));
break;
}
--iE;
}
if ( !node )
return myPoints;
vertexNodes.insert( node );
}
// Put internal nodes
if ( const SMESHDS_SubMesh* sm = myProxyMesh->GetSubMesh( myEdge[iE] ))
// Add internal nodes
nodes.clear();
if ( !GetEdgeNodes( iE, nodes, /*v0=*/false, /*v1=*/false ))
return myPoints;
if ( !nodes.empty() )
{
vector< pair< double, const SMDS_MeshNode*> > u2nodeVec;
u2nodeVec.reserve( sm->NbNodes() );
SMDS_NodeIteratorPtr nItr = sm->GetNodes();
u2nodeVec.clear();
double paramSize = myLast[iE] - myFirst[iE];
double r = myNormPar[iE] - prevNormPar;
helper.SetSubShape( myEdge[iE] );
helper.ToFixNodeParameters( true );
if ( !myIsUniform[iE] )
while ( nItr->more() )
for ( size_t i = 0; i < nodes.size(); ++i )
{
const SMDS_MeshNode* node = nItr->next();
if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
continue;
double u = helper.GetNodeU( myEdge[iE], node, 0, &paramOK );
double aLenU = GCPnts_AbscissaPoint::Length
( const_cast<GeomAdaptor_Curve&>( myC3dAdaptor[iE]), myFirst[iE], u );
double u = helper.GetNodeU( myEdge[iE], nodes[i], 0, &paramOK );
double aLenU = GCPnts_AbscissaPoint::Length( me->myC3dAdaptor[iE], myFirst[iE], u );
if ( myEdgeLength[iE] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6"
{
u2nodeVec.clear();
break;
}
double normPar = prevNormPar + r*aLenU/myEdgeLength[iE];
u2nodeVec.push_back( make_pair( normPar, node ));
double normPar = prevNormPar + r * aLenU / myEdgeLength[iE];
u2nodeVec.push_back( make_pair( normPar, nodes[i] ));
}
nItr = sm->GetNodes();
if ( u2nodeVec.empty() )
while ( nItr->more() )
for ( size_t i = 0; i < nodes.size(); ++i )
{
const SMDS_MeshNode* node = nItr->next();
if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
continue;
double u = helper.GetNodeU( myEdge[iE], node, 0, &paramOK );
double u = helper.GetNodeU( myEdge[iE], nodes[i], 0, &paramOK );
// paramSize is signed so orientation is taken into account
double normPar = prevNormPar + r * ( u - myFirst[iE] ) / paramSize;
u2nodeVec.push_back( make_pair( normPar, node ));
u2nodeVec.push_back( make_pair( normPar, nodes[i] ));
}
for ( size_t j = 0; j < u2nodeVec.size(); ++j )
u2node.insert( u2node.end(), u2nodeVec[j] );
}
// Put 2nd vertex node for a last edge
if ( iE+1 == myEdge.size() ) {
node = SMESH_Algo::VertexNode( VV[1], meshDS );
if ( !node ) {
MESSAGE(" NO NODE on VERTEX" );
return myPoints;
}
u2node.insert( u2node.end(), make_pair( 1., node ));
}
} // loop on myEdge's
if ( u2node.empty() ) return myPoints;
// Add 2nd VERTEX node for a last EDGE
{
const SMDS_MeshNode* node;
if ( IsClosed() )
node = u2node.begin()->second;
else
{
node = VertexNode( iE );
while ( !node && iE > 0 )
node = VertexNode( --iE );
if ( !node )
return myPoints;
}
if ( u2node.rbegin()->second == node )
u2node.erase( --u2node.end() );
u2node.insert( u2node.end(), make_pair( 1., node ));
}
if ( u2node.size() + nbProxyNodes != myNbPonits &&
u2node.size() + nbProxyNodes != NbPoints( /*update=*/true ))
{
@ -440,7 +432,7 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
// fill array of UVPtStruct
UVPtStructVec& points = const_cast< UVPtStructVec& >( myPoints );
UVPtStructVec& points = me->myPoints;
points.resize( myNbPonits );
int iPt = 0;
@ -487,7 +479,7 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
// -- U ----------------------------------------------
const SMDS_EdgePosition* epos =
dynamic_cast<const SMDS_EdgePosition*>(uvPt.node->GetPosition());
if ( epos ) {
if ( epos && uvPt.node->getshapeId() == myEdgeID[iE] ) {
uvPt.param = epos->GetUParameter();
}
else {
@ -577,65 +569,101 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::SimulateUVPtStruct(int nbSeg,
//purpose : Return nodes in the order they encounter while walking along the side
//=======================================================================
std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes() const
std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes(int theEdgeInd) const
{
vector<const SMDS_MeshNode*> resultNodes;
if ( myPoints.empty() )
if ( myPoints.empty() || ( theEdgeInd >= 0 && NbEdges() > 0 ))
{
if ( NbEdges() == 0 ) return resultNodes;
SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
SMESH_MesherHelper helper(*myProxyMesh->GetMesh());
bool paramOK;
bool paramOK = true;
// Sort nodes of all edges putting them into a map
map< double, const SMDS_MeshNode*> u2node;
for ( int i = 0; i < myEdge.size(); ++i )
map< double, const SMDS_MeshNode*> u2node;
vector<const SMDS_MeshNode*> nodes;
set<const SMDS_MeshNode*> vertexNodes;
int iE = 0, iEnd = myEdge.size();
if ( theEdgeInd >= 0 )
{
// Put 1st vertex node of a current edge
TopoDS_Vertex VV[2]; // TopExp::FirstVertex() returns NULL for INTERNAL edge
VV[0] = SMESH_MesherHelper::IthVertex( 0, myEdge[i]);
VV[1] = SMESH_MesherHelper::IthVertex( 1, myEdge[i]);
const SMDS_MeshNode* node = SMESH_Algo::VertexNode( VV[0], meshDS );
double prevNormPar = ( i == 0 ? 0 : myNormPar[ i-1 ]); // normalized param
if ( node ) { // nodes on internal vertices may be missing
u2node.insert( make_pair( prevNormPar, node ));
}
else if ( i == 0 ) {
MESSAGE(" NO NODE on VERTEX" );
return resultNodes;
}
iE = theEdgeInd % NbEdges();
iEnd = iE + 1;
}
for ( iE = 0; iE < iEnd; ++iE )
{
double prevNormPar = ( iE == 0 ? 0 : myNormPar[ iE-1 ]); // normalized param
// Put internal nodes
if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( myEdge[i] ))
const SMESH_ProxyMesh::SubMesh* proxySM = myProxyMesh->GetProxySubMesh( myEdge[iE] );
if ( proxySM )
{
SMDS_NodeIteratorPtr nItr = sm->GetNodes();
double paramSize = myLast[i] - myFirst[i];
double r = myNormPar[i] - prevNormPar;
helper.SetSubShape( myEdge[i] );
helper.ToFixNodeParameters( true );
while ( nItr->more() )
{
const SMDS_MeshNode* node = nItr->next();
if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
continue;
double u = helper.GetNodeU( myEdge[i], node, 0, &paramOK );
// paramSize is signed so orientation is taken into account
double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize;
u2node.insert( u2node.end(), make_pair( normPar, node ));
}
const UVPtStructVec& points = proxySM->GetUVPtStructVec();
for ( size_t i = 0; i < points.size(); ++i )
u2node.insert( make_pair( prevNormPar + points[i].normParam, points[i].node ));
continue;
}
// Put 2nd vertex node for a last edge
if ( i+1 == myEdge.size() ) {
node = SMESH_Algo::VertexNode( VV[1], meshDS );
if ( !node ) {
// Add 1st vertex node of a current EDGE
const SMDS_MeshNode* node = VertexNode( iE );
if ( node ) { // nodes on internal vertices may be missing
if ( vertexNodes.insert( node ).second )
u2node.insert( make_pair( prevNormPar, node ));
}
else if ( iE == 0 )
{
if ( nodes.empty() ) {
for ( ++iE; iE < iEnd; ++iE )
if (( node = VertexNode( iE ))) {
u2node.insert( make_pair( prevNormPar, node ));
break;
}
--iE;
}
if ( !node )
return resultNodes;
}
u2node.insert( u2node.end(), make_pair( 1., node ));
vertexNodes.insert( node );
}
// Add internal nodes
nodes.clear();
if ( !GetEdgeNodes( iE, nodes, /*v0=*/false, /*v1=*/false ))
return resultNodes;
if ( !nodes.empty() )
{
double paramSize = myLast[iE] - myFirst[iE];
double r = myNormPar[iE] - prevNormPar;
helper.SetSubShape( myEdge[iE] );
helper.ToFixNodeParameters( true );
for ( size_t i = 0; i < nodes.size(); ++i )
{
double u = helper.GetNodeU( myEdge[iE], nodes[i], 0, &paramOK );
// paramSize is signed so orientation is taken into account
double normPar = prevNormPar + r * ( u - myFirst[iE] ) / paramSize;
u2node.insert( u2node.end(), make_pair( normPar, nodes[i] ));
}
}
} // loop on myEdges
if ( u2node.empty() ) return resultNodes;
// Add 2nd vertex node for a last EDGE
{
const SMDS_MeshNode* node;
if ( IsClosed() && theEdgeInd < 0 )
node = u2node.begin()->second;
else
{
node = VertexNode( iE );
while ( !node && iE > 0 )
node = VertexNode( --iE );
if ( !node )
return resultNodes;
}
if ( u2node.rbegin()->second == node )
u2node.erase( --u2node.end() );
u2node.insert( u2node.end(), make_pair( 1., node ));
}
// Fill the result vector
@ -658,6 +686,135 @@ std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes() const
return resultNodes;
}
//================================================================================
/*!
* \brief Return (unsorted) nodes of the i-th EDGE.
* Nodes moved to other geometry by MergeNodes() are also returned.
* \retval bool - is OK
*/
//================================================================================
bool StdMeshers_FaceSide::GetEdgeNodes(size_t i,
vector<const SMDS_MeshNode*>& nodes,
bool inlude1stVertex,
bool inludeLastVertex) const
{
if ( i >= myEdge.size() )
return false;
SMESH_Mesh* mesh = myProxyMesh->GetMesh();
SMESHDS_Mesh* meshDS = mesh->GetMeshDS();
SMESHDS_SubMesh* sm = meshDS->MeshElements( myEdge[i] );
if ( inlude1stVertex )
{
const SMDS_MeshNode* n0 = VertexNode( i );
if ( !n0 ) return false;
nodes.push_back( n0 );
}
if ( sm && ( sm->NbElements() > 0 || sm->NbNodes() > 0 ))
{
if ( mesh->HasModificationsToDiscard() ) // check nb of nodes on the EDGE sub-mesh
{
int iQuad = sm->GetElements()->next()->IsQuadratic();
int nbExpect = sm->NbElements() - 1 + iQuad * sm->NbElements();
if ( nbExpect != sm->NbNodes() ) // some nodes are moved from the EDGE by MergeNodes()
{
// add nodes of all segments
typedef set< const SMDS_MeshNode* > TNodeSet;
TNodeSet sharedNodes;
SMDS_ElemIteratorPtr segIt = sm->GetElements();
while ( segIt->more() )
{
const SMDS_MeshElement* seg = segIt->next();
if ( seg->GetType() != SMDSAbs_Edge )
continue;
for ( int i = 0; i < 3-myIgnoreMediumNodes; ++i )
{
const SMDS_MeshNode* n = seg->GetNode( i );
if ( i == 2 ) // medium node
{
nodes.push_back( n );
}
else
{
pair<TNodeSet::iterator, bool> it2new = sharedNodes.insert( n );
if ( !it2new.second ) // n encounters twice == it's on EDGE, not on VERTEX
{
nodes.push_back( n );
sharedNodes.erase( it2new.first );
}
}
}
}
}
}
if ( nodes.size() < 2 ) // add nodes assigned to the EDGE
{
SMDS_NodeIteratorPtr nItr = sm->GetNodes();
while ( nItr->more() )
{
const SMDS_MeshNode* n = nItr->next();
if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( n, SMDSAbs_Edge ))
continue;
nodes.push_back( n );
}
}
} // if ( sm && sm->NbElements() > 0 )
if ( inludeLastVertex )
{
const SMDS_MeshNode* n1 = VertexNode( i+1 );
if ( !n1 ) return false;
nodes.push_back( n1 );
}
return true;
}
//================================================================================
/*!
* \brief Return a node from the i-th VERTEX (count starts from zero)
* Nodes moved to other geometry by MergeNodes() are also returned.
* \param [in] i - the VERTEX index
* \param [out] isMoved - returns \c true if the found node is moved by MergeNodes()
* \return const SMDS_MeshNode* - the found node
*/
//================================================================================
const SMDS_MeshNode* StdMeshers_FaceSide::VertexNode(std::size_t i, bool* isMoved) const
{
TopoDS_Vertex V = ( i >= myEdge.size() ) ? LastVertex() : FirstVertex(i);
const SMDS_MeshNode* n = SMESH_Algo::VertexNode( V, myProxyMesh->GetMeshDS() );
if ( !n && !myEdge.empty() && myProxyMesh->GetMesh()->HasModificationsToDiscard() )
{
size_t iE = ( i < myEdge.size() ) ? i : myEdge.size()-1;
SMESHDS_SubMesh* sm = myProxyMesh->GetMeshDS()->MeshElements( myEdgeID[ iE ]);
n = SMESH_Algo::VertexNode( V, sm, myProxyMesh->GetMesh(), /*checkV=*/false );
if (( !n ) &&
(( i > 0 && i < NbEdges() ) || IsClosed() ))
{
iE = SMESH_MesherHelper::WrapIndex( int(i)-1, NbEdges() );
sm = myProxyMesh->GetMeshDS()->MeshElements( myEdgeID[ iE ]);
n = SMESH_Algo::VertexNode( V, sm, myProxyMesh->GetMesh(), /*checkV=*/false );
}
if ( n && n->GetPosition()->GetDim() == 1 ) // check that n does not lie on an EDGE of myFace
{
TopoDS_Shape S = SMESH_MesherHelper::GetSubShapeByNode( n, myProxyMesh->GetMeshDS() );
if ( SMESH_MesherHelper::IsSubShape( S, myFace ))
n = 0; // VERTEX ignored by e.g. Composite Wire Discretization algo
}
if ( isMoved )
*isMoved = n;
}
return n;
}
//================================================================================
/*!
* \brief reverse order of vector elements
@ -667,8 +824,7 @@ std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes() const
template <typename T > void reverse(vector<T> & vec)
{
for ( int f=0, r=vec.size()-1; f < r; ++f, --r )
std::swap( vec[f], vec[r] );
std::reverse( vec.begin(), vec.end() );
}
//================================================================================
@ -790,28 +946,29 @@ int StdMeshers_FaceSide::NbPoints(const bool update) const
for ( int i = 0; i < NbEdges(); ++i )
{
TopoDS_Vertex v1 = SMESH_MesherHelper::IthVertex( 0, myEdge[i] );
if ( SMESH_Algo::VertexNode( v1, myProxyMesh->GetMeshDS() ))
me->myNbPonits += 1; // for the first end
else
me->myMissingVertexNodes = true;
if ( const SMESHDS_SubMesh* sm = myProxyMesh->GetSubMesh( Edge(i) )) {
int nbN = sm->NbNodes();
if ( myIgnoreMediumNodes ) {
SMDS_ElemIteratorPtr elemIt = sm->GetElements();
if ( elemIt->more() && elemIt->next()->IsQuadratic() )
nbN -= sm->NbElements();
if ( sm->NbElements() > 0 ) {
nbN = sm->NbElements() - 1; // nodes can be moved to other shapes by MergeNodes()
if ( !myIgnoreMediumNodes &&
sm->GetElements()->next()->IsQuadratic() )
nbN += sm->NbElements();
}
me->myNbPonits += nbN;
me->myNbSegments += sm->NbElements();
}
}
TopoDS_Vertex v1 = SMESH_MesherHelper::IthVertex( 1, Edge( NbEdges()-1 ));
if ( SMESH_Algo::VertexNode( v1, myProxyMesh->GetMeshDS() ))
me->myNbPonits++; // for the last end
else
me->myMissingVertexNodes = true;
std::set< const SMDS_MeshNode* > vNodes;
for ( int i = 0; i <= NbEdges(); ++i )
if ( const SMDS_MeshNode* n = VertexNode( i ))
vNodes.insert( n );
else
me->myMissingVertexNodes = true;
me->myNbPonits += vNodes.size();
if ( IsClosed() )
me->myNbPonits++; // closing node is repeated
}
return myNbPonits;
}
@ -928,7 +1085,7 @@ BRepAdaptor_CompCurve* StdMeshers_FaceSide::GetCurve3d() const
for ( int i=0; i<myEdge.size(); ++i )
aBuilder.Add( aWire, myEdge[i] );
if ( myEdge.size() == 2 && FirstVertex().IsSame( LastVertex() ))
if ( myEdge.size() == 2 && IsClosed() )
aWire.Closed(true); // issue 0021141
return new BRepAdaptor_CompCurve( aWire );
@ -1118,3 +1275,13 @@ TopoDS_Vertex StdMeshers_FaceSide::LastVertex(int i) const
return v;
}
//================================================================================
/*!
* \brief Return \c true if the chain of EDGEs is closed
*/
//================================================================================
bool StdMeshers_FaceSide::IsClosed() const
{
return myEdge.empty() ? false : FirstVertex().IsSame( LastVertex() );
}

View File

@ -191,10 +191,27 @@ public:
bool isXConst = 0,
double constValue = 0) const;
/*!
* \brief Return nodes in the order they encounter while walking along the side.
* \brief Return nodes in the order they encounter while walking along
* the while side or a specified EDGE.
* For a closed side, the 1st point repeats at end
*/
std::vector<const SMDS_MeshNode*> GetOrderedNodes() const;
std::vector<const SMDS_MeshNode*> GetOrderedNodes(int iE=-1) const;
/*!
* \brief Return nodes of the i-th EDGE.
* Nodes moved to other geometry by MergeNodes() are also returned.
* \retval bool - is OK
*/
bool GetEdgeNodes(const size_t i,
std::vector<const SMDS_MeshNode*>& nodes,
bool inlude1stVertex=true,
bool inludeLastVertex=true) const;
/*!
* \brief Return a node from the i-th VERTEX (count starts from zero)
* Nodes moved to other geometry by MergeNodes() are also returned.
*/
const SMDS_MeshNode* VertexNode(std::size_t i, bool* isMoved = 0) const;
/*!
* \brief Return edge and parameter on edge by normalized parameter
@ -229,13 +246,17 @@ public:
*/
const std::vector<TopoDS_Edge>& Edges() const { return myEdge; }
/*!
* \brief Return 1st vertex of the i-the edge (count starts from zero)
* \brief Return 1st vertex of the i-th edge (count starts from zero)
*/
TopoDS_Vertex FirstVertex(int i=0) const;
/*!
* \brief Return last vertex of the i-the edge (count starts from zero)
* \brief Return last vertex of the i-th edge (count starts from zero)
*/
TopoDS_Vertex LastVertex(int i=-1) const;
/*!
* \brief Return \c true if the chain of EDGEs is closed
*/
bool IsClosed() const;
/*!
* \brief Return side length
*/
@ -258,20 +279,20 @@ public:
*/
inline Handle(Geom2d_Curve) Curve2d(int i) const;
/*!
* \brief Return first normalized parameter of the i-the edge (count starts from zero)
* \brief Return first normalized parameter of the i-th edge (count starts from zero)
*/
inline double FirstParameter(int i) const;
/*!
* \brief Return last normalized parameter of the i-the edge (count starts from zero)
* \brief Return last normalized parameter of the i-th edge (count starts from zero)
*/
inline double LastParameter(int i) const;
/*!
* \brief Return first parameter of the i-the edge (count starts from zero).
* \brief Return first parameter of the i-th edge (count starts from zero).
* EDGE orientation is taken into account
*/
inline double FirstU(int i) const;
/*!
* \brief Return last parameter of the i-the edge (count starts from zero).
* \brief Return last parameter of the i-th edge (count starts from zero).
* EDGE orientation is taken into account
*/
inline double LastU(int i) const;
@ -289,6 +310,7 @@ protected:
void reverseProxySubmesh( const TopoDS_Edge& E );
// DON't FORGET to update Reverse() when adding one more vector!
TopoDS_Face myFace;
std::vector<uvPtStruct> myPoints, myFalsePoints;
std::vector<TopoDS_Edge> myEdge;
std::vector<int> myEdgeID;
@ -340,7 +362,7 @@ inline double StdMeshers_FaceSide::Parameter(double U, TopoDS_Edge & edge) const
//================================================================================
/*!
* \brief Return first normalized parameter of the i-the edge
* \brief Return first normalized parameter of the i-th edge
*/
//================================================================================
@ -351,7 +373,7 @@ inline double StdMeshers_FaceSide::FirstParameter(int i) const
//================================================================================
/*!
* \brief Return ast normalized parameter of the i-the edge
* \brief Return ast normalized parameter of the i-th edge
*/
//================================================================================
@ -362,7 +384,7 @@ inline double StdMeshers_FaceSide::LastParameter(int i) const
//================================================================================
/*!
* \brief Return first parameter of the i-the edge
* \brief Return first parameter of the i-th edge
*/
//================================================================================
@ -373,7 +395,7 @@ inline double StdMeshers_FaceSide::FirstU(int i) const
//================================================================================
/*!
* \brief Return last parameter of the i-the edge
* \brief Return last parameter of the i-th edge
*/
//================================================================================

View File

@ -441,32 +441,7 @@ namespace {
tgtWires.resize( srcWires.size() );
for ( size_t iW = 0; iW < srcWires.size(); ++iW )
{
// check ori
//bool reverse = false;
StdMeshers_FaceSidePtr srcWire = srcWires[iW];
// for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
// {
// if ( srcHelper.IsRealSeam( srcWire->EdgeID( iE )))
// continue;
// TopoDS_Shape srcE = srcWire->Edge( iE );
// TopoDS_Shape tgtE = shape2ShapeMap( srcE, /*isSrc=*/true);
// if ( shape2ShapeMap._assocType == TShapeShapeMap::PROPAGATION ||
// shape2ShapeMap._assocType == TShapeShapeMap::PROPAGATION)
// {
// reverse = false;
// }
// else if ( tgtMesh == srcMesh )
// {
// reverse = (( srcE.Orientation() == srcHelper.GetSubShapeOri( srcFace, srcE )) !=
// ( tgtE.Orientation() == srcHelper.GetSubShapeOri( tgtFace, tgtE )));
// }
// else
// {
// TopoDS_Shape srcEbis = shape2ShapeMap( tgtE, /*isSrc=*/false );
// reverse = ( srcE.Orientation() != srcEbis.Orientation() );
// }
// break;
// }
list< TopoDS_Edge > tgtEdges;
TopTools_IndexedMapOfShape edgeMap; // to detect seam edges
@ -476,7 +451,6 @@ namespace {
TopoDS_Edge tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true));
TopoDS_Shape srcEbis = shape2ShapeMap( tgtE, /*isSrc=*/false );
if ( srcE.Orientation() != srcEbis.Orientation() )
//if ( reverse )
tgtE.Reverse();
// reverse a seam edge encountered for the second time
const int index = edgeMap.Add( tgtE );
@ -504,56 +478,58 @@ namespace {
tgtE = nE.second;
}
tgtEdges.push_back( tgtE );
}
tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh,
/*theIsForward = */ true,
/*theIgnoreMediumNodes = */false));
StdMeshers_FaceSidePtr tgtWire = tgtWires[ iW ];
// Fill map of src to tgt nodes with nodes on edges
// Fill map of src to tgt nodes with nodes on edges
if ( srcMesh->GetSubMesh( srcE )->IsEmpty() ||
tgtMesh->GetSubMesh( tgtE )->IsEmpty() )
for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
{
if ( srcMesh->GetSubMesh( srcWire->Edge(iE) )->IsEmpty() ||
tgtMesh->GetSubMesh( tgtWire->Edge(iE) )->IsEmpty() )
{
// add nodes on VERTEXes for a case of not meshes EDGEs
const TopoDS_Shape& srcV = SMESH_MesherHelper::IthVertex( 0, srcE );
const TopoDS_Shape& tgtV = shape2ShapeMap( srcV, /*isSrc=*/true );
const SMDS_MeshNode* srcN = SMESH_Algo::VertexNode( TopoDS::Vertex( srcV ), srcMeshDS );
const SMDS_MeshNode* tgtN = SMESH_Algo::VertexNode( TopoDS::Vertex( tgtV ), tgtMeshDS );
const SMDS_MeshNode* srcN = srcWire->VertexNode( iE );
const SMDS_MeshNode* tgtN = tgtWire->VertexNode( iE );
if ( srcN && tgtN )
src2tgtNodes.insert( make_pair( srcN, tgtN ));
}
else
{
const bool skipMediumNodes = true;
map< double, const SMDS_MeshNode* > srcNodes, tgtNodes;
if ( !SMESH_Algo::GetSortedNodesOnEdge( srcMeshDS, srcE, skipMediumNodes, srcNodes) ||
!SMESH_Algo::GetSortedNodesOnEdge( tgtMeshDS, tgtE, skipMediumNodes, tgtNodes ))
return SMESH_ComputeError::New( COMPERR_BAD_INPUT_MESH,
"Invalid node parameters on edges");
const bool skipMedium = true, isFwd = true;
StdMeshers_FaceSide srcEdge( srcFace, srcWire->Edge(iE), srcMesh, isFwd, skipMedium);
StdMeshers_FaceSide tgtEdge( tgtFace, tgtWire->Edge(iE), tgtMesh, isFwd, skipMedium);
vector< const SMDS_MeshNode* > srcNodes = srcEdge.GetOrderedNodes();
vector< const SMDS_MeshNode* > tgtNodes = tgtEdge.GetOrderedNodes();
if (( srcNodes.size() != tgtNodes.size() ) && tgtNodes.size() > 0 )
return SMESH_ComputeError::New( COMPERR_BAD_INPUT_MESH,
"Different number of nodes on edges");
if ( !tgtNodes.empty() )
{
map< double, const SMDS_MeshNode* >::iterator u_tn = tgtNodes.begin();
if ( srcE.Orientation() == tgtE.Orientation() )
vector< const SMDS_MeshNode* >::iterator tn = tgtNodes.begin();
if ( srcWire->Edge(iE).Orientation() == tgtWire->Edge(iE).Orientation() )
{
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 ));
vector< const SMDS_MeshNode* >::iterator sn = srcNodes.begin();
for ( ; tn != tgtNodes.end(); ++tn, ++sn)
src2tgtNodes.insert( make_pair( *sn, *tn ));
}
else
{
map< double, const SMDS_MeshNode* >::reverse_iterator u_sn = srcNodes.rbegin();
for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn)
src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second ));
vector< const SMDS_MeshNode* >::reverse_iterator sn = srcNodes.rbegin();
for ( ; tn != tgtNodes.end(); ++tn, ++sn)
src2tgtNodes.insert( make_pair( *sn, *tn ));
}
is1DComputed = true;
}
}
} // loop on EDGEs of a WIRE
tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh,
/*theIsForward = */ true,
/*theIgnoreMediumNodes = */false));
} // loop on WIREs
return TError();
@ -670,7 +646,7 @@ namespace {
// Make new faces
// prepare the helper to adding quadratic elements if necessary
helper.SetSubShape( tgtFace );
//helper.SetSubShape( tgtFace );
helper.IsQuadraticSubMesh( tgtFace );
SMESHDS_SubMesh* srcSubDS = srcMeshDS->MeshElements( srcFace );

View File

@ -609,7 +609,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh,
int g = nbhoriz - 1; // last processed node in the regular grid
ilow = 0;
iup = nbhoriz - 1;
iup = nbhoriz - 1;
int stop = 0;
if ( quad->side[3].grid->Edge(0).IsNull() ) // left side is simulated one
@ -667,7 +667,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh,
for ( ; i > stop; i--) {
a = uv_e2[i].node;
b = uv_e2[i - 1].node;
gp_Pnt pb (b->X(), b->Y(), b->Z());
gp_Pnt pb = SMESH_TNodeXYZ( b );
// find node c in the grid, which will be linked with node b
int near = g;
@ -683,7 +683,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh,
nk = uv_e1[nbright - 2].node;
else
nk = quad->uv_grid[nbhoriz*(nbvertic - 2) + k].node;
gp_Pnt pnk (nk->X(), nk->Y(), nk->Z());
gp_Pnt pnk = SMESH_TNodeXYZ( nk );
double dist = pb.Distance(pnk);
if (dist < mind - eps) {
c = nk;
@ -4227,10 +4227,11 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace,
theNbDegenEdges = 0;
SMESH_MesherHelper helper( theMesh );
StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh, /*isFwd=*/true, /*skipMedium=*/true);
// sort theVertices by angle
multimap<double, TopoDS_Vertex> vertexByAngle;
TopTools_DataMapOfShapeReal angleByVertex;
TopTools_DataMapOfShapeReal angleByVertex;
TopoDS_Edge prevE = theWire.back();
if ( SMESH_Algo::isDegenerated( prevE ))
{
@ -4242,17 +4243,17 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace,
prevE = *edge;
}
list<TopoDS_Edge>::iterator edge = theWire.begin();
for ( ; edge != theWire.end(); ++edge )
for ( int iE = 0; edge != theWire.end(); ++edge, ++iE )
{
if ( SMESH_Algo::isDegenerated( *edge ))
{
++theNbDegenEdges;
continue;
}
TopoDS_Vertex v = helper.IthVertex( 0, *edge );
if ( !theConsiderMesh || SMESH_Algo::VertexNode( v, helper.GetMeshDS() ))
if ( !theConsiderMesh || faceSide.VertexNode( iE ))
{
double angle = SMESH_MesherHelper::GetAngle( prevE, *edge, theFace, v );
TopoDS_Vertex v = helper.IthVertex( 0, *edge );
double angle = SMESH_MesherHelper::GetAngle( prevE, *edge, theFace, v );
vertexByAngle.insert( make_pair( angle, v ));
angleByVertex.Bind( v, angle );
}
@ -4271,6 +4272,14 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace,
triaVertex.Nullify();
// check nb of available corners
if ( faceSide.NbEdges() < nbCorners )
return error(COMPERR_BAD_SHAPE,
TComm("Face must have 4 sides but not ") << faceSide.NbEdges() );
const int nbSegments = Max( faceSide.NbPoints()-1, faceSide.NbSegments() );
if ( nbSegments < nbCorners )
return error(COMPERR_BAD_INPUT_MESH, TComm("Too few boundary nodes: ") << nbSegments);
if ( nbCorners == 3 )
{
if ( vertexByAngle.size() < 3 )

View File

@ -436,7 +436,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh,
TopoDS_Edge CircEdge, LinEdge1, LinEdge2;
int nbe = analyseFace( aShape, CircEdge, LinEdge1, LinEdge2 );
Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge ));
if( nbe>3 || nbe < 1 || aCirc.IsNull() )
if( nbe > 3 || nbe < 1 || aCirc.IsNull() )
return error("The face must be a full circle or a part of circle (i.e. the number "
"of edges is less or equal to 3 and one of them is a circle curve)");