// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-#include <BRepMesh_GeomTool.ixx>
+#include <BRepMesh_GeomTool.hxx>
-#include <BRepMesh_ShapeTool.hxx>
#include <TopAbs_Orientation.hxx>
-#include <GeomAbs_SurfaceType.hxx>
#include <CSLib.hxx>
#include <Precision.hxx>
#include <Adaptor3d_IsoCurve.hxx>
#include <BRepAdaptor_Curve.hxx>
+#include <BRepAdaptor_HSurface.hxx>
+#include <Geom2d_Curve.hxx>
+#include <BRep_Tool.hxx>
-BRepMesh_GeomTool::BRepMesh_GeomTool(BRepAdaptor_Curve& C,
- const Standard_Real Ufirst,
- const Standard_Real Ulast,
- const Standard_Real AngDefl,
- const Standard_Real Deflection,
- const Standard_Integer nbpmin) :
- pnts(C,Ufirst,Ulast,AngDefl,Deflection, nbpmin),
-// pnts(C,Deflection,Ufirst,Ulast),
- parametric(GeomAbs_NoneIso)
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+BRepMesh_GeomTool::BRepMesh_GeomTool(
+ const BRepAdaptor_Curve& theCurve,
+ const Standard_Real theFirstParam,
+ const Standard_Real theLastParam,
+ const Standard_Real theLinDeflection,
+ const Standard_Real theAngDeflection,
+ const Standard_Integer theMinPointsNb)
+ : myEdge(&theCurve.Edge()),
+ myIsoType(GeomAbs_NoneIso)
{
+ myDiscretTool.Initialize(theCurve, theFirstParam, theLastParam,
+ theAngDeflection, theLinDeflection, theMinPointsNb);
}
-//
-BRepMesh_GeomTool::BRepMesh_GeomTool(const Handle(BRepAdaptor_HSurface)& S,
- const Standard_Real ParamIso,
- const GeomAbs_IsoType Type,
- const Standard_Real Ufirst,
- const Standard_Real Ulast,
- const Standard_Real AngDefl,
- const Standard_Real Deflection,
- const Standard_Integer nbpmin) :
- parametric(Type)
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+BRepMesh_GeomTool::BRepMesh_GeomTool(
+ const Handle(BRepAdaptor_HSurface)& theSurface,
+ const GeomAbs_IsoType theIsoType,
+ const Standard_Real theParamIso,
+ const Standard_Real theFirstParam,
+ const Standard_Real theLastParam,
+ const Standard_Real theLinDeflection,
+ const Standard_Real theAngDeflection,
+ const Standard_Integer theMinPointsNb)
+ : myEdge(NULL),
+ myIsoType(theIsoType)
{
- Adaptor3d_IsoCurve Iso(S, Type,ParamIso,Ufirst,Ulast);
- pnts.Initialize(Iso,Ufirst,Ulast,AngDefl,Deflection, nbpmin);
-// pnts.Initialize(Iso,Deflection,Ufirst,Ulast);
+ Adaptor3d_IsoCurve aIso(theSurface, theIsoType, theParamIso,
+ theFirstParam, theLastParam);
+
+ myDiscretTool.Initialize(aIso, theFirstParam, theLastParam,
+ theAngDeflection, theLinDeflection, theMinPointsNb);
}
-Standard_Integer BRepMesh_GeomTool::AddPoint(const gp_Pnt& thePnt,
- const Standard_Real theParam,
- const Standard_Boolean theIsReplace)
+//=======================================================================
+//function : Value
+//purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_GeomTool::Value(
+ const Standard_Integer theIndex,
+ const Handle(BRepAdaptor_HSurface)& theSurface,
+ Standard_Real& theParam,
+ gp_Pnt& thePoint,
+ gp_Pnt2d& theUV) const
{
- return pnts.AddPoint(thePnt, theParam, theIsReplace);
+ if (theIndex < 1 || theIndex > NbPoints())
+ return Standard_False;
+
+ if (myEdge == NULL)
+ return Standard_False;
+
+ thePoint = myDiscretTool.Value(theIndex);
+ theParam = myDiscretTool.Parameter(theIndex);
+
+ const TopoDS_Face& aFace = ((BRepAdaptor_Surface*)&(theSurface->Surface()))->Face();
+
+ Standard_Real aFirst, aLast;
+ Handle(Geom2d_Curve) aCurve =
+ BRep_Tool::CurveOnSurface(*myEdge, aFace, aFirst, aLast);
+
+ aCurve->D0(theParam, theUV);
+
+ return Standard_True;
}
-Standard_Integer BRepMesh_GeomTool::NbPoints() const {
- return pnts.NbPoints();
+//=======================================================================
+//function : Value
+//purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_GeomTool::Value(const Standard_Integer theIndex,
+ const Standard_Real theIsoParam,
+ Standard_Real& theParam,
+ gp_Pnt& thePoint,
+ gp_Pnt2d& theUV) const
+{
+ if (theIndex < 1 || theIndex > NbPoints())
+ return Standard_False;
+
+ thePoint = myDiscretTool.Value(theIndex);
+ theParam = myDiscretTool.Parameter(theIndex);
+
+ if (myIsoType == GeomAbs_IsoU)
+ theUV.SetCoord(theIsoParam, theParam);
+ else
+ theUV.SetCoord(theParam, theIsoParam);
+
+ return Standard_True;
}
-void BRepMesh_GeomTool::Value(const Standard_Real IsoParam,
- const Standard_Integer Index,
- Standard_Real& W, gp_Pnt& P, gp_Pnt2d& UV) const
+//=======================================================================
+//function : Normal
+//purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_GeomTool::Normal(
+ const Handle(BRepAdaptor_HSurface)& theSurface,
+ const Standard_Real theParamU,
+ const Standard_Real theParamV,
+ gp_Pnt& thePoint,
+ gp_Dir& theNormal)
{
- P = pnts.Value(Index);
- W = pnts.Parameter(Index);
- if (parametric == GeomAbs_IsoU) {
- UV.SetCoord(IsoParam,W);
- }
- else {
- UV.SetCoord(W,IsoParam);
+ Standard_Boolean isOK = Standard_True;
+ gp_Vec aD1U, aD1V;
+
+ theSurface->D1(theParamU, theParamV, thePoint, aD1U, aD1V);
+
+ CSLib_DerivativeStatus aStatus;
+ CSLib::Normal(aD1U, aD1V, Precision::Angular(), aStatus, theNormal);
+ if (aStatus != CSLib_Done)
+ {
+ gp_Vec aD2U,aD2V,aD2UV;
+ theSurface->D2(theParamU, theParamV, thePoint, aD1U, aD1V, aD2U, aD2V, aD2UV);
+ CSLib_NormalStatus aNormalStatus;
+ CSLib::Normal(aD1U, aD1V, aD2U, aD2V, aD2UV, Precision::Angular(),
+ isOK, aNormalStatus, theNormal);
}
+
+ if (!isOK)
+ return Standard_False;
+
+ const TopoDS_Face& aFace = ((BRepAdaptor_Surface*)&(theSurface->Surface()))->Face();
+ TopAbs_Orientation aOri = aFace.Orientation();
+ if (aOri == TopAbs_REVERSED)
+ theNormal.Reverse();
+
+ return Standard_True;
}
-void BRepMesh_GeomTool::Value(const BRepAdaptor_Curve& C,
- const Handle(BRepAdaptor_HSurface)& S,
- const Standard_Integer Index,
- Standard_Real& W, gp_Pnt& P, gp_Pnt2d& UV) const
+//=============================================================================
+//function : IntLinLin
+//purpose :
+//=============================================================================
+BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntLinLin(
+ const gp_XY& theStartPnt1,
+ const gp_XY& theEndPnt1,
+ const gp_XY& theStartPnt2,
+ const gp_XY& theEndPnt2,
+ gp_XY& theIntPnt,
+ Standard_Real (&theParamOnSegment)[2])
{
- P = pnts.Value(Index);
- W = pnts.Parameter(Index);
- BRepMesh_ShapeTool::Parameters(C.Edge(), ((BRepAdaptor_Surface*)&(S->Surface()))->Face(), W, UV);
+ gp_XY aVec1 = theEndPnt1 - theStartPnt1;
+ gp_XY aVec2 = theEndPnt2 - theStartPnt2;
+ gp_XY aVecO1O2 = theStartPnt2 - theStartPnt1;
+
+ Standard_Real aCrossD1D2 = aVec1 ^ aVec2;
+ Standard_Real aCrossD1D3 = aVecO1O2 ^ aVec2;
+
+ const Standard_Real aPrec = gp::Resolution();
+ // Are edgegs codirectional
+ if ( Abs( aCrossD1D2 ) < aPrec )
+ {
+ // Just a parallel case?
+ if( Abs( aCrossD1D3 ) < aPrec )
+ return BRepMesh_GeomTool::Same;
+ else
+ return BRepMesh_GeomTool::NoIntersection;
+ }
+
+ theParamOnSegment[0] = aCrossD1D3 / aCrossD1D2;
+ theIntPnt = theStartPnt1 + theParamOnSegment[0] * aVec1;
+
+ Standard_Real aCrossD2D3 = aVecO1O2 ^ aVec1;
+ theParamOnSegment[1] = aCrossD2D3 / aCrossD1D2;
+
+ return BRepMesh_GeomTool::Cross;
}
-void BRepMesh_GeomTool::D0(const Handle(BRepAdaptor_HSurface)& S,const Standard_Real U,
- const Standard_Real V,gp_Pnt& P)
+//=============================================================================
+//function : IntSegSeg
+//purpose :
+//=============================================================================
+BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntSegSeg(
+ const gp_XY& theStartPnt1,
+ const gp_XY& theEndPnt1,
+ const gp_XY& theStartPnt2,
+ const gp_XY& theEndPnt2,
+ const Standard_Boolean isConsiderEndPointTouch,
+ const Standard_Boolean isConsiderPointOnSegment,
+ gp_Pnt2d& theIntPnt)
{
- S->D0(U,V,P);
-}
-
-Standard_Boolean BRepMesh_GeomTool::Normal(const Handle(BRepAdaptor_HSurface)& S,
- const Standard_Real U,
- const Standard_Real V,
- gp_Pnt& P,
- gp_Dir& Nor)
+ Standard_Integer aPointHash[] = {
+ classifyPoint(theStartPnt1, theEndPnt1, theStartPnt2),
+ classifyPoint(theStartPnt1, theEndPnt1, theEndPnt2 ),
+ classifyPoint(theStartPnt2, theEndPnt2, theStartPnt1),
+ classifyPoint(theStartPnt2, theEndPnt2, theEndPnt1 )
+ };
+
+ // Consider case when edges have shared vertex
+ if ( isConsiderEndPointTouch )
+ {
+ if ( aPointHash[0] < 0 || aPointHash[1] < 0 )
+ return BRepMesh_GeomTool::EndPointTouch;
+ }
+
+ Standard_Integer aPosHash =
+ aPointHash[0] + aPointHash[1] + aPointHash[2] + aPointHash[3];
+
+ /*=========================================*/
+ /* 1) hash code == 1:
+
+ 0+
+ /
+ 0 1/ 0
+ +======+==========+
+
+ 2) hash code == 2:
+
+ 0 1 1 0
+ a) +----+========+---+
+
+ 0 1 1 0
+ b) +-------+===+=====+
+
+ */
+ /*=========================================*/
+ if ( aPosHash == 1 )
+ {
+ if (isConsiderPointOnSegment)
+ {
+ if (aPointHash[0] == 1)
+ theIntPnt = theStartPnt1;
+ else if (aPointHash[1] == 1)
+ theIntPnt = theEndPnt1;
+ else if (aPointHash[2] == 1)
+ theIntPnt = theStartPnt2;
+ else
+ theIntPnt = theEndPnt2;
+
+ return BRepMesh_GeomTool::PointOnSegment;
+ }
+
+ return BRepMesh_GeomTool::NoIntersection;
+ }
+ else if ( aPosHash == 2 )
+ return BRepMesh_GeomTool::Glued;
+
+ Standard_Real aParam[2];
+ IntFlag aIntFlag = IntLinLin(theStartPnt1, theEndPnt1,
+ theStartPnt2, theEndPnt2, theIntPnt.ChangeCoord(), aParam);
+
+ if (aIntFlag == BRepMesh_GeomTool::NoIntersection)
+ return BRepMesh_GeomTool::NoIntersection;
+
+ if (aIntFlag == BRepMesh_GeomTool::Same)
+ {
+ if ( aPosHash < -2 )
+ return BRepMesh_GeomTool::Same;
+ else if ( aPosHash == -1 )
+ return BRepMesh_GeomTool::Glued;
+
+ return BRepMesh_GeomTool::NoIntersection;
+ }
+
+ // Cross
+ // Intersection is out of segments ranges
+ const Standard_Real aPrec = Precision::PConfusion();
+ const Standard_Real aEndPrec = 1 - aPrec;
+ for (Standard_Integer i = 0; i < 2; ++i)
+ {
+ if( aParam[i] < aPrec || aParam[i] > aEndPrec )
+ return BRepMesh_GeomTool::NoIntersection;
+ }
+
+ return BRepMesh_GeomTool::Cross;
+}
+
+//=============================================================================
+//function : classifyPoint
+//purpose :
+//=============================================================================
+Standard_Integer BRepMesh_GeomTool::classifyPoint(
+ const gp_XY& thePoint1,
+ const gp_XY& thePoint2,
+ const gp_XY& thePointToCheck)
{
- Standard_Boolean OK = Standard_True;
- gp_Vec D1U,D1V;
- CSLib_DerivativeStatus Status;
- S->D1(U,V,P,D1U,D1V);
- CSLib::Normal(D1U,D1V,Standard_Real(Precision::Angular()),Status,Nor);
- if (Status!= CSLib_Done) {
- gp_Vec D2U,D2V,D2UV;
- S->D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
- CSLib_NormalStatus NStat;
- CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,Nor);
+ gp_XY aP1 = thePoint2 - thePoint1;
+ gp_XY aP2 = thePointToCheck - thePoint1;
+
+ const Standard_Real aPrec = Precision::PConfusion();
+ const Standard_Real aSqPrec = aPrec * aPrec;
+ Standard_Real aDist = Abs(aP1 ^ aP2);
+ if (aDist > aPrec)
+ {
+ aDist = (aDist * aDist) / aP1.SquareModulus();
+ if (aDist > aSqPrec)
+ return 0; //out
}
- if (OK) {
- if (BRepMesh_ShapeTool::Orientation(((BRepAdaptor_Surface*)&(S->Surface()))->Face()) == TopAbs_REVERSED) Nor.Reverse();
+
+ gp_XY aMult = aP1.Multiplied(aP2);
+ if ( aMult.X() < 0.0 || aMult.Y() < 0.0 )
+ return 0; //out
+
+ if (aP1.SquareModulus() < aP2.SquareModulus())
+ return 0; //out
+
+ if (thePointToCheck.IsEqual(thePoint1, aPrec) ||
+ thePointToCheck.IsEqual(thePoint2, aPrec))
+ {
+ return -1; //coinsides with an end point
}
- return OK;
+
+ return 1;
}