1 // Created on: 1993-09-29
2 // Created by: Isabelle GRIGNON
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <BRepMesh_GeomTool.hxx>
19 #include <TopAbs_Orientation.hxx>
21 #include <Precision.hxx>
22 #include <Adaptor3d_IsoCurve.hxx>
23 #include <BRepAdaptor_Curve.hxx>
24 #include <BRepAdaptor_HSurface.hxx>
25 #include <Geom2d_Curve.hxx>
26 #include <BRep_Tool.hxx>
28 //=======================================================================
29 //function : Constructor
31 //=======================================================================
32 BRepMesh_GeomTool::BRepMesh_GeomTool(
33 const BRepAdaptor_Curve& theCurve,
34 const Standard_Real theFirstParam,
35 const Standard_Real theLastParam,
36 const Standard_Real theLinDeflection,
37 const Standard_Real theAngDeflection,
38 const Standard_Integer theMinPointsNb)
39 : myEdge(&theCurve.Edge()),
40 myIsoType(GeomAbs_NoneIso)
42 myDiscretTool.Initialize(theCurve, theFirstParam, theLastParam,
43 theAngDeflection, theLinDeflection, theMinPointsNb);
46 //=======================================================================
47 //function : Constructor
49 //=======================================================================
50 BRepMesh_GeomTool::BRepMesh_GeomTool(
51 const Handle(BRepAdaptor_HSurface)& theSurface,
52 const GeomAbs_IsoType theIsoType,
53 const Standard_Real theParamIso,
54 const Standard_Real theFirstParam,
55 const Standard_Real theLastParam,
56 const Standard_Real theLinDeflection,
57 const Standard_Real theAngDeflection,
58 const Standard_Integer theMinPointsNb)
62 Adaptor3d_IsoCurve aIso(theSurface, theIsoType, theParamIso,
63 theFirstParam, theLastParam);
65 myDiscretTool.Initialize(aIso, theFirstParam, theLastParam,
66 theAngDeflection, theLinDeflection, theMinPointsNb);
69 //=======================================================================
72 //=======================================================================
73 Standard_Boolean BRepMesh_GeomTool::Value(
74 const Standard_Integer theIndex,
75 const Handle(BRepAdaptor_HSurface)& theSurface,
76 Standard_Real& theParam,
78 gp_Pnt2d& theUV) const
80 if (theIndex < 1 || theIndex > NbPoints())
81 return Standard_False;
84 return Standard_False;
86 thePoint = myDiscretTool.Value(theIndex);
87 theParam = myDiscretTool.Parameter(theIndex);
89 const TopoDS_Face& aFace = ((BRepAdaptor_Surface*)&(theSurface->Surface()))->Face();
91 Standard_Real aFirst, aLast;
92 Handle(Geom2d_Curve) aCurve =
93 BRep_Tool::CurveOnSurface(*myEdge, aFace, aFirst, aLast);
95 aCurve->D0(theParam, theUV);
100 //=======================================================================
103 //=======================================================================
104 Standard_Boolean BRepMesh_GeomTool::Value(const Standard_Integer theIndex,
105 const Standard_Real theIsoParam,
106 Standard_Real& theParam,
108 gp_Pnt2d& theUV) const
110 if (theIndex < 1 || theIndex > NbPoints())
111 return Standard_False;
113 thePoint = myDiscretTool.Value(theIndex);
114 theParam = myDiscretTool.Parameter(theIndex);
116 if (myIsoType == GeomAbs_IsoU)
117 theUV.SetCoord(theIsoParam, theParam);
119 theUV.SetCoord(theParam, theIsoParam);
121 return Standard_True;
124 //=======================================================================
127 //=======================================================================
128 Standard_Boolean BRepMesh_GeomTool::Normal(
129 const Handle(BRepAdaptor_HSurface)& theSurface,
130 const Standard_Real theParamU,
131 const Standard_Real theParamV,
135 Standard_Boolean isOK = Standard_True;
138 theSurface->D1(theParamU, theParamV, thePoint, aD1U, aD1V);
140 CSLib_DerivativeStatus aStatus;
141 CSLib::Normal(aD1U, aD1V, Precision::Angular(), aStatus, theNormal);
142 if (aStatus != CSLib_Done)
144 gp_Vec aD2U,aD2V,aD2UV;
145 theSurface->D2(theParamU, theParamV, thePoint, aD1U, aD1V, aD2U, aD2V, aD2UV);
146 CSLib_NormalStatus aNormalStatus;
147 CSLib::Normal(aD1U, aD1V, aD2U, aD2V, aD2UV, Precision::Angular(),
148 isOK, aNormalStatus, theNormal);
152 return Standard_False;
154 const TopoDS_Face& aFace = ((BRepAdaptor_Surface*)&(theSurface->Surface()))->Face();
155 TopAbs_Orientation aOri = aFace.Orientation();
156 if (aOri == TopAbs_REVERSED)
159 return Standard_True;
162 //=============================================================================
163 //function : IntLinLin
165 //=============================================================================
166 BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntLinLin(
167 const gp_XY& theStartPnt1,
168 const gp_XY& theEndPnt1,
169 const gp_XY& theStartPnt2,
170 const gp_XY& theEndPnt2,
172 Standard_Real (&theParamOnSegment)[2])
174 gp_XY aVec1 = theEndPnt1 - theStartPnt1;
175 gp_XY aVec2 = theEndPnt2 - theStartPnt2;
176 gp_XY aVecO1O2 = theStartPnt2 - theStartPnt1;
178 Standard_Real aCrossD1D2 = aVec1 ^ aVec2;
179 Standard_Real aCrossD1D3 = aVecO1O2 ^ aVec2;
181 const Standard_Real aPrec = gp::Resolution();
182 // Are edgegs codirectional
183 if ( Abs( aCrossD1D2 ) < aPrec )
185 // Just a parallel case?
186 if( Abs( aCrossD1D3 ) < aPrec )
187 return BRepMesh_GeomTool::Same;
189 return BRepMesh_GeomTool::NoIntersection;
192 theParamOnSegment[0] = aCrossD1D3 / aCrossD1D2;
193 theIntPnt = theStartPnt1 + theParamOnSegment[0] * aVec1;
195 Standard_Real aCrossD2D3 = aVecO1O2 ^ aVec1;
196 theParamOnSegment[1] = aCrossD2D3 / aCrossD1D2;
198 return BRepMesh_GeomTool::Cross;
201 //=============================================================================
202 //function : IntSegSeg
204 //=============================================================================
205 BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntSegSeg(
206 const gp_XY& theStartPnt1,
207 const gp_XY& theEndPnt1,
208 const gp_XY& theStartPnt2,
209 const gp_XY& theEndPnt2,
210 const Standard_Boolean isConsiderEndPointTouch,
211 const Standard_Boolean isConsiderPointOnSegment,
214 Standard_Integer aPointHash[] = {
215 classifyPoint(theStartPnt1, theEndPnt1, theStartPnt2),
216 classifyPoint(theStartPnt1, theEndPnt1, theEndPnt2 ),
217 classifyPoint(theStartPnt2, theEndPnt2, theStartPnt1),
218 classifyPoint(theStartPnt2, theEndPnt2, theEndPnt1 )
221 // Consider case when edges have shared vertex
222 if ( isConsiderEndPointTouch )
224 if ( aPointHash[0] < 0 || aPointHash[1] < 0 )
225 return BRepMesh_GeomTool::EndPointTouch;
228 Standard_Integer aPosHash =
229 aPointHash[0] + aPointHash[1] + aPointHash[2] + aPointHash[3];
231 /*=========================================*/
232 /* 1) hash code == 1:
242 a) +----+========+---+
245 b) +-------+===+=====+
248 /*=========================================*/
251 if (isConsiderPointOnSegment)
253 if (aPointHash[0] == 1)
254 theIntPnt = theStartPnt1;
255 else if (aPointHash[1] == 1)
256 theIntPnt = theEndPnt1;
257 else if (aPointHash[2] == 1)
258 theIntPnt = theStartPnt2;
260 theIntPnt = theEndPnt2;
262 return BRepMesh_GeomTool::PointOnSegment;
265 return BRepMesh_GeomTool::NoIntersection;
267 else if ( aPosHash == 2 )
268 return BRepMesh_GeomTool::Glued;
270 Standard_Real aParam[2];
271 IntFlag aIntFlag = IntLinLin(theStartPnt1, theEndPnt1,
272 theStartPnt2, theEndPnt2, theIntPnt.ChangeCoord(), aParam);
274 if (aIntFlag == BRepMesh_GeomTool::NoIntersection)
275 return BRepMesh_GeomTool::NoIntersection;
277 if (aIntFlag == BRepMesh_GeomTool::Same)
280 return BRepMesh_GeomTool::Same;
281 else if ( aPosHash == -1 )
282 return BRepMesh_GeomTool::Glued;
284 return BRepMesh_GeomTool::NoIntersection;
288 // Intersection is out of segments ranges
289 const Standard_Real aPrec = Precision::PConfusion();
290 const Standard_Real aEndPrec = 1 - aPrec;
291 for (Standard_Integer i = 0; i < 2; ++i)
293 if( aParam[i] < aPrec || aParam[i] > aEndPrec )
294 return BRepMesh_GeomTool::NoIntersection;
297 return BRepMesh_GeomTool::Cross;
300 //=============================================================================
301 //function : classifyPoint
303 //=============================================================================
304 Standard_Integer BRepMesh_GeomTool::classifyPoint(
305 const gp_XY& thePoint1,
306 const gp_XY& thePoint2,
307 const gp_XY& thePointToCheck)
309 gp_XY aP1 = thePoint2 - thePoint1;
310 gp_XY aP2 = thePointToCheck - thePoint1;
312 const Standard_Real aPrec = Precision::PConfusion();
313 const Standard_Real aSqPrec = aPrec * aPrec;
314 Standard_Real aDist = Abs(aP1 ^ aP2);
317 aDist = (aDist * aDist) / aP1.SquareModulus();
322 gp_XY aMult = aP1.Multiplied(aP2);
323 if ( aMult.X() < 0.0 || aMult.Y() < 0.0 )
326 if (aP1.SquareModulus() < aP2.SquareModulus())
329 if (thePointToCheck.IsEqual(thePoint1, aPrec) ||
330 thePointToCheck.IsEqual(thePoint2, aPrec))
332 return -1; //coinsides with an end point