for ( TopExp_Explorer eF( aSh, TopAbs_FACE ); eF.More(); eF.Next() )
{
const TopoDS_Face& face = TopoDS::Face( eF.Current() );
- TopLoc_Location loc;
- Handle(Geom_Surface) surface = BRep_Tool::Surface( face, loc );
+ // TopLoc_Location loc;
+ // Handle(Geom_Surface) surface = BRep_Tool::Surface( face, loc );
// if ( surface->IsUPeriodic() || surface->IsVPeriodic() ||
// surface->IsUClosed() || surface->IsVClosed() )
{
//while ( surface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface )))
//surface = Handle(Geom_RectangularTrimmedSurface)::DownCast( surface )->BasisSurface();
- GeomAdaptor_Surface surf( surface );
for (TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next())
{
// look for a seam edge
- const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
+ TopoDS_Edge edge = TopoDS::Edge( exp.Current() );
if ( BRep_Tool::IsClosed( edge, face )) {
// initialize myPar1, myPar2 and myParIndex
gp_Pnt2d uv1, uv2;
BRep_Tool::UVPoints( edge, face, uv1, uv2 );
if ( Abs( uv1.Coord(1) - uv2.Coord(1) ) < Abs( uv1.Coord(2) - uv2.Coord(2) ))
{
+ double u1 = uv1.Coord(1);
+ edge.Reverse();
+ BRep_Tool::UVPoints( edge, face, uv1, uv2 );
+ double u2 = uv1.Coord(1);
myParIndex |= U_periodic;
- myPar1[0] = surf.FirstUParameter();
- myPar2[0] = surf.LastUParameter();
+ myPar1[0] = Min( u1, u2 );
+ myPar2[0] = Max( u1, u2 );
}
else {
+ double v1 = uv1.Coord(2);
+ edge.Reverse();
+ BRep_Tool::UVPoints( edge, face, uv1, uv2 );
+ double v2 = uv1.Coord(2);
myParIndex |= V_periodic;
- myPar1[1] = surf.FirstVParameter();
- myPar2[1] = surf.LastVParameter();
+ myPar1[1] = Min( v1, v2 );
+ myPar2[1] = Max( v1, v2 );
}
// store seam shape indices, negative if shape encounters twice
int edgeID = meshDS->ShapeToIndex( edge );
myDegenShapeIds.insert( meshDS->ShapeToIndex( v.Current() ));
}
}
- if ( !myDegenShapeIds.empty() && !myParIndex ) {
- if ( surface->IsUPeriodic() || surface->IsUClosed() ) {
+ if ( !myDegenShapeIds.empty() && !myParIndex )
+ {
+ BRepAdaptor_Surface surf( face, false );
+ if ( surf.IsUPeriodic() || surf.IsUClosed() ) {
myParIndex |= U_periodic;
myPar1[0] = surf.FirstUParameter();
myPar2[0] = surf.LastUParameter();
}
- else if ( surface->IsVPeriodic() || surface->IsVClosed() ) {
+ else if ( surf.IsVPeriodic() || surf.IsVClosed() ) {
myParIndex |= V_periodic;
myPar1[1] = surf.FirstVParameter();
myPar2[1] = surf.LastVParameter();
double p1 = uv1.Coord( i );
double dp1 = Abs( p1-myPar1[i-1]), dp2 = Abs( p1-myPar2[i-1]);
if ( myParIndex == i ||
- dp1 < ( myPar2[i-1] - myPar2[i-1] ) / 100. ||
- dp2 < ( myPar2[i-1] - myPar2[i-1] ) / 100. )
+ dp1 < ( myPar2[i-1] - myPar1[i-1] ) / 100. ||
+ dp2 < ( myPar2[i-1] - myPar1[i-1] ) / 100. )
{
double p2 = uv2.Coord( i );
double p1Alt = ( dp1 < dp2 ) ? myPar2[i-1] : myPar1[i-1];
{
// node has position on face
const SMDS_FacePosition* fpos =
- static_cast<const SMDS_FacePosition*>(n->GetPosition());
+ static_cast<const SMDS_FacePosition*>( Pos );
uv.SetCoord(fpos->GetUParameter(),fpos->GetVParameter());
if ( check )
uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ));
// corresponding edge from face, get pcurve for this
// edge and retrieve value from this pcurve
const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(n->GetPosition());
+ static_cast<const SMDS_EdgePosition*>( Pos );
int edgeID = n->getshapeId();
TopoDS_Edge E = TopoDS::Edge(GetMeshDS()->IndexToShape(edgeID));
double f, l, u = epos->GetUParameter();
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] );
double SMESH_MesherHelper::GetAngle( const TopoDS_Edge & theE1,
const TopoDS_Edge & theE2,
- const TopoDS_Face & theFace)
+ const TopoDS_Face & theFace,
+ gp_Vec* theFaceNormal)
{
double angle = 1e100;
try
}
if ( theFace.Orientation() == TopAbs_REVERSED )
vecRef.Reverse();
+ if ( theFaceNormal ) *theFaceNormal = vecRef;
+
c1->D1( p1, p, vec1 );
c2->D1( p2, p, vec2 );
- TopoDS_Face F = theFace;
- if ( F.Orientation() == TopAbs_INTERNAL )
- F.Orientation( TopAbs_FORWARD );
+ // TopoDS_Face F = theFace;
+ // if ( F.Orientation() == TopAbs_INTERNAL )
+ // F.Orientation( TopAbs_FORWARD );
if ( theE1.Orientation() /*GetSubShapeOri( F, theE1 )*/ == TopAbs_REVERSED )
vec1.Reverse();
if ( theE2.Orientation() /*GetSubShapeOri( F, theE2 )*/ == TopAbs_REVERSED )
vec2.Reverse();
angle = vec1.AngleWithRef( vec2, vecRef );
+
+ if ( Abs ( angle ) >= 0.99 * M_PI )
+ {
+ BRep_Tool::Range( theE1, f, l );
+ p1 += 1e-7 * ( p1-f < l-p1 ? +1. : -1. );
+ c1->D1( p1, p, vec1 );
+ if ( theE1.Orientation() == TopAbs_REVERSED )
+ vec1.Reverse();
+ BRep_Tool::Range( theE2, f, l );
+ p2 += 1e-7 * ( p2-f < l-p2 ? +1. : -1. );
+ c2->D1( p2, p, vec2 );
+ if ( theE2.Orientation() == TopAbs_REVERSED )
+ vec2.Reverse();
+ angle = vec1.AngleWithRef( vec2, vecRef );
+ }
}
catch (...)
{
//BRepClass3d_SolidClassifier solidClassifier( shape );
TIDSortedElemSet checkedVols, movedNodes;
- for ( faceIt.ReInit(); faceIt.More(); faceIt.Next() ) // loop on FACEs of a SOLID
+ //for ( faceIt.ReInit(); faceIt.More(); faceIt.Next() ) // loop on FACEs of a SOLID
+ for ( size_t iF = 0; iF < concaveFaces.size(); ++iF ) // loop on concave FACEs
{
- const TopoDS_Shape& face = faceIt.Current();
+ //const TopoDS_Shape& face = faceIt.Current();
+ const TopoDS_Shape& face = concaveFaces[ iF ];
SMESHDS_SubMesh* faceSM = meshDS->MeshElements( face );
if ( !faceSM ) continue;
if ( !vertexSM ) continue;
nodeIt = vertexSM->GetNodes();
}
+ // get ids of sub-shapes of the FACE
+ set< int > subIDs;
+ SMESH_subMeshIteratorPtr smIt =
+ theHelper.GetMesh()->GetSubMesh( face )->getDependsOnIterator(/*includeSelf=*/true);
+ while ( smIt->more() )
+ subIDs.insert( smIt->next()->GetId() );
// find suspicious volumes adjacent to the FACE
vector< const SMDS_MeshNode* > nOnFace( 4 );
const SMDS_MeshNode* nInSolid;
- //vector< const SMDS_MeshElement* > intersectedFaces;
while ( nodeIt->more() )
{
const SMDS_MeshNode* n = nodeIt->next();
n = *volNode;
if ( n->GetPosition()->GetDim() == 3 )
nInSolid = n;
- else
+ else if ( subIDs.count( n->getshapeId() ))
nOnFace.push_back( n );
}
if ( !nInSolid || nOnFace.size() != nbN - 1 )
#include <cmath>
#include <limits>
-//#define __myDEBUG
+#define __myDEBUG
using namespace std;
bool makeLayer(_SolidData& data);
bool setEdgeData(_LayerEdge& edge, const set<TGeomID>& subIds,
SMESH_MesherHelper& helper, _SolidData& data);
+ gp_XYZ getFaceNormal(const SMDS_MeshNode* n,
+ const TopoDS_Face& face,
+ SMESH_MesherHelper& helper,
+ bool& isOK,
+ bool shiftInside=false);
gp_XYZ getWeigthedNormal( const SMDS_MeshNode* n,
std::pair< TGeomID, gp_XYZ > fId2Normal[],
const int nbFaces );
vector< vector<_LayerEdge*> >& edgesByGeom);
bool sortEdges( _SolidData& data,
vector< vector<_LayerEdge*> >& edgesByGeom);
+ void limitStepSizeByCurvature( _SolidData& data,
+ vector< vector<_LayerEdge*> >& edgesByGeom);
void limitStepSize( _SolidData& data,
const SMDS_MeshElement* face,
const double cosin);
if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX &&
helper.IsClosedEdge( fromE ))
{
- if ( fabs(u-f) < fabs(u-l )) c->D1( l, p, dv );
- else c->D1( f, p, dv );
+ if ( fabs(u-f) < fabs(u-l)) c->D1( l, p, dv );
+ else c->D1( f, p, dv );
if ( o == TopAbs_REVERSED )
dv.Reverse();
gp_Vec dir2 = norm ^ dv;
const SMDS_MeshNode* node, SMESH_MesherHelper& helper,
bool& ok, double* cosin=0)
{
+ TopoDS_Face faceFrw = F;
+ faceFrw.Orientation( TopAbs_FORWARD );
double f,l; TopLoc_Location loc;
- vector< TopoDS_Edge > edges; // sharing a vertex
- PShapeIteratorPtr eIt = helper.GetAncestors( fromV, *helper.GetMesh(), TopAbs_EDGE);
- while ( eIt->more())
- {
- const TopoDS_Edge* e = static_cast<const TopoDS_Edge*>( eIt->next() );
- if ( helper.IsSubShape( *e, F ) && !BRep_Tool::Curve( *e, loc,f,l).IsNull() )
- edges.push_back( *e );
- }
- gp_XYZ dir(0,0,0);
- if ( !( ok = ( edges.size() > 0 ))) return dir;
- // get average dir of edges going fromV
- gp_XYZ edgeDir;
- //if ( edges.size() > 1 )
- for ( size_t i = 0; i < edges.size(); ++i )
- {
- edgeDir = getEdgeDir( edges[i], fromV );
- double size2 = edgeDir.SquareModulus();
- if ( size2 > numeric_limits<double>::min() )
- edgeDir /= sqrt( size2 );
- else
- ok = false;
- dir += edgeDir;
- }
- gp_XYZ fromEdgeDir = getFaceDir( F, edges[0], node, helper, ok );
- try {
- if ( edges.size() == 1 )
- dir = fromEdgeDir;
- else if ( dir.SquareModulus() < 0.1 ) // ~< 20 degrees
- dir = fromEdgeDir.Normalized() + getFaceDir( F, edges[1], node, helper, ok ).Normalized();
- else if ( dir * fromEdgeDir < 0 )
- dir *= -1;
- }
- catch ( Standard_Failure )
+ TopoDS_Edge edges[2]; // sharing a vertex
+ int nbEdges = 0;
{
- ok = false;
+ TopoDS_Vertex VV[2];
+ TopExp_Explorer exp( faceFrw, TopAbs_EDGE );
+ for ( ; exp.More() && nbEdges < 2; exp.Next() )
+ {
+ const TopoDS_Edge& e = TopoDS::Edge( exp.Current() );
+ if ( SMESH_Algo::isDegenerated( e )) continue;
+ TopExp::Vertices( e, VV[0], VV[1], /*CumOri=*/true );
+ if ( VV[1].IsSame( fromV )) {
+ edges[ 0 ] = e;
+ nbEdges++;
+ }
+ else if ( VV[0].IsSame( fromV )) {
+ edges[ 1 ] = e;
+ nbEdges++;
+ }
+ }
}
- if ( ok )
+ gp_XYZ dir(0,0,0), edgeDir[2];
+ if ( nbEdges == 2 )
{
- //dir /= edges.size();
+ // get dirs of edges going fromV
+ ok = true;
+ for ( size_t i = 0; i < nbEdges && ok; ++i )
+ {
+ edgeDir[i] = getEdgeDir( edges[i], fromV );
+ double size2 = edgeDir[i].SquareModulus();
+ if (( ok = size2 > numeric_limits<double>::min() ))
+ edgeDir[i] /= sqrt( size2 );
+ }
+ if ( !ok ) return dir;
+
+ // get angle between the 2 edges
+ gp_Vec faceNormal;
+ double angle = helper.GetAngle( edges[0], edges[1], faceFrw, &faceNormal );
+ if ( Abs( angle ) < 5 * M_PI/180 )
+ {
+ dir = ( faceNormal.XYZ() ^ edgeDir[0].Reversed()) + ( faceNormal.XYZ() ^ edgeDir[1] );
+ }
+ else
+ {
+ dir = edgeDir[0] + edgeDir[1];
+ if ( angle < 0 )
+ dir.Reverse();
+ }
if ( cosin ) {
- double angle = gp_Vec( edgeDir ).Angle( dir );
- *cosin = cos( angle );
+ double angle = gp_Vec( edgeDir[0] ).Angle( dir );
+ *cosin = Cos( angle );
}
}
+ else if ( nbEdges == 1 )
+ {
+ dir = getFaceDir( faceFrw, edges[0], node, helper, ok );
+ if ( cosin ) *cosin = 1.;
+ }
+ else
+ {
+ ok = false;
+ }
+
return dir;
}
//================================================================================
// fill data._simplexTestEdges
findSimplexTestEdges( data, edgesByGeom );
+ // limit data._stepSize depending on surface curvature
+ limitStepSizeByCurvature( data, edgesByGeom );
+
// Put _LayerEdge's into the vector data._edges
if ( !sortEdges( data, edgesByGeom ))
return false;
}
}
+//================================================================================
+/*!
+ * \brief Limit data._stepSize by evaluating curvature of shapes
+ */
+//================================================================================
+
+void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data,
+ vector< vector<_LayerEdge*> >& edgesByGeom)
+{
+ const int nbTestPnt = 5;
+ const double minCurvature = 0.9 / data._hyp->GetTotalThickness();
+
+ BRepLProp_SLProps surfProp( 2, 1e-6 );
+ SMESH_MesherHelper helper( *_mesh );
+
+ TopExp_Explorer face( data._solid, TopAbs_FACE );
+ for ( ; face.More(); face.Next() )
+ {
+ const TopoDS_Face& F = TopoDS::Face( face.Current() );
+ BRepAdaptor_Surface surface( F, false );
+ surfProp.SetSurface( surface );
+
+ SMESH_subMesh * sm = _mesh->GetSubMesh( F );
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true);
+ while ( smIt->more() )
+ {
+ sm = smIt->next();
+ const vector<_LayerEdge*>& ledges = edgesByGeom[ sm->GetId() ];
+ int step = Max( 1, int( ledges.size()) / nbTestPnt );
+ for ( size_t i = 0; i < ledges.size(); i += step )
+ {
+ gp_XY uv = helper.GetNodeUV( F, ledges[i]->_nodes[0] );
+ surfProp.SetParameters( uv.X(), uv.Y() );
+ if ( !surfProp.IsCurvatureDefined() )
+ continue;
+ double surfCurvature = Max( Abs( surfProp.MaxCurvature() ),
+ Abs( surfProp.MinCurvature() ));
+ if ( surfCurvature < minCurvature )
+ continue;
+
+ gp_Dir minDir, maxDir;
+ surfProp.CurvatureDirections( maxDir, minDir );
+ if ( F.Orientation() == TopAbs_REVERSED ) {
+ maxDir.Reverse(); minDir.Reverse();
+ }
+ const gp_XYZ& inDir = ledges[i]->_normal;
+ if ( inDir * maxDir.XYZ() < 0 &&
+ inDir * minDir.XYZ() < 0 )
+ continue;
+
+ limitStepSize( data, 0.9 / surfCurvature );
+ }
+ }
+ }
+}
+
//================================================================================
/*!
* Fill data._simplexTestEdges. These _LayerEdge's are used to stop inflation
const double minCurvature = 1. / data._hyp->GetTotalThickness();
- for ( size_t iS = 0; iS < edgesByGeom.size(); ++iS )
+ for ( size_t iS = 1; iS < edgesByGeom.size(); ++iS )
{
// look for a FACE with layers and w/o _LayerEdge's
const vector<_LayerEdge*>& eS = edgesByGeom[iS];
if ( s.IsNull() || s.ShapeType() != TopAbs_FACE || !subIds.count( *id ))
continue;
F = TopoDS::Face( s );
+ geomNorm = getFaceNormal( node, F, helper, normOK );
+ if ( !normOK ) continue;
- gp_XY uv = helper.GetNodeUV( F, node, 0, &normOK );
- Handle(Geom_Surface) surface = BRep_Tool::Surface( F );
- {
- gp_Dir normal;
- if ( GeomLib::NormEstim( surface, uv, 1e-10, normal ) < 3 )
- {
- geomNorm = normal;
- normOK = true;
- }
- else // hard singularity
- {
- SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator(SMDSAbs_Face);
- while ( fIt->more() )
- {
- const SMDS_MeshElement* f = fIt->next();
- if ( editor.FindShape( f ) == *id )
- {
- SMESH_MeshAlgos::FaceNormal( f, (gp_XYZ&) geomNorm.XYZ(), /*normalized=*/false );
- if ( helper.IsReversedSubMesh( F ))
- geomNorm.Reverse();
- break;
- }
- }
- double size2 = geomNorm.SquareMagnitude();
- if ( size2 > numeric_limits<double>::min() )
- geomNorm /= sqrt( size2 );
- else
- normOK = false;
- }
- }
if ( helper.GetSubShapeOri( data._solid, F ) != TopAbs_REVERSED )
geomNorm.Reverse();
id2Norm[ totalNbFaces ].first = *id;
if ( totalNbFaces == 0 )
return error(SMESH_Comment("Can't get normal to node ") << node->GetID(), data._index);
+ if ( normOK && edge._normal.Modulus() < 1e-3 && totalNbFaces > 1 )
+ {
+ // opposite normals, re-get normals at shifted positions (IPAL 52426)
+ edge._normal.SetCoord( 0,0,0 );
+ for ( int i = 0; i < totalNbFaces; ++i )
+ {
+ const TopoDS_Face& F = TopoDS::Face( getMeshDS()->IndexToShape( id2Norm[i].first ));
+ geomNorm = getFaceNormal( node, F, helper, normOK, /*shiftInside=*/true );
+ if ( helper.GetSubShapeOri( data._solid, F ) != TopAbs_REVERSED )
+ geomNorm.Reverse();
+ if ( normOK )
+ id2Norm[ i ].second = geomNorm.XYZ();
+ edge._normal += id2Norm[ i ].second;
+ }
+ }
+
if ( totalNbFaces < 3 )
{
//edge._normal /= totalNbFaces;
case SMDS_TOP_EDGE: {
TopoDS_Edge E = TopoDS::Edge( helper.GetSubShapeByNode( node, getMeshDS()));
- gp_Vec inFaceDir = getFaceDir( F, E, node, helper, normOK);
+ gp_Vec inFaceDir = getFaceDir( F, E, node, helper, normOK );
double angle = inFaceDir.Angle( edge._normal ); // [0,PI]
edge._cosin = cos( angle );
//cout << "Cosin on EDGE " << edge._cosin << " node " << node->GetID() << endl;
}
case SMDS_TOP_VERTEX: {
TopoDS_Vertex V = TopoDS::Vertex( helper.GetSubShapeByNode( node, getMeshDS()));
- gp_XYZ inFaceDir = getFaceDir( F, V, node, helper, normOK);
- double angle = gp_Vec( inFaceDir).Angle( edge._normal ); // [0,PI]
+ gp_Vec inFaceDir = getFaceDir( F, V, node, helper, normOK );
+ double angle = inFaceDir.Angle( edge._normal ); // [0,PI]
edge._cosin = cos( angle );
//cout << "Cosin on VERTEX " << edge._cosin << " node " << node->GetID() << endl;
break;
default:
return error(SMESH_Comment("Invalid shape position of node ")<<node, data._index);
}
- }
+ } // case _sWOL.IsNull()
double normSize = edge._normal.SquareModulus();
if ( normSize < numeric_limits<double>::min() )
//================================================================================
/*!
- * \brief Return normal at a node weighted with angles taken by FACEs
+ * \brief Return normal to a FACE at a node
+ * \param [in] n - node
+ * \param [in] face - FACE
+ * \param [in] helper - helper
+ * \param [out] isOK - true or false
+ * \param [in] shiftInside - to find normal at a position shifted inside the face
+ * \return gp_XYZ - normal
+ */
+//================================================================================
+
+gp_XYZ _ViscousBuilder::getFaceNormal(const SMDS_MeshNode* node,
+ const TopoDS_Face& face,
+ SMESH_MesherHelper& helper,
+ bool& isOK,
+ bool shiftInside)
+{
+ gp_XY uv;
+ if ( shiftInside )
+ {
+ // get a shifted position
+ gp_Pnt p = SMESH_TNodeXYZ( node );
+ gp_XYZ shift( 0,0,0 );
+ TopoDS_Shape S = helper.GetSubShapeByNode( node, helper.GetMeshDS() );
+ switch ( S.ShapeType() ) {
+ case TopAbs_VERTEX:
+ {
+ shift = getFaceDir( face, TopoDS::Vertex( S ), node, helper, isOK );
+ break;
+ }
+ case TopAbs_EDGE:
+ {
+ shift = getFaceDir( face, TopoDS::Edge( S ), node, helper, isOK );
+ break;
+ }
+ default:
+ isOK = false;
+ }
+ if ( isOK )
+ shift.Normalize();
+ p.Translate( shift * 1e-5 );
+
+ TopLoc_Location loc;
+ GeomAPI_ProjectPointOnSurf& projector = helper.GetProjector( face, loc, 1e-7 );
+
+ if ( !loc.IsIdentity() ) p.Transform( loc.Transformation().Inverted() );
+
+ projector.Perform( p );
+ if ( !projector.IsDone() || projector.NbPoints() < 1 )
+ {
+ isOK = false;
+ return p.XYZ();
+ }
+ Quantity_Parameter U,V;
+ projector.LowerDistanceParameters(U,V);
+ uv.SetCoord( U,V );
+ }
+ else
+ {
+ uv = helper.GetNodeUV( face, node, 0, &isOK );
+ }
+
+ gp_Dir normal;
+ isOK = false;
+
+ Handle(Geom_Surface) surface = BRep_Tool::Surface( face );
+ if ( GeomLib::NormEstim( surface, uv, 1e-10, normal ) < 3 )
+ {
+ normal;
+ isOK = true;
+ }
+ else // hard singularity
+ {
+ const TGeomID faceID = helper.GetMeshDS()->ShapeToIndex( face );
+
+ SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator(SMDSAbs_Face);
+ while ( fIt->more() )
+ {
+ const SMDS_MeshElement* f = fIt->next();
+ if ( f->getshapeId() == faceID )
+ {
+ isOK = SMESH_MeshAlgos::FaceNormal( f, (gp_XYZ&) normal.XYZ(), /*normalized=*/true );
+ if ( isOK )
+ {
+ if ( helper.IsReversedSubMesh( face ))
+ normal.Reverse();
+ break;
+ }
+ }
+ }
+ }
+ return normal.XYZ();
+}
+
+//================================================================================
+/*!
+ * \brief Return a normal at a node weighted with angles taken by FACEs
* \param [in] n - the node
* \param [in] fId2Normal - FACE ids and normals
* \param [in] nbFaces - nb of FACEs meeting at the node
void _LayerEdge::SetCosin( double cosin )
{
_cosin = cosin;
- _lenFactor = ( Abs( _cosin ) > 0.1 ) ? 1./sqrt(1-_cosin*_cosin) : 1.0;
+ cosin = Abs( _cosin );
+ _lenFactor = ( /*0.1 < cosin &&*/ cosin < 1-1e-12 ) ? 1./sqrt(1-cosin*cosin) : 1.0;
}
//================================================================================
gp_Vec2d vec1( center, uv1 );
double uLast = vec0.Angle( vec1 ); // -PI - +PI
double uMidl = vec0.Angle( vecM );
- if ( uLast * uMidl < 0. )
+ if ( uLast * uMidl <= 0. )
uLast += ( uMidl > 0 ? +2. : -2. ) * M_PI;
const double radius = 0.5 * ( vec0.Magnitude() + vec1.Magnitude() );
if ( edge1->_cosin < 0 )
dirInFace = dir1;
else
- getFaceDir( FF1[0], E1, edge1->_nodes[0], helper, ok );
+ dirInFace = getFaceDir( FF1[0], E1, edge1->_nodes[0], helper, ok );
double angle = dir1.Angle( edge1->_normal ); // [0,PI]
edge1->SetCosin( cos( angle ));