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 const Standard_Real theMinSize)
40 : myEdge(&theCurve.Edge()),
41 myIsoType(GeomAbs_NoneIso)
43 myDiscretTool.Initialize(theCurve, theFirstParam, theLastParam,
44 theAngDeflection, theLinDeflection, theMinPointsNb,
45 Precision::PConfusion(), theMinSize);
48 //=======================================================================
49 //function : Constructor
51 //=======================================================================
52 BRepMesh_GeomTool::BRepMesh_GeomTool(
53 const Handle(BRepAdaptor_HSurface)& theSurface,
54 const GeomAbs_IsoType theIsoType,
55 const Standard_Real theParamIso,
56 const Standard_Real theFirstParam,
57 const Standard_Real theLastParam,
58 const Standard_Real theLinDeflection,
59 const Standard_Real theAngDeflection,
60 const Standard_Integer theMinPointsNb,
61 const Standard_Real theMinSize)
65 Adaptor3d_IsoCurve aIso(theSurface, theIsoType, theParamIso,
66 theFirstParam, theLastParam);
68 myDiscretTool.Initialize(aIso, theFirstParam, theLastParam,
69 theAngDeflection, theLinDeflection, theMinPointsNb,
70 Precision::PConfusion(), theMinSize);
73 //=======================================================================
76 //=======================================================================
77 Standard_Boolean BRepMesh_GeomTool::Value(
78 const Standard_Integer theIndex,
79 Standard_Real& theParam,
80 gp_Pnt& thePoint) const
82 if (theIndex < 1 || theIndex > NbPoints())
83 return Standard_False;
86 return Standard_False;
88 thePoint = myDiscretTool.Value(theIndex);
89 theParam = myDiscretTool.Parameter(theIndex);
94 //=======================================================================
97 //=======================================================================
98 Standard_Boolean BRepMesh_GeomTool::Value(const Standard_Integer theIndex,
99 const Standard_Real theIsoParam,
100 Standard_Real& theParam,
102 gp_Pnt2d& theUV) const
104 if (theIndex < 1 || theIndex > NbPoints())
105 return Standard_False;
107 thePoint = myDiscretTool.Value(theIndex);
108 theParam = myDiscretTool.Parameter(theIndex);
110 if (myIsoType == GeomAbs_IsoU)
111 theUV.SetCoord(theIsoParam, theParam);
113 theUV.SetCoord(theParam, theIsoParam);
115 return Standard_True;
118 //=======================================================================
121 //=======================================================================
122 Standard_Boolean BRepMesh_GeomTool::Normal(
123 const Handle(BRepAdaptor_HSurface)& theSurface,
124 const Standard_Real theParamU,
125 const Standard_Real theParamV,
129 Standard_Boolean isOK = Standard_True;
132 theSurface->D1(theParamU, theParamV, thePoint, aD1U, aD1V);
134 CSLib_DerivativeStatus aStatus;
135 CSLib::Normal(aD1U, aD1V, Precision::Angular(), aStatus, theNormal);
136 if (aStatus != CSLib_Done)
138 gp_Vec aD2U,aD2V,aD2UV;
139 theSurface->D2(theParamU, theParamV, thePoint, aD1U, aD1V, aD2U, aD2V, aD2UV);
140 CSLib_NormalStatus aNormalStatus;
141 CSLib::Normal(aD1U, aD1V, aD2U, aD2V, aD2UV, Precision::Angular(),
142 isOK, aNormalStatus, theNormal);
146 return Standard_False;
148 const TopoDS_Face& aFace = ((BRepAdaptor_Surface*)&(theSurface->Surface()))->Face();
149 TopAbs_Orientation aOri = aFace.Orientation();
150 if (aOri == TopAbs_REVERSED)
153 return Standard_True;
156 //=============================================================================
157 //function : IntLinLin
159 //=============================================================================
160 BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntLinLin(
161 const gp_XY& theStartPnt1,
162 const gp_XY& theEndPnt1,
163 const gp_XY& theStartPnt2,
164 const gp_XY& theEndPnt2,
166 Standard_Real (&theParamOnSegment)[2])
168 gp_XY aVec1 = theEndPnt1 - theStartPnt1;
169 gp_XY aVec2 = theEndPnt2 - theStartPnt2;
170 gp_XY aVecO1O2 = theStartPnt2 - theStartPnt1;
172 Standard_Real aCrossD1D2 = aVec1 ^ aVec2;
173 Standard_Real aCrossD1D3 = aVecO1O2 ^ aVec2;
175 const Standard_Real aPrec = gp::Resolution();
176 // Are edgegs codirectional
177 if ( Abs( aCrossD1D2 ) < aPrec )
179 // Just a parallel case?
180 if( Abs( aCrossD1D3 ) < aPrec )
181 return BRepMesh_GeomTool::Same;
183 return BRepMesh_GeomTool::NoIntersection;
186 theParamOnSegment[0] = aCrossD1D3 / aCrossD1D2;
187 theIntPnt = theStartPnt1 + theParamOnSegment[0] * aVec1;
189 Standard_Real aCrossD2D3 = aVecO1O2 ^ aVec1;
190 theParamOnSegment[1] = aCrossD2D3 / aCrossD1D2;
192 return BRepMesh_GeomTool::Cross;
195 //=============================================================================
196 //function : IntSegSeg
198 //=============================================================================
199 BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntSegSeg(
200 const gp_XY& theStartPnt1,
201 const gp_XY& theEndPnt1,
202 const gp_XY& theStartPnt2,
203 const gp_XY& theEndPnt2,
204 const Standard_Boolean isConsiderEndPointTouch,
205 const Standard_Boolean isConsiderPointOnSegment,
208 Standard_Integer aPointHash[] = {
209 classifyPoint(theStartPnt1, theEndPnt1, theStartPnt2),
210 classifyPoint(theStartPnt1, theEndPnt1, theEndPnt2 ),
211 classifyPoint(theStartPnt2, theEndPnt2, theStartPnt1),
212 classifyPoint(theStartPnt2, theEndPnt2, theEndPnt1 )
215 // Consider case when edges have shared vertex
216 if ( aPointHash[0] < 0 || aPointHash[1] < 0 )
218 if ( isConsiderEndPointTouch )
219 return BRepMesh_GeomTool::EndPointTouch;
221 return BRepMesh_GeomTool::NoIntersection;
224 Standard_Integer aPosHash =
225 aPointHash[0] + aPointHash[1] + aPointHash[2] + aPointHash[3];
227 /*=========================================*/
228 /* 1) hash code == 1:
238 a) +----+========+---+
241 b) +-------+===+=====+
244 /*=========================================*/
247 if (isConsiderPointOnSegment)
249 if (aPointHash[0] == 1)
250 theIntPnt = theStartPnt1;
251 else if (aPointHash[1] == 1)
252 theIntPnt = theEndPnt1;
253 else if (aPointHash[2] == 1)
254 theIntPnt = theStartPnt2;
256 theIntPnt = theEndPnt2;
258 return BRepMesh_GeomTool::PointOnSegment;
261 return BRepMesh_GeomTool::NoIntersection;
263 else if ( aPosHash == 2 )
264 return BRepMesh_GeomTool::Glued;
266 Standard_Real aParam[2];
267 IntFlag aIntFlag = IntLinLin(theStartPnt1, theEndPnt1,
268 theStartPnt2, theEndPnt2, theIntPnt.ChangeCoord(), aParam);
270 if (aIntFlag == BRepMesh_GeomTool::NoIntersection)
271 return BRepMesh_GeomTool::NoIntersection;
273 if (aIntFlag == BRepMesh_GeomTool::Same)
276 return BRepMesh_GeomTool::Same;
277 else if ( aPosHash == -1 )
278 return BRepMesh_GeomTool::Glued;
280 return BRepMesh_GeomTool::NoIntersection;
284 // Intersection is out of segments ranges
285 const Standard_Real aPrec = Precision::PConfusion();
286 const Standard_Real aEndPrec = 1 - aPrec;
287 for (Standard_Integer i = 0; i < 2; ++i)
289 if( aParam[i] < aPrec || aParam[i] > aEndPrec )
290 return BRepMesh_GeomTool::NoIntersection;
293 return BRepMesh_GeomTool::Cross;
296 //=============================================================================
297 //function : classifyPoint
299 //=============================================================================
300 Standard_Integer BRepMesh_GeomTool::classifyPoint(
301 const gp_XY& thePoint1,
302 const gp_XY& thePoint2,
303 const gp_XY& thePointToCheck)
305 gp_XY aP1 = thePoint2 - thePoint1;
306 gp_XY aP2 = thePointToCheck - thePoint1;
308 const Standard_Real aPrec = Precision::PConfusion();
309 const Standard_Real aSqPrec = aPrec * aPrec;
310 Standard_Real aDist = Abs(aP1 ^ aP2);
313 aDist = (aDist * aDist) / aP1.SquareModulus();
318 gp_XY aMult = aP1.Multiplied(aP2);
319 if ( aMult.X() < 0.0 || aMult.Y() < 0.0 )
322 if (aP1.SquareModulus() < aP2.SquareModulus())
325 if (thePointToCheck.IsEqual(thePoint1, aPrec) ||
326 thePointToCheck.IsEqual(thePoint2, aPrec))
328 return -1; //coinsides with an end point