#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>
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() )
{
gp_Pnt p; gp_Vec du, dv;
// BRepClass_FaceClassifier is most time consuming, so minimize its usage
- const double clsfTol = 10 * BRep_Tool::Tolerance( geomFace );
+ const double clsfTol = 1e2 * BRep_Tool::MaxTolerance( geomFace, TopAbs_VERTEX );
BRepTopAdaptor_FClass2d classifier( geomFace, clsfTol ); //Brimless_FaceClassifier classifier;
Bnd_B2d bndBox2d;
Bnd_Box bndBox3d;
double minGroupTol = Precision::Infinite();
SMESH::Controls::ElementsOnShape onEdgeClassifier;
- if ( helper.HasSeam() )
{
TopoDS_Compound edgesCompound;
BRep_Builder builder;
// another idea: try to use max tol of all edges
//const double clsfTol = 10 * BRep_Tool::Tolerance( geomFace ); // 0.1 * groupTol;
- if ( helper.HasSeam() )
- onEdgeClassifier.SetMesh( srcMesh->GetMeshDS() );
+ onEdgeClassifier.SetMesh( srcMesh->GetMeshDS() );
+ onEdgeClassifier.SetTolerance( groupTol / 10 );
+
SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
while ( srcElems->more() ) // loop on group contents
{
// find out if node lies on the surface of theShape
gp_XY uv( Precision::Infinite(), 0 );
- isOut = ( !helper.CheckNodeUV( geomFace, node, uv, groupTol, /*force=*/true ) ||
- bndBox2d.IsOut( uv ));
+ bool isOutBox = true;
+ isOut = (! helper.CheckNodeUV( geomFace, node, uv, groupTol, /*force=*/true ) ||
+ ( isOutBox = bndBox2d.IsOut( uv )));
//int iCoo;
if ( !isOut && !isIn ) // classify
{
nodeState[i] = classifier.Perform( uv ); //classifier.Perform( geomFace, uv, clsfTol );
//nodeState[i] = classifier.State();
isOut = ( nodeState[i] == TopAbs_OUT );
- if ( isOut && helper.IsOnSeam( uv ) && onEdgeClassifier.IsSatisfy( node->GetID() ))
+ if (( isOut ) &&
+ ( !isOutBox || helper.IsOnSeam( uv )) &&
+ onEdgeClassifier.IsSatisfy( node->GetID() ))
{
// uv.SetCoord( iCoo, helper.GetOtherParam( uv.Coord( iCoo )));
// classifier.Perform( geomFace, uv, clsfTol );
newNode = tgtMesh->AddNode( nXYZ.X(), nXYZ.Y(), nXYZ.Z());
tgtMesh->SetNodeOnFace( newNode, shapeID, uv.X(), uv.Y() );
nbCreatedNodes++;
- if ( newNode->GetID() >= (int) isNodeIn.size() )
+ if ( newNode->GetID() >= (smIdType) isNodeIn.size() )
{
isNodeIn.push_back( false ); // allow allocate more than newNode->GetID()
isNodeIn.resize( newNode->GetID() + 1, false );
// the imported mesh is valid if all external links (encountered once)
// lie on geom edges
subShapeIDs.erase( shapeID ); // to contain edges and vertices only
- double u, f, l;
for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); ++link2Nb)
{
const TLink& link = (*link2Nb).first;
const SMDS_MeshNode* n = is1stN ? link.node1() : link.node2();
if ( !subShapeIDs.count( n->getshapeId() )) // n is assigned to FACE
{
- for ( size_t iE = 0; iE < edges.size(); ++iE )
- if ( helper.CheckNodeU( edges[iE], n, u=0, projTol, /*force=*/true ))
- {
- BRep_Tool::Range(edges[iE],f,l);
- if ( Abs(u-f) < 2 * faceTol || Abs(u-l) < 2 * faceTol )
- // duplicated node on vertex
- return error("Source elements overlap one another");
- tgtFaceSM->RemoveNode( n );
- tgtMesh->SetNodeOnEdge( n, edges[iE], u );
- break;
- }
+ TopoDS_Shape edge;
+ if ( onEdgeClassifier.IsSatisfy( n, &edge ))
+ {
+ tgtFaceSM->RemoveNode( n );
+ tgtMesh->SetNodeOnEdge( n, TopoDS::Edge(edge), /*u=*/0 );
+ }
nodesOnBoundary = subShapeIDs.count( n->getshapeId());
}
if ( nodesOnBoundary )
{
edge = tgtMesh->AddEdge( newNodes[0], newNodes[1], link._medium );
+ double u;
TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back());
helper.CheckNodeU( geomEdge, link._medium, u, projTol, /*force=*/true );
tgtFaceSM->RemoveNode( link._medium );
TUNodeList nodesOnSeam;
double u = helper.GetNodeU( seamEdge, vertNode );
nodesOnSeam.push_back( make_pair( u, vertNode ));
+ size_t nbNodesOnSeam = 1;
TUNodeList::iterator u2nIt = nodesOnSeam.begin();
for ( ; u2nIt != nodesOnSeam.end(); ++u2nIt )
{
{
const SMDS_MeshNode* n = face->GetNode( i );
if ( n == startNode || !checkedNodes.insert( n ).second ) continue;
- if ( helper.CheckNodeU( seamEdge, n, u=0, projTol, /*force=*/true ))
- nodesOnSeam.push_back( make_pair( u, n ));
+ helper.CheckNodeU( seamEdge, n, u=0, projTol, /*force=*/true );
+ nodesOnSeam.push_back( make_pair( u, n ));
+ ++nbNodesOnSeam;
}
}
}
map< double, const SMDS_MeshNode* > u2nodeMap;
for ( u2nIt = nodesOnSeam.begin(); u2nIt != nodesOnSeam.end(); ++u2nIt )
u2nodeMap.insert( u2nodeMap.end(), *u2nIt );
+ if ( u2nodeMap.size() != nbNodesOnSeam ) // problem with parameters on EDGE
+ {
+ // sort nodes by distance from seamVertex
+ gp_Pnt vertPnt = SMESH_NodeXYZ( vertNode );
+ u2nodeMap.clear();
+ for ( u2nIt = nodesOnSeam.begin(); u2nIt != nodesOnSeam.end(); ++u2nIt )
+ u2nodeMap.insert
+ ({ vertPnt.SquareDistance( SMESH_NodeXYZ( u2nIt->second )), u2nIt->second });
+ }
// create edges
{