#include "StdMeshers_MEFISTO_2D.hxx"#include "SMESH_Gen.hxx"#include "SMESH_Mesh.hxx"#include "SMESH_subMesh.hxx"#include "SMESH_Block.hxx"#include "SMESH_MesherHelper.hxx"#include "SMESH_Comment.hxx"#include "StdMeshers_FaceSide.hxx"#include "StdMeshers_MaxElementArea.hxx"#include "StdMeshers_LengthFromEdges.hxx"#include "Rn.h"#include "aptrte.h"#include "SMDS_MeshElement.hxx"#include "SMDS_MeshNode.hxx"#include "SMDS_EdgePosition.hxx"#include "SMDS_FacePosition.hxx"#include "utilities.h"#include <BRepTools.hxx>#include <BRep_Tool.hxx>#include <Geom_Curve.hxx>#include <Geom2d_Curve.hxx>#include <Geom_Surface.hxx>#include <Precision.hxx>#include <TopExp.hxx>#include <TopExp_Explorer.hxx>#include <TopTools_ListIteratorOfListOfShape.hxx>#include <TopTools_ListOfShape.hxx>#include <TopTools_MapOfShape.hxx>#include <TopoDS.hxx>#include <TopoDS_Edge.hxx>#include <TopoDS_Face.hxx>#include <TopoDS_Iterator.hxx>#include <gp_Pnt2d.hxx>#include <GProp_GProps.hxx>#include <BRepGProp.hxx>
Go to the source code of this file.
Functions | |
| static bool | fixOverlappedLinkUV (R2 &uv0, const R2 &uv1, const R2 &uv2) |
| static bool | fixCommonVertexUV (R2 &theUV, const TopoDS_Vertex &theV, const TopoDS_Face &theF, const TopTools_IndexedDataMapOfShapeListOfShape &theVWMap, SMESH_Mesh &theMesh, const double theScaleX, const double theScaleY, const bool theCreateQuadratic) |
| static bool fixCommonVertexUV | ( | R2 & | theUV, |
| const TopoDS_Vertex & | theV, | ||
| const TopoDS_Face & | theF, | ||
| const TopTools_IndexedDataMapOfShapeListOfShape & | theVWMap, | ||
| SMESH_Mesh & | theMesh, | ||
| const double | theScaleX, | ||
| const double | theScaleY, | ||
| const bool | theCreateQuadratic | ||
| ) | [static] |
Definition at line 434 of file StdMeshers_MEFISTO_2D.cxx.
References fixOverlappedLinkUV(), SMDS_MeshNode.GetPosition(), SMDS_EdgePosition.GetUParameter(), Handle(), SMESH_MesherHelper.IsMedium(), MESSAGE, ex29_refine.node(), SMDSAbs_Edge, R2.x, and R2.y.
Referenced by StdMeshers_MEFISTO_2D.LoadPoints().
{
if( !theVWMap.Contains( theV )) return false;
// check if there is another wire sharing theV
const TopTools_ListOfShape& WList = theVWMap.FindFromKey( theV );
TopTools_ListIteratorOfListOfShape aWIt;
TopTools_MapOfShape aWires;
for ( aWIt.Initialize( WList ); aWIt.More(); aWIt.Next() )
aWires.Add( aWIt.Value() );
if ( aWires.Extent() < 2 ) return false;
TopoDS_Shape anOuterWire = BRepTools::OuterWire(theF);
TopoDS_Shape anInnerWire;
for ( aWIt.Initialize( WList ); aWIt.More() && anInnerWire.IsNull(); aWIt.Next() )
if ( !anOuterWire.IsSame( aWIt.Value() ))
anInnerWire = aWIt.Value();
TopTools_ListOfShape EList;
list< double > UList;
// find edges of theW sharing theV
// and find 2d normal to them at theV
gp_Vec2d N(0.,0.);
TopoDS_Iterator itE( anInnerWire );
for ( ; itE.More(); itE.Next() )
{
const TopoDS_Edge& E = TopoDS::Edge( itE.Value() );
TopoDS_Iterator itV( E );
for ( ; itV.More(); itV.Next() )
{
const TopoDS_Vertex & V = TopoDS::Vertex( itV.Value() );
if ( !V.IsSame( theV ))
continue;
EList.Append( E );
Standard_Real u = BRep_Tool::Parameter( V, E );
UList.push_back( u );
double f, l;
Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
gp_Vec2d d1;
gp_Pnt2d p;
C2d->D1( u, p, d1 );
gp_Vec2d n( d1.Y() * theScaleX, -d1.X() * theScaleY);
if ( E.Orientation() == TopAbs_REVERSED )
n.Reverse();
N += n.Normalized();
}
}
// define step size by which to move theUV
gp_Pnt2d nextUV; // uv of next node on edge, most distant of the four
gp_Pnt2d thisUV( theUV.x, theUV.y );
double maxDist = -DBL_MAX;
TopTools_ListIteratorOfListOfShape aEIt (EList);
list< double >::iterator aUIt = UList.begin();
for ( ; aEIt.More(); aEIt.Next(), aUIt++ )
{
const TopoDS_Edge& E = TopoDS::Edge( aEIt.Value() );
double f, l;
Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
double umin = DBL_MAX, umax = -DBL_MAX;
SMDS_NodeIteratorPtr nIt = theMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
if ( !nIt->more() ) // no nodes on edge, only on vertices
{
umin = l;
umax = f;
}
else {
while ( nIt->more() ) {
const SMDS_MeshNode* node = nIt->next();
// check if node is medium
if ( theCreateQuadratic && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
continue;
const SMDS_EdgePosition* epos =
static_cast<const SMDS_EdgePosition*>(node->GetPosition());
double u = epos->GetUParameter();
if ( u < umin )
umin = u;
if ( u > umax )
umax = u;
}
}
bool isFirstCommon = ( *aUIt == f );
gp_Pnt2d uv = C2d->Value( isFirstCommon ? umin : umax );
double dist = thisUV.SquareDistance( uv );
if ( dist > maxDist ) {
maxDist = dist;
nextUV = uv;
}
}
R2 uv0, uv1, uv2;
uv0.x = thisUV.X(); uv0.y = thisUV.Y();
uv1.x = nextUV.X(); uv1.y = nextUV.Y();
uv2.x = thisUV.X(); uv2.y = thisUV.Y();
uv1.x *= theScaleX; uv1.y *= theScaleY;
if ( fixOverlappedLinkUV( uv0, uv1, uv2 ))
{
double step = thisUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
// move theUV along the normal by the step
N *= step;
MESSAGE("--fixCommonVertexUV move(" << theUV.x << " " << theUV.x
<< ") by (" << N.X() << " " << N.Y() << ")"
<< endl << "--- MAX DIST " << maxDist);
theUV.x += N.X();
theUV.y += N.Y();
return true;
}
return false;
}
Definition at line 383 of file StdMeshers_MEFISTO_2D.cxx.
References SMESH.if(), MESSAGE, R2.x, and R2.y.
Referenced by fixCommonVertexUV(), and StdMeshers_MEFISTO_2D.LoadPoints().
{
gp_XY v1( uv0.x - uv1.x, uv0.y - uv1.y );
gp_XY v2( uv2.x - uv1.x, uv2.y - uv1.y );
double tol2 = DBL_MIN * DBL_MIN;
double sqMod1 = v1.SquareModulus();
if ( sqMod1 <= tol2 ) return false;
double sqMod2 = v2.SquareModulus();
if ( sqMod2 <= tol2 ) return false;
double dot = v1*v2;
// check sinus >= 1.e-3
const double minSin = 1.e-3;
if ( dot > 0 && 1 - dot * dot / ( sqMod1 * sqMod2 ) < minSin * minSin ) {
MESSAGE(" ___ FIX UV ____" << uv0.x << " " << uv0.y);
v1.SetCoord( -v1.Y(), v1.X() );
double delta = sqrt( sqMod1 ) * minSin;
if ( v1.X() < 0 )
uv0.x -= delta;
else
uv0.x += delta;
if ( v1.Y() < 0 )
uv0.y -= delta;
else
uv0.y += delta;
// #ifdef _DEBUG_
// MESSAGE(" -> " << uv0.x << " " << uv0.y << " ");
// MESSAGE("v1( " << v1.X() << " " << v1.Y() << " ) " <<
// "v2( " << v2.X() << " " << v2.Y() << " ) ");
// MESSAGE("SIN: " << sqrt(1 - dot * dot / (sqMod1 * sqMod2)));
// v1.SetCoord( uv0.x - uv1.x, uv0.y - uv1.y );
// v2.SetCoord( uv2.x - uv1.x, uv2.y - uv1.y );
// gp_XY v3( uv2.x - uv0.x, uv2.y - uv0.y );
// sqMod1 = v1.SquareModulus();
// sqMod2 = v2.SquareModulus();
// dot = v1*v2;
// double sin = sqrt(1 - dot * dot / (sqMod1 * sqMod2));
// MESSAGE("NEW SIN: " << sin);
// #endif
return true;
}
return false;
}