-// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2019 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 "SMESH_HypoFilter.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_MeshAlgos.hxx"
+#include "SMESH_MeshEditor.hxx"
#include "SMESH_ProxyMesh.hxx"
#include "SMESH_subMesh.hxx"
namespace {
- inline SMESH_TNodeXYZ XYZ(const SMDS_MeshNode* n) { return SMESH_TNodeXYZ(n); }
+ inline SMESH_NodeXYZ XYZ(const SMDS_MeshNode* n) { return SMESH_NodeXYZ(n); }
enum { U_periodic = 1, V_periodic = 2 };
}
// we can create quadratic elements only if all elements
// created on sub-shapes of given shape are quadratic
myCreateQuadratic = true;
- mySeamShapeIds.clear();
- myDegenShapeIds.clear();
TopAbs_ShapeEnum subType( aSh.ShapeType()==TopAbs_FACE ? TopAbs_EDGE : TopAbs_FACE );
if ( aSh.ShapeType()==TopAbs_COMPOUND )
{
if ( !C2d.IsNull() ) {
double u = ( V == IthVertex( 0, edge )) ? f : l;
uv = C2d->Value( u );
- uvOK = true;
+ gp_Pnt p = GetSurface( F )->Value( uv );
+ uvOK = ( p.Distance( BRep_Tool::Pnt( V )) < getFaceMaxTol( F ));
break;
}
}
// check that uv is correct
TopLoc_Location loc;
Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc );
- gp_Pnt nodePnt = XYZ( n ), surfPnt(0,0,0);
+ SMESH_NodeXYZ nXYZ( n );
+ gp_Pnt nodePnt = nXYZ, surfPnt(0,0,0);
double dist = 0;
if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
if ( infinit ||
(dist = nodePnt.Distance( surfPnt = surface->Value( uv.X(), uv.Y() ))) > tol )
{
setPosOnShapeValidity( shapeID, false );
- if ( !infinit && distXYZ ) {
- surfPnt.Transform( loc );
- distXYZ[0] = dist;
- distXYZ[1] = surfPnt.X(); distXYZ[2] = surfPnt.Y(); distXYZ[3]=surfPnt.Z();
- }
// uv incorrect, project the node to surface
- GeomAPI_ProjectPointOnSurf& projector = GetProjector( F, loc, tol );
- projector.Perform( nodePnt );
- if ( !projector.IsDone() || projector.NbPoints() < 1 )
- {
- MESSAGE( "SMESH_MesherHelper::CheckNodeUV() failed to project" );
- return false;
- }
- Standard_Real U,V;
- projector.LowerDistanceParameters(U,V);
- uv.SetCoord( U,V );
- surfPnt = surface->Value( U, V );
- dist = nodePnt.Distance( surfPnt );
+ Handle(ShapeAnalysis_Surface) sprojector = GetSurface( F );
+ uv = sprojector->ValueOfUV( nXYZ, tol ).XY();
+ surfPnt = sprojector->Value( uv );
+ dist = surfPnt.Distance( nXYZ );
if ( distXYZ ) {
- surfPnt.Transform( loc );
distXYZ[0] = dist;
distXYZ[1] = surfPnt.X(); distXYZ[2] = surfPnt.Y(); distXYZ[3]=surfPnt.Z();
}
// store the fixed UV on the face
if ( myShape.IsSame(F) && shapeID == myShapeID && myFixNodeParameters )
const_cast<SMDS_MeshNode*>(n)->SetPosition
- ( SMDS_PositionPtr( new SMDS_FacePosition( U, V )));
+ ( SMDS_PositionPtr( new SMDS_FacePosition( uv.X(), uv.Y() )));
}
else if ( myShape.IsSame(F) && uv.Modulus() > numeric_limits<double>::min() )
{
int vertexID = n->getshapeId();
const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID));
param = BRep_Tool::Parameter( V, E );
+
+ if ( inEdgeNode )
+ {
+ BRepAdaptor_Curve curve( E );
+ if ( curve.IsPeriodic() )
+ {
+ double uInEdge = GetNodeU( E, inEdgeNode );
+ param += ShapeAnalysis::AdjustByPeriod( param, uInEdge, curve.Period() );
+ }
+ }
}
}
if ( check )
// get positions of the given nodes on shapes
if ( pos.second == TopAbs_FACE )
{
- F = TopoDS::Face(meshDS->IndexToShape( faceID = pos.first ));
+ F = TopoDS::Face( meshDS->IndexToShape( faceID = pos.first ));
uv[0] = GetNodeUV(F,n1,n2, force3d ? 0 : &uvOK[0]);
- if (( !force3d ) &&
- ( HasDegeneratedEdges() || GetSurface( F )->HasSingularities( 1e-7 )))
- {
- // IPAL52850 (degen VERTEX not at singularity)
- // project middle point to a surface
- SMESH_TNodeXYZ p1( n1 ), p2( n2 );
- gp_Pnt pMid = 0.5 * ( p1 + p2 );
- Handle(ShapeAnalysis_Surface) projector = GetSurface( F );
- gp_Pnt2d uvMid;
- if ( uvOK[0] )
- uvMid = projector->NextValueOfUV( uv[0], pMid, BRep_Tool::Tolerance( F ));
- else
- uvMid = projector->ValueOfUV( pMid, getFaceMaxTol( F ));
- if ( projector->Gap() * projector->Gap() < ( p1 - p2 ).SquareModulus() / 4 )
- {
- gp_Pnt pProj = projector->Value( uvMid );
- n12 = meshDS->AddNode( pProj.X(), pProj.Y(), pProj.Z() );
- meshDS->SetNodeOnFace( n12, faceID, uvMid.X(), uvMid.Y() );
- myTLinkNodeMap.insert( make_pair ( link, n12 ));
- return n12;
- }
- }
uv[1] = GetNodeUV(F,n2,n1, force3d ? 0 : &uvOK[1]);
}
else if ( pos.second == TopAbs_EDGE )
// nodes, else - medium between corresponding 3d points
if( ! F.IsNull() )
{
- //if ( uvOK[0] && uvOK[1] )
+ if ( IsDegenShape( n1->getshapeId() )) {
+ if ( myParIndex & U_periodic ) uv[0].SetCoord( 1, uv[1].Coord( 1 ));
+ else uv[0].SetCoord( 2, uv[1].Coord( 2 ));
+ }
+ else if ( IsDegenShape( n2->getshapeId() )) {
+ if ( myParIndex & U_periodic ) uv[1].SetCoord( 1, uv[0].Coord( 1 ));
+ else uv[1].SetCoord( 2, uv[0].Coord( 2 ));
+ }
+ TopLoc_Location loc;
+ Handle(Geom_Surface) S = BRep_Tool::Surface(F,loc);
+ gp_XY UV = GetMiddleUV( S, uv[0], uv[1] );
+ gp_Pnt P = S->Value( UV.X(), UV.Y() ).Transformed(loc);
+
+ SMESH_TNodeXYZ p1( n1 ), p2( n2 );
+ gp_Pnt pMid = 0.5 * ( p1 + p2 );
+ double distMid = pMid.SquareDistance( P );
+ double dist12 = ( p1 - p2 ).SquareModulus();
+ Handle(ShapeAnalysis_Surface) surfInfo = GetSurface( F );
+ if ( distMid > dist12 ||
+ HasDegeneratedEdges() ||
+ surfInfo->HasSingularities( 1e-7 ) )
{
- if ( IsDegenShape( n1->getshapeId() )) {
- if ( myParIndex & U_periodic ) uv[0].SetCoord( 1, uv[1].Coord( 1 ));
- else uv[0].SetCoord( 2, uv[1].Coord( 2 ));
- }
- else if ( IsDegenShape( n2->getshapeId() )) {
- if ( myParIndex & U_periodic ) uv[1].SetCoord( 1, uv[0].Coord( 1 ));
- else uv[1].SetCoord( 2, uv[0].Coord( 2 ));
- }
- TopLoc_Location loc;
- Handle(Geom_Surface) S = BRep_Tool::Surface(F,loc);
- gp_XY UV = GetMiddleUV( S, uv[0], uv[1] );
- gp_Pnt P = S->Value( UV.X(), UV.Y() ).Transformed(loc);
- n12 = meshDS->AddNode(P.X(), P.Y(), P.Z());
- // if ( mySetElemOnShape ) node is not elem!
- meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y());
- myTLinkNodeMap.insert(make_pair(link,n12));
- return n12;
+ // IPAL52850 (degen VERTEX not at singularity)
+ // project middle point to a surface
+ gp_Pnt2d uvMid;
+ if ( uvOK[0] )
+ uvMid = surfInfo->NextValueOfUV( uv[0], pMid, BRep_Tool::Tolerance( F ));
+ else
+ uvMid = surfInfo->ValueOfUV( pMid, getFaceMaxTol( F ));
+ if ( surfInfo->Gap() * surfInfo->Gap() < distMid )
+ P = surfInfo->Value( uvMid );
}
+ n12 = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ // if ( mySetElemOnShape ) node is not elem!
+ meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y());
+ myTLinkNodeMap.insert(make_pair(link,n12));
+ return n12;
}
else if ( !E.IsNull() )
{
const SMDS_MeshElement* f = faceIt->next();
if ( !faceSM->Contains( f ) ||
f->NbNodes() < 6 || // check quadratic triangles only
+ f->NbNodes() > 7 ||
!checkedFaces.insert( f ).second )
continue;
gp_Pnt pMedium = SMESH_TNodeXYZ( linkIt->second );
double hMedium = faceNorm * gp_Vec( pOnFace0, pMedium ).XYZ();
double hVol = faceNorm * gp_Vec( pOnFace0, pInSolid ).XYZ();
- isDistorted = ( Abs( hMedium ) > Abs( hVol * 0.75 ));
+ if ( Abs( hMedium ) > Abs( hVol * 0.75 ))
+ {
+ SMESH_TNodeXYZ pI( nOnFace[i]), pJ( nOnFace[j]);
+ double angle = gp_Vec( pI, pMedium ).Angle( gp_Vec( pI, pJ ));
+ isDistorted = ( angle > M_PI / 20 );
+ }
}
}
}