-// Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_Surface.hxx>
#include <ShapeAnalysis.hxx>
+#include <ShapeAnalysis_Curve.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
// corresponding EDGE from FACE, get pcurve for this
// EDGE and retrieve value from this pcurve
SMDS_EdgePositionPtr epos = pos;
- const int edgeID = n->getshapeId();
- const TopoDS_Edge& E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID ));
+ const int edgeID = n->getshapeId();
+ const TopoDS_Edge& E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID ));
double f, l, u = epos->GetUParameter();
- Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( E, F, f, l );
+ Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( E, F, f, l );
bool validU = ( !C2d.IsNull() && ( f < u ) && ( u < l ));
if ( validU ) uv = C2d->Value( u );
else uv.SetCoord( Precision::Infinite(),0.);
if ( isSeam )
uv = getUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
}
+ else if ( myParIndex && n2 )
+ {
+ gp_Pnt2d oldUV = uv;
+ gp_Pnt2d uv2 = GetNodeUV( F, n2, 0 );
+ if ( myParIndex & 1 )
+ uv.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod( uv.X(), myPar1[0], myPar2[0]));
+ if ( myParIndex & 2 )
+ uv.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod( uv.Y(), myPar1[1], myPar2[1]));
+ if ( uv.SquareDistance( uv2 ) > oldUV.SquareDistance( uv2 ))
+ uv = oldUV;
+ }
}
}
else
return *( i_proj->second );
}
+//=======================================================================
+//function : GetProjector
+//purpose : Return projector initialized by given face, which is returned
+//=======================================================================
+
+GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face& F,
+ double tol ) const
+{
+ Handle(Geom_Surface) surface = BRep_Tool::Surface( F );
+ int faceID = GetMeshDS()->ShapeToIndex( F );
+ TID2ProjectorOnSurf& i2proj = const_cast< TID2ProjectorOnSurf&>( myFace2Projector );
+ TID2ProjectorOnSurf::iterator i_proj = i2proj.find( faceID );
+ if ( i_proj == i2proj.end() )
+ {
+ if ( tol == 0 ) tol = BRep_Tool::Tolerance( F );
+ double U1, U2, V1, V2;
+ surface->Bounds(U1, U2, V1, V2);
+ GeomAPI_ProjectPointOnSurf* proj = new GeomAPI_ProjectPointOnSurf();
+ proj->Init( surface, U1, U2, V1, V2, tol );
+ i_proj = i2proj.insert( make_pair( faceID, proj )).first;
+ }
+ return *( i_proj->second );
+}
+
+//=======================================================================
+//function : GetPCProjector
+//purpose : Return projector initialized by given EDGE
+//=======================================================================
+
+GeomAPI_ProjectPointOnCurve& SMESH_MesherHelper::GetPCProjector(const TopoDS_Edge& E ) const
+{
+ int edgeID = GetMeshDS()->ShapeToIndex( E );
+ TID2ProjectorOnCurve& i2proj = const_cast< TID2ProjectorOnCurve&>( myEdge2Projector );
+ TID2ProjectorOnCurve::iterator i_proj = i2proj.insert( make_pair( edgeID, nullptr )).first;
+ if ( !i_proj->second )
+ {
+ double f,l;
+ Handle(Geom_Curve) curve = BRep_Tool::Curve( E,f,l );
+ i_proj->second = new GeomAPI_ProjectPointOnCurve();
+ i_proj->second->Init( curve, f, l );
+ }
+ GeomAPI_ProjectPointOnCurve* projector = i_proj->second;
+ return *projector;
+}
+
//=======================================================================
//function : GetSurface
//purpose : Return a cached ShapeAnalysis_Surface of a FACE
{
setPosOnShapeValidity( shapeID, false );
// u incorrect, project the node to the curve
- int edgeID = GetMeshDS()->ShapeToIndex( E );
- TID2ProjectorOnCurve& i2proj = const_cast< TID2ProjectorOnCurve&>( myEdge2Projector );
- TID2ProjectorOnCurve::iterator i_proj =
- i2proj.insert( make_pair( edgeID, (GeomAPI_ProjectPointOnCurve*) 0 )).first;
- if ( !i_proj->second )
- {
- i_proj->second = new GeomAPI_ProjectPointOnCurve();
- i_proj->second->Init( curve, f, l );
- }
- GeomAPI_ProjectPointOnCurve* projector = i_proj->second;
- projector->Perform( nodePnt );
- if ( projector->NbPoints() < 1 )
- {
- MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" );
- return false;
- }
- Standard_Real U = projector->LowerDistanceParameter();
- u = double( U );
- curvPnt = curve->Value( u );
- dist = nodePnt.Distance( curvPnt );
+ //GeomAPI_ProjectPointOnCurve& projector = GetPCProjector( E ); -- bug in OCCT-7.5.3p1
+ GeomAdaptor_Curve curveAd( curve, f, l );
+ ShapeAnalysis_Curve projector;
+ dist = projector.Project( curveAd, nodePnt, tol, curvPnt, u, false );
+ // if ( projector.NbPoints() < 1 )
+ // {
+ // MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" );
+ // return false;
+ // }
if ( distXYZ ) {
+ curvPnt = curve->Value( u );
curvPnt.Transform( loc );
distXYZ[0] = dist;
distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z();
// store the fixed U on the edge
if ( myShape.IsSame(E) && shapeID == myShapeID && myFixNodeParameters )
const_cast<SMDS_MeshNode*>(n)->SetPosition
- ( SMDS_PositionPtr( new SMDS_EdgePosition( U )));
+ ( SMDS_PositionPtr( new SMDS_EdgePosition( u )));
}
else if ( fabs( u ) > numeric_limits<double>::min() )
{
//purpose : Creates a node
//=======================================================================
-SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, int ID,
+SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, smIdType ID,
double u, double v)
{
SMESHDS_Mesh * meshDS = GetMeshDS();
SMDS_MeshEdge* SMESH_MesherHelper::AddEdge(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
- const int id,
+ const smIdType id,
const bool force3d)
{
SMESHDS_Mesh * meshDS = GetMeshDS();
SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
const SMDS_MeshNode* n3,
- const int id,
+ const smIdType id,
const bool force3d)
{
SMESHDS_Mesh * meshDS = GetMeshDS();
const SMDS_MeshNode* n2,
const SMDS_MeshNode* n3,
const SMDS_MeshNode* n4,
- const int id,
+ const smIdType id,
const bool force3d)
{
SMESHDS_Mesh * meshDS = GetMeshDS();
//=======================================================================
SMDS_MeshFace* SMESH_MesherHelper::AddPolygonalFace (const vector<const SMDS_MeshNode*>& nodes,
- const int id,
+ const smIdType id,
const bool force3d)
{
SMESHDS_Mesh * meshDS = GetMeshDS();
const SMDS_MeshNode* n4,
const SMDS_MeshNode* n5,
const SMDS_MeshNode* n6,
- const int id,
+ const smIdType id,
const bool force3d)
{
SMESHDS_Mesh * meshDS = GetMeshDS();
const SMDS_MeshNode* n2,
const SMDS_MeshNode* n3,
const SMDS_MeshNode* n4,
- const int id,
+ const smIdType id,
const bool force3d)
{
SMESHDS_Mesh * meshDS = GetMeshDS();
const SMDS_MeshNode* n3,
const SMDS_MeshNode* n4,
const SMDS_MeshNode* n5,
- const int id,
+ const smIdType id,
const bool force3d)
{
SMDS_MeshVolume* elem = 0;
const SMDS_MeshNode* n6,
const SMDS_MeshNode* n7,
const SMDS_MeshNode* n8,
- const int id,
+ const smIdType id,
const bool force3d)
{
SMESHDS_Mesh * meshDS = GetMeshDS();
const SMDS_MeshNode* n10,
const SMDS_MeshNode* n11,
const SMDS_MeshNode* n12,
- const int id,
+ const smIdType id,
bool /*force3d*/)
{
SMESHDS_Mesh * meshDS = GetMeshDS();
SMDS_MeshVolume*
SMESH_MesherHelper::AddPolyhedralVolume (const std::vector<const SMDS_MeshNode*>& nodes,
const std::vector<int>& quantities,
- const int id,
+ const smIdType id,
const bool force3d)
{
SMESHDS_Mesh * meshDS = GetMeshDS();
theParam2ColumnMap.begin()->second.size() == prevNbRows + expectNbRows );
}
-namespace
+//================================================================================
+/*!
+ * \brief Return true if a node is at a corner of a 2D structured mesh of FACE
+ */
+//================================================================================
+
+bool SMESH_MesherHelper::IsCornerOfStructure( const SMDS_MeshNode* n,
+ const SMESHDS_SubMesh* faceSM,
+ SMESH_MesherHelper& faceAnalyser )
{
- //================================================================================
- /*!
- * \brief Return true if a node is at a corner of a 2D structured mesh of FACE
- */
- //================================================================================
+ int nbFacesInSM = 0;
+ if ( n ) {
+ SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator( SMDSAbs_Face );
+ while ( fIt->more() )
+ nbFacesInSM += faceSM->Contains( fIt->next() );
+ }
+ if ( nbFacesInSM == 1 )
+ return true;
- bool isCornerOfStructure( const SMDS_MeshNode* n,
- const SMESHDS_SubMesh* faceSM,
- SMESH_MesherHelper& faceAnalyser )
+ if ( nbFacesInSM == 2 && n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
{
- int nbFacesInSM = 0;
- if ( n ) {
- SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator( SMDSAbs_Face );
- while ( fIt->more() )
- nbFacesInSM += faceSM->Contains( fIt->next() );
- }
- if ( nbFacesInSM == 1 )
- return true;
-
- if ( nbFacesInSM == 2 && n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
- {
- return faceAnalyser.IsRealSeam( n->getshapeId() );
- }
- return false;
+ return faceAnalyser.IsRealSeam( n->getshapeId() );
}
+ return false;
}
//=======================================================================
int nbRemainEdges = nbEdgesInWires.front();
do {
TopoDS_Vertex V = IthVertex( 0, edges.front() );
- isCorner = isCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ),
+ isCorner = IsCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ),
fSM, faceAnalyser);
if ( !isCorner ) {
edges.splice( edges.end(), edges, edges.begin() );
for ( ; n != nodes.end(); ++n )
{
++nbEdges;
- if ( isCornerOfStructure( *n, fSM, faceAnalyser )) {
+ if ( IsCornerOfStructure( *n, fSM, faceAnalyser )) {
nbEdgesInSide.push_back( nbEdges );
nbEdges = 0;
}
if ( !aSubMeshDSFace )
return isReversed;
- // find an element on a bounday of theFace
+ // find an element on a boundary of theFace
SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements();
const SMDS_MeshNode* nn[2];
while ( iteratorElem->more() ) // loop on elements on theFace
SMESH_MesherHelper:: MType SMESH_MesherHelper::IsQuadraticMesh()
{
- int NbAllEdgsAndFaces=0;
- int NbQuadFacesAndEdgs=0;
- int NbFacesAndEdges=0;
+ smIdType NbAllEdgsAndFaces=0;
+ smIdType NbQuadFacesAndEdgs=0;
+ smIdType NbFacesAndEdges=0;
//All faces and edges
NbAllEdgsAndFaces = myMesh->NbEdges() + myMesh->NbFaces();
if ( NbAllEdgsAndFaces == 0 )
*/
//================================================================================
- bool QFace::IsSpoiled(const QLink* bentLink ) const // todo: unused
- {
- // code is valid for convex faces only
- gp_XYZ gc(0,0,0);
- for ( TIDSortedNodeSet::const_iterator n = begin(); n != end(); ++n )
- gc += XYZ( *n ) / double( size() );
- for ( size_t i = 0; i < _sides.size(); ++i )
- {
- if ( _sides[i] == bentLink ) continue;
- gp_Vec linkNorm = _normal ^ gp_Vec( XYZ(_sides[i]->node1()), XYZ(_sides[i]->node2()));
- gp_Vec vecOut( gc, _sides[i]->MiddlePnt() );
- if ( linkNorm * vecOut < 0 )
- linkNorm.Reverse();
- double mag2 = linkNorm.SquareMagnitude();
- if ( mag2 > numeric_limits<double>::min() )
- linkNorm /= sqrt( mag2 );
- gp_Vec vecBent ( _sides[i]->MiddlePnt(), bentLink->MediumPnt());
- gp_Vec vecStraight( _sides[i]->MiddlePnt(), bentLink->MiddlePnt());
- if ( vecBent * linkNorm > -0.1*vecStraight.Magnitude() )
- return true;
- }
- return false;
+ // bool QFace::IsSpoiled(const QLink* bentLink ) const
+ // {
+ // // code is valid for convex faces only
+ // gp_XYZ gc(0,0,0);
+ // for ( TIDSortedNodeSet::const_iterator n = begin(); n != end(); ++n )
+ // gc += XYZ( *n ) / double( size() );
+ // for ( size_t i = 0; i < _sides.size(); ++i )
+ // {
+ // if ( _sides[i] == bentLink ) continue;
+ // gp_Vec linkNorm = _normal ^ gp_Vec( XYZ(_sides[i]->node1()), XYZ(_sides[i]->node2()));
+ // gp_Vec vecOut( gc, _sides[i]->MiddlePnt() );
+ // if ( linkNorm * vecOut < 0 )
+ // linkNorm.Reverse();
+ // double mag2 = linkNorm.SquareMagnitude();
+ // if ( mag2 > numeric_limits<double>::min() )
+ // linkNorm /= sqrt( mag2 );
+ // gp_Vec vecBent ( _sides[i]->MiddlePnt(), bentLink->MediumPnt());
+ // gp_Vec vecStraight( _sides[i]->MiddlePnt(), bentLink->MiddlePnt());
+ // if ( vecBent * linkNorm > -0.1*vecStraight.Magnitude() )
+ // return true;
+ // }
+ // return false;
- }
+ // }
//================================================================================
/*!
SMESH_MesherHelper h(*myMesh);
h.SetSubShape( s.Current() );
h.ToFixNodeParameters(true);
- h.FixQuadraticElements( compError, false );
+ try {
+ OCC_CATCH_SIGNALS;
+ h.FixQuadraticElements( compError, false );
+ }
+ catch(...) {
+ if ( compError && compError->myComment.empty() )
+ compError->myComment = "SMESH_MesherHelper::FixQuadraticElements() failed";
+ }
}
}
// fix nodes on geom faces
#ifdef _DEBUG_
int nbfaces = nbSolids;
- nbfaces = faces.Extent(); /*avoid "unused varianbles": */ nbfaces++, nbfaces--;
+ nbfaces = faces.Extent(); /*avoid "unused varianbles": */ nbfaces++, nbfaces--;
#endif
for ( TopTools_MapIteratorOfMapOfShape fIt( faces ); fIt.More(); fIt.Next() ) {
MESSAGE("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key()));
SMESH_MesherHelper h(*myMesh);
h.SetSubShape( fIt.Key() );
h.ToFixNodeParameters(true);
- h.FixQuadraticElements( compError, true);
+ try {
+ OCC_CATCH_SIGNALS;
+ h.FixQuadraticElements( compError, true);
+ }
+ catch(...) {
+ if ( compError && compError->myComment.empty() )
+ compError->myComment = "SMESH_MesherHelper::FixQuadraticElements() failed";
+ }
}
//perf_print_all_meters(1);
if ( compError && compError->myName == EDITERR_NO_MEDIUM_ON_GEOM )
while ( len < numeric_limits<double>::min() ) { // remove degenerated link
if ( savedChain.empty() ) savedChain = chain;
link1 = chain.erase( link1 );
- if ( link1 == chain.end() )
+ if ( link1 == chain.end() ) {
+ link1 = --chain.end();
break;
+ }
len = ((*link0)->MiddlePnt() - (*link1)->MiddlePnt()).Modulus();
}
chainLen += len;
linkPos.push_back( chainLen );
}
}
+ if ( chain.begin() == --chain.end() ) // chain.size() == 1
+ continue;
+
gp_Vec move0 = chain.front()->_nodeMove;
gp_Vec move1 = chain.back ()->_nodeMove;