mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-12 17:50:34 +05:00
23068: [CEA 1505] Be able to keep meshing in 2D after having merged the nodes in 1D
This commit is contained in:
parent
ff644361c8
commit
0e017d4c87
@ -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
|
||||
|
@ -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 };
|
||||
|
||||
/*!
|
||||
|
@ -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;
|
||||
}
|
||||
//=======================================================================
|
||||
|
@ -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();
|
||||
|
@ -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?
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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, ¶mOK );
|
||||
double aLenU = GCPnts_AbscissaPoint::Length
|
||||
( const_cast<GeomAdaptor_Curve&>( myC3dAdaptor[iE]), myFirst[iE], u );
|
||||
double u = helper.GetNodeU( myEdge[iE], nodes[i], 0, ¶mOK );
|
||||
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, ¶mOK );
|
||||
|
||||
double u = helper.GetNodeU( myEdge[iE], nodes[i], 0, ¶mOK );
|
||||
// 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, ¶mOK );
|
||||
|
||||
// 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, ¶mOK );
|
||||
// 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() );
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
|
@ -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 );
|
||||
|
@ -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 )
|
||||
|
@ -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)");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user