mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-13 02:00: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 =
|
const SMDS_EdgePosition* epos =
|
||||||
static_cast<const SMDS_EdgePosition*>(node->GetPosition());
|
static_cast<const SMDS_EdgePosition*>(node->GetPosition());
|
||||||
theNodes.insert( theNodes.end(), make_pair( epos->GetUParameter(), node ));
|
theNodes.insert( theNodes.end(), make_pair( epos->GetUParameter(), node ));
|
||||||
//MESSAGE("U " << epos->GetUParameter() << " ID " << node->GetID());
|
|
||||||
++nbNodes;
|
++nbNodes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add vertex nodes
|
// add vertex nodes
|
||||||
TopoDS_Vertex v1, v2;
|
TopoDS_Vertex v1, v2;
|
||||||
TopExp::Vertices(theEdge, v1, v2);
|
TopExp::Vertices(theEdge, v1, v2);
|
||||||
const SMDS_MeshNode* n1 = VertexNode( v1, (SMESHDS_Mesh*) theMesh );
|
const SMDS_MeshNode* n1 = VertexNode( v1, eSubMesh, 0 );
|
||||||
const SMDS_MeshNode* n2 = VertexNode( v2, (SMESHDS_Mesh*) theMesh );
|
const SMDS_MeshNode* n2 = VertexNode( v2, eSubMesh, 0 );
|
||||||
//MESSAGE("Vertices ID " << n1->GetID() << " " << n2->GetID());
|
|
||||||
Standard_Real f, l;
|
Standard_Real f, l;
|
||||||
BRep_Tool::Range(theEdge, f, l);
|
BRep_Tool::Range(theEdge, f, l);
|
||||||
if ( v1.Orientation() != TopAbs_FORWARD )
|
if ( v1.Orientation() != TopAbs_FORWARD )
|
||||||
@ -614,6 +612,118 @@ const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V,
|
|||||||
return 0;
|
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
|
//function : GetMeshError
|
||||||
//purpose : Finds topological errors of a sub-mesh
|
//purpose : Finds topological errors of a sub-mesh
|
||||||
|
@ -313,6 +313,7 @@ public:
|
|||||||
* \param theEdge - The geometrical edge of interest
|
* \param theEdge - The geometrical edge of interest
|
||||||
* \param theParams - The resulting vector of sorted node parameters
|
* \param theParams - The resulting vector of sorted node parameters
|
||||||
* \retval bool - false if not all parameters are OK
|
* \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,
|
static bool GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh,
|
||||||
const TopoDS_Edge& theEdge,
|
const TopoDS_Edge& theEdge,
|
||||||
@ -325,17 +326,14 @@ public:
|
|||||||
* \param ignoreMediumNodes - to store medium nodes of quadratic elements or not
|
* \param ignoreMediumNodes - to store medium nodes of quadratic elements or not
|
||||||
* \param typeToCheck - type of elements to check for medium nodes
|
* \param typeToCheck - type of elements to check for medium nodes
|
||||||
* \retval bool - false if not all parameters are OK
|
* \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,
|
static bool GetSortedNodesOnEdge(const SMESHDS_Mesh* theMesh,
|
||||||
const TopoDS_Edge& theEdge,
|
const TopoDS_Edge& theEdge,
|
||||||
const bool ignoreMediumNodes,
|
const bool ignoreMediumNodes,
|
||||||
std::map< double, const SMDS_MeshNode* > & theNodes,
|
std::map< double, const SMDS_MeshNode* > & theNodes,
|
||||||
const SMDSAbs_ElementType typeToCheck = SMDSAbs_All);
|
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
|
* \brief Compute length of an edge
|
||||||
* \param E - the edge
|
* \param E - the edge
|
||||||
@ -343,7 +341,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
static double EdgeLength(const TopoDS_Edge & E);
|
static double EdgeLength(const TopoDS_Edge & E);
|
||||||
|
|
||||||
//static int NumberOfWires(const TopoDS_Shape& S);
|
|
||||||
int NumberOfPoints(SMESH_Mesh& aMesh,const TopoDS_Wire& W);
|
int NumberOfPoints(SMESH_Mesh& aMesh,const TopoDS_Wire& W);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -372,11 +369,34 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief Return the node built on a vertex
|
* \brief Return the node built on a vertex
|
||||||
* \param V - the vertex
|
* \param V - the vertex
|
||||||
* \param meshDS - mesh
|
* \param meshDS - mesh data structure
|
||||||
* \retval const SMDS_MeshNode* - found node or NULL
|
* \retval const SMDS_MeshNode* - found node or NULL
|
||||||
*/
|
*/
|
||||||
static const SMDS_MeshNode* VertexNode(const TopoDS_Vertex& V, const SMESHDS_Mesh* meshDS);
|
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 };
|
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,7 +1131,7 @@ SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const
|
|||||||
if ( !subMesh )
|
if ( !subMesh )
|
||||||
return found;
|
return found;
|
||||||
|
|
||||||
// submeshes of groups have max IDs, so search from the map end
|
// sub-meshes of groups have max IDs, so search from the map end
|
||||||
SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) );
|
SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) );
|
||||||
while ( smIt->more() ) {
|
while ( smIt->more() ) {
|
||||||
SMESH_subMesh* sm = smIt->next();
|
SMESH_subMesh* sm = smIt->next();
|
||||||
@ -1158,6 +1158,12 @@ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) )
|
|||||||
found.push_back( mainSM );
|
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;
|
return found;
|
||||||
}
|
}
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
@ -191,8 +191,8 @@ bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( nbOldLinks == myTLinkNodeMap.size() )
|
// if ( nbOldLinks == myTLinkNodeMap.size() ) -- 0023068
|
||||||
myCreateQuadratic = false;
|
// myCreateQuadratic = false;
|
||||||
|
|
||||||
if(!myCreateQuadratic) {
|
if(!myCreateQuadratic) {
|
||||||
myTLinkNodeMap.clear();
|
myTLinkNodeMap.clear();
|
||||||
|
@ -455,7 +455,8 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
|
|||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
|
{
|
||||||
int dependsOnMapKey( const SMESH_subMesh* sm )
|
int dependsOnMapKey( const SMESH_subMesh* sm )
|
||||||
{
|
{
|
||||||
int type = sm->GetSubShape().ShapeType();
|
int type = sm->GetSubShape().ShapeType();
|
||||||
@ -479,6 +480,8 @@ void SMESH_subMesh::insertDependence(const TopoDS_Shape aShape,
|
|||||||
for ( ; sub.More(); sub.Next() )
|
for ( ; sub.More(); sub.Next() )
|
||||||
{
|
{
|
||||||
SMESH_subMesh *aSubMesh = _father->GetSubMesh( sub.Current() );
|
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 );
|
int cle = dependsOnMapKey( aSubMesh );
|
||||||
if ( _mapDepend.find( cle ) == _mapDepend.end())
|
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
|
// le retour des evenement father n'indiquent pas que add ou remove fait
|
||||||
|
|
||||||
SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK;
|
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();
|
SMESHDS_Mesh* meshDS =_father->GetMeshDS();
|
||||||
SMESH_Algo* algo = 0;
|
SMESH_Algo* algo = 0;
|
||||||
@ -1004,7 +1008,7 @@ SMESH_Hypothesis::Hypothesis_Status
|
|||||||
// detect algorithm hiding
|
// detect algorithm hiding
|
||||||
//
|
//
|
||||||
if ( ret == SMESH_Hypothesis::HYP_OK &&
|
if ( ret == SMESH_Hypothesis::HYP_OK &&
|
||||||
( event == ADD_ALGO || event == ADD_FATHER_ALGO ) &&
|
( event == ADD_ALGO || event == ADD_FATHER_ALGO ) && algo &&
|
||||||
algo->GetName() == anHyp->GetName() )
|
algo->GetName() == anHyp->GetName() )
|
||||||
{
|
{
|
||||||
// is algo hidden?
|
// is algo hidden?
|
||||||
|
@ -73,7 +73,7 @@ class SMESHDS_EXPORT SMESHDS_SubMesh
|
|||||||
int getSize();
|
int getSize();
|
||||||
void compactList();
|
void compactList();
|
||||||
|
|
||||||
SMESHDS_Mesh *GetParent() { return myParent; }
|
SMESHDS_Mesh* GetParent() const { return const_cast< SMESHDS_Mesh*>( myParent ); }
|
||||||
int GetID() const { return myIndex; }
|
int GetID() const { return myIndex; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -79,8 +79,6 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
|
|||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructor of a side of several edges
|
* \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 );
|
myNormPar.resize ( nbEdges );
|
||||||
myEdgeLength.resize( nbEdges );
|
myEdgeLength.resize( nbEdges );
|
||||||
myIsUniform.resize ( nbEdges, true );
|
myIsUniform.resize ( nbEdges, true );
|
||||||
|
myFace = theFace;
|
||||||
myLength = 0;
|
myLength = 0;
|
||||||
myNbPonits = myNbSegments = 0;
|
myNbPonits = myNbSegments = 0;
|
||||||
myProxyMesh = theProxyMesh;
|
myProxyMesh = theProxyMesh;
|
||||||
@ -132,25 +131,6 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
|
|||||||
if ( myEdge[i].Orientation() == TopAbs_REVERSED )
|
if ( myEdge[i].Orientation() == TopAbs_REVERSED )
|
||||||
std::swap( myFirst[i], myLast[i] );
|
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)
|
// check if the edge has a non-uniform parametrization (issue 0020705)
|
||||||
if ( !myC2d[i].IsNull() )
|
if ( !myC2d[i].IsNull() )
|
||||||
{
|
{
|
||||||
@ -159,7 +139,8 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
|
|||||||
Geom2dAdaptor_Curve A2dC( myC2d[i],
|
Geom2dAdaptor_Curve A2dC( myC2d[i],
|
||||||
std::min( myFirst[i], myLast[i] ),
|
std::min( myFirst[i], myLast[i] ),
|
||||||
std::max( 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 d2 = GCPnts_AbscissaPoint::Length( A2dC, myFirst[i], p2 );
|
||||||
double d4 = GCPnts_AbscissaPoint::Length( A2dC, myFirst[i], p4 );
|
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;
|
//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 ));
|
myC3dAdaptor[i].Load( C3d, 0, 0.5 * BRep_Tool::Tolerance( V ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// reverse a proxy submesh
|
// reverse a proxy sub-mesh
|
||||||
if ( !theIsForward )
|
if ( !theIsForward )
|
||||||
reverseProxySubmesh( myEdge[i] );
|
reverseProxySubmesh( myEdge[i] );
|
||||||
|
|
||||||
} // loop on edges
|
} // loop on edges
|
||||||
|
|
||||||
vExp.Initialize( theEdges.back() );
|
// count nodes and segments
|
||||||
if ( vExp.Value().Orientation() != TopAbs_REVERSED ) vExp.Next();
|
NbPoints( /*update=*/true );
|
||||||
if ( vExp.More() )
|
|
||||||
{
|
|
||||||
if ( SMESH_Algo::VertexNode( TopoDS::Vertex( vExp.Value()), meshDS ))
|
|
||||||
myNbPonits++; // for the last end
|
|
||||||
else
|
|
||||||
myMissingVertexNodes = true;
|
|
||||||
}
|
|
||||||
if ( nbEdges > 1 && myLength > DBL_MIN ) {
|
if ( nbEdges > 1 && myLength > DBL_MIN ) {
|
||||||
const double degenNormLen = 1.e-5;
|
const double degenNormLen = 1.e-5;
|
||||||
double totLength = myLength;
|
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
|
* \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;
|
myMissingVertexNodes = myIgnoreMediumNodes = false;
|
||||||
myDefaultPnt2d.SetCoord( 1e100, 1e100 );
|
myDefaultPnt2d.SetCoord( 1e100, 1e100 );
|
||||||
|
|
||||||
|
myFace = theFace;
|
||||||
myPoints = theSideNodes;
|
myPoints = theSideNodes;
|
||||||
myNbPonits = myPoints.size();
|
myNbPonits = myPoints.size();
|
||||||
myNbSegments = myNbPonits + 1;
|
myNbSegments = myNbPonits + 1;
|
||||||
@ -332,10 +306,11 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(UVPtStructVec& theSideNodes,
|
|||||||
const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
|
const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
|
||||||
double constValue) const
|
double constValue) const
|
||||||
{
|
{
|
||||||
if ( myPoints.empty() ) {
|
if ( myPoints.empty() )
|
||||||
|
{
|
||||||
if ( NbEdges() == 0 ) return myPoints;
|
if ( NbEdges() == 0 ) return myPoints;
|
||||||
|
|
||||||
|
StdMeshers_FaceSide* me = const_cast< StdMeshers_FaceSide* >( this );
|
||||||
SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
|
SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
|
||||||
SMESH_MesherHelper helper( *myProxyMesh->GetMesh() );
|
SMESH_MesherHelper helper( *myProxyMesh->GetMesh() );
|
||||||
bool paramOK;
|
bool paramOK;
|
||||||
@ -344,9 +319,14 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
|
|||||||
// sort nodes of all edges putting them into a map
|
// sort nodes of all edges putting them into a map
|
||||||
|
|
||||||
map< double, const SMDS_MeshNode*> u2node;
|
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() );
|
vector< const SMESH_ProxyMesh::SubMesh* > proxySubMesh( myEdge.size() );
|
||||||
int nbProxyNodes = 0;
|
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] );
|
proxySubMesh[iE] = myProxyMesh->GetProxySubMesh( myEdge[iE] );
|
||||||
if ( proxySubMesh[iE] )
|
if ( proxySubMesh[iE] )
|
||||||
@ -361,74 +341,86 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Put 1st vertex node of a current edge
|
|
||||||
TopoDS_Vertex VV[2]; // TopExp::FirstVertex() returns NULL for INTERNAL edge
|
// Add 1st vertex node of a current edge
|
||||||
VV[0] = SMESH_MesherHelper::IthVertex( 0, myEdge[iE]);
|
const SMDS_MeshNode* node = VertexNode( iE );
|
||||||
VV[1] = SMESH_MesherHelper::IthVertex( 1, myEdge[iE]);
|
const double prevNormPar = ( iE == 0 ? 0 : myNormPar[ iE-1 ]); // normalized param
|
||||||
const SMDS_MeshNode* node = SMESH_Algo::VertexNode( VV[0], meshDS );
|
if ( node ) // nodes on internal vertices may be missing
|
||||||
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 ));
|
u2node.insert( u2node.end(), make_pair( prevNormPar, node ));
|
||||||
}
|
}
|
||||||
else if ( iE == 0 ) {
|
else if ( iE == 0 )
|
||||||
MESSAGE(" NO NODE on VERTEX" );
|
{
|
||||||
|
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;
|
return myPoints;
|
||||||
|
vertexNodes.insert( node );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put internal nodes
|
// Add internal nodes
|
||||||
if ( const SMESHDS_SubMesh* sm = myProxyMesh->GetSubMesh( myEdge[iE] ))
|
nodes.clear();
|
||||||
|
if ( !GetEdgeNodes( iE, nodes, /*v0=*/false, /*v1=*/false ))
|
||||||
|
return myPoints;
|
||||||
|
if ( !nodes.empty() )
|
||||||
{
|
{
|
||||||
vector< pair< double, const SMDS_MeshNode*> > u2nodeVec;
|
u2nodeVec.clear();
|
||||||
u2nodeVec.reserve( sm->NbNodes() );
|
|
||||||
SMDS_NodeIteratorPtr nItr = sm->GetNodes();
|
|
||||||
double paramSize = myLast[iE] - myFirst[iE];
|
double paramSize = myLast[iE] - myFirst[iE];
|
||||||
double r = myNormPar[iE] - prevNormPar;
|
double r = myNormPar[iE] - prevNormPar;
|
||||||
helper.SetSubShape( myEdge[iE] );
|
helper.SetSubShape( myEdge[iE] );
|
||||||
helper.ToFixNodeParameters( true );
|
helper.ToFixNodeParameters( true );
|
||||||
if ( !myIsUniform[iE] )
|
if ( !myIsUniform[iE] )
|
||||||
while ( nItr->more() )
|
for ( size_t i = 0; i < nodes.size(); ++i )
|
||||||
{
|
{
|
||||||
const SMDS_MeshNode* node = nItr->next();
|
double u = helper.GetNodeU( myEdge[iE], nodes[i], 0, ¶mOK );
|
||||||
if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
|
double aLenU = GCPnts_AbscissaPoint::Length( me->myC3dAdaptor[iE], myFirst[iE], u );
|
||||||
continue;
|
|
||||||
double u = helper.GetNodeU( myEdge[iE], node, 0, ¶mOK );
|
|
||||||
double aLenU = GCPnts_AbscissaPoint::Length
|
|
||||||
( const_cast<GeomAdaptor_Curve&>( myC3dAdaptor[iE]), myFirst[iE], u );
|
|
||||||
if ( myEdgeLength[iE] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6"
|
if ( myEdgeLength[iE] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6"
|
||||||
{
|
{
|
||||||
u2nodeVec.clear();
|
u2nodeVec.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
double normPar = prevNormPar + r * aLenU / myEdgeLength[iE];
|
double normPar = prevNormPar + r * aLenU / myEdgeLength[iE];
|
||||||
u2nodeVec.push_back( make_pair( normPar, node ));
|
u2nodeVec.push_back( make_pair( normPar, nodes[i] ));
|
||||||
}
|
}
|
||||||
nItr = sm->GetNodes();
|
|
||||||
if ( u2nodeVec.empty() )
|
if ( u2nodeVec.empty() )
|
||||||
while ( nItr->more() )
|
for ( size_t i = 0; i < nodes.size(); ++i )
|
||||||
{
|
{
|
||||||
const SMDS_MeshNode* node = nItr->next();
|
double u = helper.GetNodeU( myEdge[iE], nodes[i], 0, ¶mOK );
|
||||||
if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
|
|
||||||
continue;
|
|
||||||
double u = helper.GetNodeU( myEdge[iE], node, 0, ¶mOK );
|
|
||||||
|
|
||||||
// paramSize is signed so orientation is taken into account
|
// paramSize is signed so orientation is taken into account
|
||||||
double normPar = prevNormPar + r * ( u - myFirst[iE] ) / paramSize;
|
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 )
|
for ( size_t j = 0; j < u2nodeVec.size(); ++j )
|
||||||
u2node.insert( u2node.end(), u2nodeVec[j] );
|
u2node.insert( u2node.end(), u2nodeVec[j] );
|
||||||
}
|
}
|
||||||
|
} // loop on myEdge's
|
||||||
|
|
||||||
// Put 2nd vertex node for a last edge
|
if ( u2node.empty() ) return myPoints;
|
||||||
if ( iE+1 == myEdge.size() ) {
|
|
||||||
node = SMESH_Algo::VertexNode( VV[1], meshDS );
|
// Add 2nd VERTEX node for a last EDGE
|
||||||
if ( !node ) {
|
{
|
||||||
MESSAGE(" NO NODE on VERTEX" );
|
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;
|
return myPoints;
|
||||||
}
|
}
|
||||||
|
if ( u2node.rbegin()->second == node )
|
||||||
|
u2node.erase( --u2node.end() );
|
||||||
u2node.insert( u2node.end(), make_pair( 1., node ));
|
u2node.insert( u2node.end(), make_pair( 1., node ));
|
||||||
}
|
}
|
||||||
} // loop on myEdge's
|
|
||||||
|
|
||||||
if ( u2node.size() + nbProxyNodes != myNbPonits &&
|
if ( u2node.size() + nbProxyNodes != myNbPonits &&
|
||||||
u2node.size() + nbProxyNodes != NbPoints( /*update=*/true ))
|
u2node.size() + nbProxyNodes != NbPoints( /*update=*/true ))
|
||||||
@ -440,7 +432,7 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
|
|||||||
|
|
||||||
// fill array of UVPtStruct
|
// fill array of UVPtStruct
|
||||||
|
|
||||||
UVPtStructVec& points = const_cast< UVPtStructVec& >( myPoints );
|
UVPtStructVec& points = me->myPoints;
|
||||||
points.resize( myNbPonits );
|
points.resize( myNbPonits );
|
||||||
|
|
||||||
int iPt = 0;
|
int iPt = 0;
|
||||||
@ -487,7 +479,7 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
|
|||||||
// -- U ----------------------------------------------
|
// -- U ----------------------------------------------
|
||||||
const SMDS_EdgePosition* epos =
|
const SMDS_EdgePosition* epos =
|
||||||
dynamic_cast<const SMDS_EdgePosition*>(uvPt.node->GetPosition());
|
dynamic_cast<const SMDS_EdgePosition*>(uvPt.node->GetPosition());
|
||||||
if ( epos ) {
|
if ( epos && uvPt.node->getshapeId() == myEdgeID[iE] ) {
|
||||||
uvPt.param = epos->GetUParameter();
|
uvPt.param = epos->GetUParameter();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -577,66 +569,102 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::SimulateUVPtStruct(int nbSeg,
|
|||||||
//purpose : Return nodes in the order they encounter while walking along the side
|
//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;
|
vector<const SMDS_MeshNode*> resultNodes;
|
||||||
if ( myPoints.empty() )
|
if ( myPoints.empty() || ( theEdgeInd >= 0 && NbEdges() > 0 ))
|
||||||
{
|
{
|
||||||
if ( NbEdges() == 0 ) return resultNodes;
|
if ( NbEdges() == 0 ) return resultNodes;
|
||||||
|
|
||||||
SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
|
SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
|
||||||
SMESH_MesherHelper helper(*myProxyMesh->GetMesh());
|
SMESH_MesherHelper helper(*myProxyMesh->GetMesh());
|
||||||
bool paramOK;
|
bool paramOK = true;
|
||||||
|
|
||||||
// Sort nodes of all edges putting them into a map
|
// Sort nodes of all edges putting them into a map
|
||||||
|
|
||||||
map< double, const SMDS_MeshNode*> u2node;
|
map< double, const SMDS_MeshNode*> u2node;
|
||||||
for ( int i = 0; i < myEdge.size(); ++i )
|
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
|
iE = theEdgeInd % NbEdges();
|
||||||
TopoDS_Vertex VV[2]; // TopExp::FirstVertex() returns NULL for INTERNAL edge
|
iEnd = iE + 1;
|
||||||
VV[0] = SMESH_MesherHelper::IthVertex( 0, myEdge[i]);
|
}
|
||||||
VV[1] = SMESH_MesherHelper::IthVertex( 1, myEdge[i]);
|
for ( iE = 0; iE < iEnd; ++iE )
|
||||||
const SMDS_MeshNode* node = SMESH_Algo::VertexNode( VV[0], meshDS );
|
{
|
||||||
double prevNormPar = ( i == 0 ? 0 : myNormPar[ i-1 ]); // normalized param
|
double prevNormPar = ( iE == 0 ? 0 : myNormPar[ iE-1 ]); // normalized param
|
||||||
|
|
||||||
|
const SMESH_ProxyMesh::SubMesh* proxySM = myProxyMesh->GetProxySubMesh( myEdge[iE] );
|
||||||
|
if ( proxySM )
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add 1st vertex node of a current EDGE
|
||||||
|
const SMDS_MeshNode* node = VertexNode( iE );
|
||||||
if ( node ) { // nodes on internal vertices may be missing
|
if ( node ) { // nodes on internal vertices may be missing
|
||||||
|
if ( vertexNodes.insert( node ).second )
|
||||||
u2node.insert( make_pair( prevNormPar, node ));
|
u2node.insert( make_pair( prevNormPar, node ));
|
||||||
}
|
}
|
||||||
else if ( i == 0 ) {
|
else if ( iE == 0 )
|
||||||
MESSAGE(" NO NODE on VERTEX" );
|
{
|
||||||
|
if ( nodes.empty() ) {
|
||||||
|
for ( ++iE; iE < iEnd; ++iE )
|
||||||
|
if (( node = VertexNode( iE ))) {
|
||||||
|
u2node.insert( make_pair( prevNormPar, node ));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
--iE;
|
||||||
|
}
|
||||||
|
if ( !node )
|
||||||
return resultNodes;
|
return resultNodes;
|
||||||
|
vertexNodes.insert( node );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put internal nodes
|
// Add internal nodes
|
||||||
if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( myEdge[i] ))
|
nodes.clear();
|
||||||
|
if ( !GetEdgeNodes( iE, nodes, /*v0=*/false, /*v1=*/false ))
|
||||||
|
return resultNodes;
|
||||||
|
if ( !nodes.empty() )
|
||||||
{
|
{
|
||||||
SMDS_NodeIteratorPtr nItr = sm->GetNodes();
|
double paramSize = myLast[iE] - myFirst[iE];
|
||||||
double paramSize = myLast[i] - myFirst[i];
|
double r = myNormPar[iE] - prevNormPar;
|
||||||
double r = myNormPar[i] - prevNormPar;
|
helper.SetSubShape( myEdge[iE] );
|
||||||
helper.SetSubShape( myEdge[i] );
|
|
||||||
helper.ToFixNodeParameters( true );
|
helper.ToFixNodeParameters( true );
|
||||||
while ( nItr->more() )
|
for ( size_t i = 0; i < nodes.size(); ++i )
|
||||||
{
|
{
|
||||||
const SMDS_MeshNode* node = nItr->next();
|
double u = helper.GetNodeU( myEdge[iE], nodes[i], 0, ¶mOK );
|
||||||
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
|
// paramSize is signed so orientation is taken into account
|
||||||
double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize;
|
double normPar = prevNormPar + r * ( u - myFirst[iE] ) / paramSize;
|
||||||
u2node.insert( u2node.end(), make_pair( normPar, node ));
|
u2node.insert( u2node.end(), make_pair( normPar, nodes[i] ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put 2nd vertex node for a last edge
|
} // loop on myEdges
|
||||||
if ( i+1 == myEdge.size() ) {
|
|
||||||
node = SMESH_Algo::VertexNode( VV[1], meshDS );
|
if ( u2node.empty() ) return resultNodes;
|
||||||
if ( !node ) {
|
|
||||||
|
// 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;
|
return resultNodes;
|
||||||
}
|
}
|
||||||
|
if ( u2node.rbegin()->second == node )
|
||||||
|
u2node.erase( --u2node.end() );
|
||||||
u2node.insert( u2node.end(), make_pair( 1., node ));
|
u2node.insert( u2node.end(), make_pair( 1., node ));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Fill the result vector
|
// Fill the result vector
|
||||||
|
|
||||||
@ -658,6 +686,135 @@ std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes() const
|
|||||||
return resultNodes;
|
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
|
* \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)
|
template <typename T > void reverse(vector<T> & vec)
|
||||||
{
|
{
|
||||||
for ( int f=0, r=vec.size()-1; f < r; ++f, --r )
|
std::reverse( vec.begin(), vec.end() );
|
||||||
std::swap( vec[f], vec[r] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -790,28 +946,29 @@ int StdMeshers_FaceSide::NbPoints(const bool update) const
|
|||||||
|
|
||||||
for ( int i = 0; i < NbEdges(); ++i )
|
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) )) {
|
if ( const SMESHDS_SubMesh* sm = myProxyMesh->GetSubMesh( Edge(i) )) {
|
||||||
int nbN = sm->NbNodes();
|
int nbN = sm->NbNodes();
|
||||||
if ( myIgnoreMediumNodes ) {
|
if ( sm->NbElements() > 0 ) {
|
||||||
SMDS_ElemIteratorPtr elemIt = sm->GetElements();
|
nbN = sm->NbElements() - 1; // nodes can be moved to other shapes by MergeNodes()
|
||||||
if ( elemIt->more() && elemIt->next()->IsQuadratic() )
|
if ( !myIgnoreMediumNodes &&
|
||||||
nbN -= sm->NbElements();
|
sm->GetElements()->next()->IsQuadratic() )
|
||||||
|
nbN += sm->NbElements();
|
||||||
}
|
}
|
||||||
me->myNbPonits += nbN;
|
me->myNbPonits += nbN;
|
||||||
me->myNbSegments += sm->NbElements();
|
me->myNbSegments += sm->NbElements();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TopoDS_Vertex v1 = SMESH_MesherHelper::IthVertex( 1, Edge( NbEdges()-1 ));
|
|
||||||
if ( SMESH_Algo::VertexNode( v1, myProxyMesh->GetMeshDS() ))
|
std::set< const SMDS_MeshNode* > vNodes;
|
||||||
me->myNbPonits++; // for the last end
|
for ( int i = 0; i <= NbEdges(); ++i )
|
||||||
|
if ( const SMDS_MeshNode* n = VertexNode( i ))
|
||||||
|
vNodes.insert( n );
|
||||||
else
|
else
|
||||||
me->myMissingVertexNodes = true;
|
me->myMissingVertexNodes = true;
|
||||||
|
me->myNbPonits += vNodes.size();
|
||||||
|
|
||||||
|
if ( IsClosed() )
|
||||||
|
me->myNbPonits++; // closing node is repeated
|
||||||
}
|
}
|
||||||
return myNbPonits;
|
return myNbPonits;
|
||||||
}
|
}
|
||||||
@ -928,7 +1085,7 @@ BRepAdaptor_CompCurve* StdMeshers_FaceSide::GetCurve3d() const
|
|||||||
for ( int i=0; i<myEdge.size(); ++i )
|
for ( int i=0; i<myEdge.size(); ++i )
|
||||||
aBuilder.Add( aWire, myEdge[i] );
|
aBuilder.Add( aWire, myEdge[i] );
|
||||||
|
|
||||||
if ( myEdge.size() == 2 && FirstVertex().IsSame( LastVertex() ))
|
if ( myEdge.size() == 2 && IsClosed() )
|
||||||
aWire.Closed(true); // issue 0021141
|
aWire.Closed(true); // issue 0021141
|
||||||
|
|
||||||
return new BRepAdaptor_CompCurve( aWire );
|
return new BRepAdaptor_CompCurve( aWire );
|
||||||
@ -1118,3 +1275,13 @@ TopoDS_Vertex StdMeshers_FaceSide::LastVertex(int i) const
|
|||||||
return v;
|
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,
|
bool isXConst = 0,
|
||||||
double constValue = 0) const;
|
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
|
* 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
|
* \brief Return edge and parameter on edge by normalized parameter
|
||||||
@ -229,13 +246,17 @@ public:
|
|||||||
*/
|
*/
|
||||||
const std::vector<TopoDS_Edge>& Edges() const { return myEdge; }
|
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;
|
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;
|
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
|
* \brief Return side length
|
||||||
*/
|
*/
|
||||||
@ -258,20 +279,20 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline Handle(Geom2d_Curve) Curve2d(int i) const;
|
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;
|
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;
|
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
|
* EDGE orientation is taken into account
|
||||||
*/
|
*/
|
||||||
inline double FirstU(int i) const;
|
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
|
* EDGE orientation is taken into account
|
||||||
*/
|
*/
|
||||||
inline double LastU(int i) const;
|
inline double LastU(int i) const;
|
||||||
@ -289,6 +310,7 @@ protected:
|
|||||||
void reverseProxySubmesh( const TopoDS_Edge& E );
|
void reverseProxySubmesh( const TopoDS_Edge& E );
|
||||||
|
|
||||||
// DON't FORGET to update Reverse() when adding one more vector!
|
// DON't FORGET to update Reverse() when adding one more vector!
|
||||||
|
TopoDS_Face myFace;
|
||||||
std::vector<uvPtStruct> myPoints, myFalsePoints;
|
std::vector<uvPtStruct> myPoints, myFalsePoints;
|
||||||
std::vector<TopoDS_Edge> myEdge;
|
std::vector<TopoDS_Edge> myEdge;
|
||||||
std::vector<int> myEdgeID;
|
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() );
|
tgtWires.resize( srcWires.size() );
|
||||||
for ( size_t iW = 0; iW < srcWires.size(); ++iW )
|
for ( size_t iW = 0; iW < srcWires.size(); ++iW )
|
||||||
{
|
{
|
||||||
// check ori
|
|
||||||
//bool reverse = false;
|
|
||||||
StdMeshers_FaceSidePtr srcWire = srcWires[iW];
|
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;
|
list< TopoDS_Edge > tgtEdges;
|
||||||
TopTools_IndexedMapOfShape edgeMap; // to detect seam edges
|
TopTools_IndexedMapOfShape edgeMap; // to detect seam edges
|
||||||
@ -476,7 +451,6 @@ namespace {
|
|||||||
TopoDS_Edge tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true));
|
TopoDS_Edge tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true));
|
||||||
TopoDS_Shape srcEbis = shape2ShapeMap( tgtE, /*isSrc=*/false );
|
TopoDS_Shape srcEbis = shape2ShapeMap( tgtE, /*isSrc=*/false );
|
||||||
if ( srcE.Orientation() != srcEbis.Orientation() )
|
if ( srcE.Orientation() != srcEbis.Orientation() )
|
||||||
//if ( reverse )
|
|
||||||
tgtE.Reverse();
|
tgtE.Reverse();
|
||||||
// reverse a seam edge encountered for the second time
|
// reverse a seam edge encountered for the second time
|
||||||
const int index = edgeMap.Add( tgtE );
|
const int index = edgeMap.Add( tgtE );
|
||||||
@ -504,56 +478,58 @@ namespace {
|
|||||||
tgtE = nE.second;
|
tgtE = nE.second;
|
||||||
}
|
}
|
||||||
tgtEdges.push_back( tgtE );
|
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() ||
|
for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
|
||||||
tgtMesh->GetSubMesh( tgtE )->IsEmpty() )
|
{
|
||||||
|
if ( srcMesh->GetSubMesh( srcWire->Edge(iE) )->IsEmpty() ||
|
||||||
|
tgtMesh->GetSubMesh( tgtWire->Edge(iE) )->IsEmpty() )
|
||||||
{
|
{
|
||||||
// add nodes on VERTEXes for a case of not meshes EDGEs
|
// add nodes on VERTEXes for a case of not meshes EDGEs
|
||||||
const TopoDS_Shape& srcV = SMESH_MesherHelper::IthVertex( 0, srcE );
|
const SMDS_MeshNode* srcN = srcWire->VertexNode( iE );
|
||||||
const TopoDS_Shape& tgtV = shape2ShapeMap( srcV, /*isSrc=*/true );
|
const SMDS_MeshNode* tgtN = tgtWire->VertexNode( iE );
|
||||||
const SMDS_MeshNode* srcN = SMESH_Algo::VertexNode( TopoDS::Vertex( srcV ), srcMeshDS );
|
|
||||||
const SMDS_MeshNode* tgtN = SMESH_Algo::VertexNode( TopoDS::Vertex( tgtV ), tgtMeshDS );
|
|
||||||
if ( srcN && tgtN )
|
if ( srcN && tgtN )
|
||||||
src2tgtNodes.insert( make_pair( srcN, tgtN ));
|
src2tgtNodes.insert( make_pair( srcN, tgtN ));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const bool skipMediumNodes = true;
|
const bool skipMedium = true, isFwd = true;
|
||||||
map< double, const SMDS_MeshNode* > srcNodes, tgtNodes;
|
StdMeshers_FaceSide srcEdge( srcFace, srcWire->Edge(iE), srcMesh, isFwd, skipMedium);
|
||||||
if ( !SMESH_Algo::GetSortedNodesOnEdge( srcMeshDS, srcE, skipMediumNodes, srcNodes) ||
|
StdMeshers_FaceSide tgtEdge( tgtFace, tgtWire->Edge(iE), tgtMesh, isFwd, skipMedium);
|
||||||
!SMESH_Algo::GetSortedNodesOnEdge( tgtMeshDS, tgtE, skipMediumNodes, tgtNodes ))
|
|
||||||
return SMESH_ComputeError::New( COMPERR_BAD_INPUT_MESH,
|
vector< const SMDS_MeshNode* > srcNodes = srcEdge.GetOrderedNodes();
|
||||||
"Invalid node parameters on edges");
|
vector< const SMDS_MeshNode* > tgtNodes = tgtEdge.GetOrderedNodes();
|
||||||
|
|
||||||
if (( srcNodes.size() != tgtNodes.size() ) && tgtNodes.size() > 0 )
|
if (( srcNodes.size() != tgtNodes.size() ) && tgtNodes.size() > 0 )
|
||||||
return SMESH_ComputeError::New( COMPERR_BAD_INPUT_MESH,
|
return SMESH_ComputeError::New( COMPERR_BAD_INPUT_MESH,
|
||||||
"Different number of nodes on edges");
|
"Different number of nodes on edges");
|
||||||
if ( !tgtNodes.empty() )
|
if ( !tgtNodes.empty() )
|
||||||
{
|
{
|
||||||
map< double, const SMDS_MeshNode* >::iterator u_tn = tgtNodes.begin();
|
vector< const SMDS_MeshNode* >::iterator tn = tgtNodes.begin();
|
||||||
if ( srcE.Orientation() == tgtE.Orientation() )
|
if ( srcWire->Edge(iE).Orientation() == tgtWire->Edge(iE).Orientation() )
|
||||||
{
|
{
|
||||||
map< double, const SMDS_MeshNode* >::iterator u_sn = srcNodes.begin();
|
vector< const SMDS_MeshNode* >::iterator sn = srcNodes.begin();
|
||||||
for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn)
|
for ( ; tn != tgtNodes.end(); ++tn, ++sn)
|
||||||
src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second ));
|
src2tgtNodes.insert( make_pair( *sn, *tn ));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
map< double, const SMDS_MeshNode* >::reverse_iterator u_sn = srcNodes.rbegin();
|
vector< const SMDS_MeshNode* >::reverse_iterator sn = srcNodes.rbegin();
|
||||||
for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn)
|
for ( ; tn != tgtNodes.end(); ++tn, ++sn)
|
||||||
src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second ));
|
src2tgtNodes.insert( make_pair( *sn, *tn ));
|
||||||
}
|
}
|
||||||
is1DComputed = true;
|
is1DComputed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // loop on EDGEs of a WIRE
|
} // loop on EDGEs of a WIRE
|
||||||
|
|
||||||
tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh,
|
|
||||||
/*theIsForward = */ true,
|
|
||||||
/*theIgnoreMediumNodes = */false));
|
|
||||||
} // loop on WIREs
|
} // loop on WIREs
|
||||||
|
|
||||||
return TError();
|
return TError();
|
||||||
@ -670,7 +646,7 @@ namespace {
|
|||||||
// Make new faces
|
// Make new faces
|
||||||
|
|
||||||
// prepare the helper to adding quadratic elements if necessary
|
// prepare the helper to adding quadratic elements if necessary
|
||||||
helper.SetSubShape( tgtFace );
|
//helper.SetSubShape( tgtFace );
|
||||||
helper.IsQuadraticSubMesh( tgtFace );
|
helper.IsQuadraticSubMesh( tgtFace );
|
||||||
|
|
||||||
SMESHDS_SubMesh* srcSubDS = srcMeshDS->MeshElements( srcFace );
|
SMESHDS_SubMesh* srcSubDS = srcMeshDS->MeshElements( srcFace );
|
||||||
|
@ -667,7 +667,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh,
|
|||||||
for ( ; i > stop; i--) {
|
for ( ; i > stop; i--) {
|
||||||
a = uv_e2[i].node;
|
a = uv_e2[i].node;
|
||||||
b = uv_e2[i - 1].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
|
// find node c in the grid, which will be linked with node b
|
||||||
int near = g;
|
int near = g;
|
||||||
@ -683,7 +683,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh,
|
|||||||
nk = uv_e1[nbright - 2].node;
|
nk = uv_e1[nbright - 2].node;
|
||||||
else
|
else
|
||||||
nk = quad->uv_grid[nbhoriz*(nbvertic - 2) + k].node;
|
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);
|
double dist = pb.Distance(pnk);
|
||||||
if (dist < mind - eps) {
|
if (dist < mind - eps) {
|
||||||
c = nk;
|
c = nk;
|
||||||
@ -4227,6 +4227,7 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace,
|
|||||||
theNbDegenEdges = 0;
|
theNbDegenEdges = 0;
|
||||||
|
|
||||||
SMESH_MesherHelper helper( theMesh );
|
SMESH_MesherHelper helper( theMesh );
|
||||||
|
StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh, /*isFwd=*/true, /*skipMedium=*/true);
|
||||||
|
|
||||||
// sort theVertices by angle
|
// sort theVertices by angle
|
||||||
multimap<double, TopoDS_Vertex> vertexByAngle;
|
multimap<double, TopoDS_Vertex> vertexByAngle;
|
||||||
@ -4242,16 +4243,16 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace,
|
|||||||
prevE = *edge;
|
prevE = *edge;
|
||||||
}
|
}
|
||||||
list<TopoDS_Edge>::iterator edge = theWire.begin();
|
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 ))
|
if ( SMESH_Algo::isDegenerated( *edge ))
|
||||||
{
|
{
|
||||||
++theNbDegenEdges;
|
++theNbDegenEdges;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TopoDS_Vertex v = helper.IthVertex( 0, *edge );
|
if ( !theConsiderMesh || faceSide.VertexNode( iE ))
|
||||||
if ( !theConsiderMesh || SMESH_Algo::VertexNode( v, helper.GetMeshDS() ))
|
|
||||||
{
|
{
|
||||||
|
TopoDS_Vertex v = helper.IthVertex( 0, *edge );
|
||||||
double angle = SMESH_MesherHelper::GetAngle( prevE, *edge, theFace, v );
|
double angle = SMESH_MesherHelper::GetAngle( prevE, *edge, theFace, v );
|
||||||
vertexByAngle.insert( make_pair( angle, v ));
|
vertexByAngle.insert( make_pair( angle, v ));
|
||||||
angleByVertex.Bind( v, angle );
|
angleByVertex.Bind( v, angle );
|
||||||
@ -4271,6 +4272,14 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace,
|
|||||||
triaVertex.Nullify();
|
triaVertex.Nullify();
|
||||||
|
|
||||||
// check nb of available corners
|
// 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 ( nbCorners == 3 )
|
||||||
{
|
{
|
||||||
if ( vertexByAngle.size() < 3 )
|
if ( vertexByAngle.size() < 3 )
|
||||||
|
Loading…
Reference in New Issue
Block a user