]>
Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2000-11-16 |
2 | // Created by: Peter KURNEV | |
973c2be1 | 3 | // Copyright (c) 2000-2014 OPEN CASCADE SAS |
7fd59977 | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 6 | // |
d5f74e42 | 7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
11 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
7fd59977 | 15 | |
7fd59977 | 16 | |
42cf5bc1 | 17 | #include <Bnd_Box.hxx> |
7fd59977 | 18 | #include <BRep_Builder.hxx> |
19 | #include <BRep_Tool.hxx> | |
7fd59977 | 20 | #include <BRepAdaptor_Curve.hxx> |
21 | #include <BRepAdaptor_Surface.hxx> | |
7fd59977 | 22 | #include <Geom2d_Curve.hxx> |
42cf5bc1 | 23 | #include <Geom2d_TrimmedCurve.hxx> |
9ae88397 | 24 | #include <Geom2dAdaptor_Curve.hxx> |
7fd59977 | 25 | #include <Geom_BoundedCurve.hxx> |
42cf5bc1 | 26 | #include <Geom_Curve.hxx> |
7fd59977 | 27 | #include <Geom_Geometry.hxx> |
42cf5bc1 | 28 | #include <Geom_Line.hxx> |
29 | #include <Geom_Surface.hxx> | |
7fd59977 | 30 | #include <Geom_TrimmedCurve.hxx> |
42cf5bc1 | 31 | #include <GeomAbs_CurveType.hxx> |
32 | #include <GeomAdaptor_Curve.hxx> | |
33 | #include <GeomAdaptor_Surface.hxx> | |
34 | #include <GeomAPI_ProjectPointOnCurve.hxx> | |
35 | #include <GeomAPI_ProjectPointOnSurf.hxx> | |
36 | #include <gp.hxx> | |
37 | #include <gp_Ax1.hxx> | |
38 | #include <gp_Dir.hxx> | |
39 | #include <gp_Lin.hxx> | |
40 | #include <gp_Pln.hxx> | |
41 | #include <gp_Pnt.hxx> | |
42 | #include <gp_Pnt2d.hxx> | |
43 | #include <IntTools_CommonPrt.hxx> | |
7fd59977 | 44 | #include <IntTools_Curve.hxx> |
42cf5bc1 | 45 | #include <IntTools_FClass2d.hxx> |
46 | #include <IntTools_Range.hxx> | |
7fd59977 | 47 | #include <IntTools_SequenceOfCurves.hxx> |
42cf5bc1 | 48 | #include <IntTools_Tools.hxx> |
49 | #include <Precision.hxx> | |
50 | #include <TopExp_Explorer.hxx> | |
51 | #include <TopLoc_Location.hxx> | |
52 | #include <TopoDS.hxx> | |
53 | #include <TopoDS_Edge.hxx> | |
54 | #include <TopoDS_Face.hxx> | |
55 | #include <TopoDS_Shape.hxx> | |
56 | #include <TopoDS_Vertex.hxx> | |
57 | #include <TopoDS_Wire.hxx> | |
58 | #include <TopTools_IndexedDataMapOfShapeShape.hxx> | |
7fd59977 | 59 | |
60 | static | |
61 | void ParabolaTolerance(const Handle(Geom_Curve)& , | |
1e143abb | 62 | const Standard_Real , |
63 | const Standard_Real , | |
64 | const Standard_Real , | |
65 | Standard_Real& , | |
66 | Standard_Real& ); | |
7fd59977 | 67 | |
68 | //======================================================================= | |
69 | //function : HasInternalEdge | |
70 | //purpose : | |
71 | //======================================================================= | |
72 | Standard_Boolean IntTools_Tools::HasInternalEdge(const TopoDS_Wire& aW) | |
73 | { | |
74 | Standard_Boolean bFlag=Standard_True; | |
75 | ||
76 | TopExp_Explorer anExp(aW, TopAbs_EDGE); | |
77 | for (; anExp.More(); anExp.Next()) { | |
78 | const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current()); | |
79 | TopAbs_Orientation anOr=aE.Orientation(); | |
80 | if (anOr==TopAbs_INTERNAL) { | |
81 | return bFlag; | |
82 | } | |
83 | } | |
84 | return !bFlag; | |
85 | } | |
86 | ||
87 | //======================================================================= | |
88 | //function : IsClosed | |
89 | //purpose : | |
90 | //======================================================================= | |
91 | Standard_Boolean IntTools_Tools::IsClosed (const Handle(Geom_Curve)& aC3D) | |
92 | { | |
cf8e963a | 93 | Standard_Boolean bRet; |
94 | Standard_Real aF, aL, aDist, aPC; | |
7fd59977 | 95 | gp_Pnt aP1, aP2; |
cf8e963a | 96 | |
7fd59977 | 97 | Handle (Geom_BoundedCurve) aGBC= |
98 | Handle (Geom_BoundedCurve)::DownCast(aC3D); | |
99 | if (aGBC.IsNull()) { | |
100 | return Standard_False; | |
101 | } | |
cf8e963a | 102 | |
7fd59977 | 103 | aF=aC3D->FirstParameter(); |
104 | aL=aC3D-> LastParameter(); | |
105 | ||
106 | aC3D->D0(aF, aP1); | |
107 | aC3D->D0(aL, aP2); | |
108 | ||
cf8e963a | 109 | |
110 | // | |
cf8e963a | 111 | aPC=Precision::Confusion(); |
112 | aPC=aPC*aPC; | |
113 | aDist=aP1.SquareDistance(aP2); | |
114 | bRet=aDist<aPC; | |
115 | return bRet; | |
7fd59977 | 116 | } |
117 | ||
118 | //======================================================================= | |
119 | //function : RejectLines | |
120 | //purpose : | |
121 | //======================================================================= | |
122 | void IntTools_Tools::RejectLines(const IntTools_SequenceOfCurves& aSIn, | |
1e143abb | 123 | IntTools_SequenceOfCurves& aSOut) |
7fd59977 | 124 | { |
125 | Standard_Integer i, j, aNb; | |
126 | Standard_Boolean bFlag; | |
127 | Handle (Geom_Curve) aC3D; | |
128 | ||
129 | gp_Dir aD1, aD2; | |
130 | ||
131 | aSOut.Clear(); | |
132 | ||
133 | aNb=aSIn.Length(); | |
134 | for (i=1; i<=aNb; i++) { | |
135 | const IntTools_Curve& IC=aSIn(i); | |
136 | aC3D=IC.Curve(); | |
137 | // | |
138 | Handle (Geom_TrimmedCurve) aGTC= | |
139 | Handle (Geom_TrimmedCurve)::DownCast(aC3D); | |
140 | ||
141 | if (!aGTC.IsNull()) { | |
142 | aC3D=aGTC->BasisCurve(); | |
143 | IntTools_Curve* pIC=(IntTools_Curve*) &IC; | |
144 | pIC->SetCurve(aC3D); | |
145 | } | |
146 | // | |
147 | Handle (Geom_Line) aGLine= | |
148 | Handle (Geom_Line)::DownCast(aC3D); | |
149 | ||
150 | if (aGLine.IsNull()) { | |
151 | aSOut.Clear(); | |
152 | for (j=1; j<=aNb; j++) { | |
1e143abb | 153 | aSOut.Append(aSIn(j)); |
7fd59977 | 154 | } |
155 | return; | |
156 | } | |
157 | // | |
158 | gp_Lin aLin=aGLine->Lin(); | |
159 | aD2=aLin.Direction(); | |
160 | if (i==1) { | |
161 | aSOut.Append(IC); | |
162 | aD1=aD2; | |
163 | continue; | |
164 | } | |
165 | ||
166 | bFlag=IntTools_Tools::IsDirsCoinside(aD1, aD2); | |
167 | if (!bFlag) { | |
168 | aSOut.Append(IC); | |
169 | return; | |
170 | } | |
171 | } | |
172 | } | |
173 | ||
174 | //======================================================================= | |
175 | //function : IsDirsCoinside | |
176 | //purpose : | |
177 | //======================================================================= | |
178 | Standard_Boolean IntTools_Tools::IsDirsCoinside (const gp_Dir& D1, const gp_Dir& D2) | |
179 | { | |
180 | Standard_Boolean bFlag; | |
181 | gp_Pnt P1(D1.X(), D1.Y(), D1.Z()); | |
182 | gp_Pnt P2(D2.X(), D2.Y(), D2.Z()); | |
183 | Standard_Real dLim=0.0002, d; | |
184 | d=P1.Distance (P2); | |
185 | bFlag= (d<dLim || fabs (2.-d)<dLim); | |
186 | return bFlag; | |
187 | } | |
188 | ||
189 | //======================================================================= | |
190 | //function : IsDirsCoinside | |
191 | //purpose : | |
192 | //======================================================================= | |
193 | Standard_Boolean IntTools_Tools::IsDirsCoinside (const gp_Dir& D1, | |
1e143abb | 194 | const gp_Dir& D2, |
195 | const Standard_Real dLim) | |
7fd59977 | 196 | { |
197 | Standard_Boolean bFlag; | |
198 | Standard_Real d; | |
199 | // | |
200 | gp_Pnt P1(D1.X(), D1.Y(), D1.Z()); | |
201 | gp_Pnt P2(D2.X(), D2.Y(), D2.Z()); | |
202 | d=P1.Distance (P2); | |
203 | bFlag= (d<dLim || fabs (2.-d)<dLim); | |
204 | return bFlag; | |
205 | } | |
206 | //======================================================================= | |
207 | //function : SplitCurve | |
208 | //purpose : | |
209 | //======================================================================= | |
210 | Standard_Integer IntTools_Tools::SplitCurve(const IntTools_Curve& IC, | |
1e143abb | 211 | IntTools_SequenceOfCurves& aCvs) |
7fd59977 | 212 | { |
213 | Handle (Geom_Curve) aC3D =IC.Curve(); | |
214 | if(aC3D.IsNull()) | |
215 | return 0; | |
216 | // | |
217 | Handle (Geom2d_Curve) aC2D1=IC.FirstCurve2d(); | |
218 | Handle (Geom2d_Curve) aC2D2=IC.SecondCurve2d(); | |
219 | Standard_Boolean bIsClosed; | |
220 | ||
221 | bIsClosed=IntTools_Tools::IsClosed(aC3D); | |
222 | if (!bIsClosed) { | |
223 | return 0; | |
224 | } | |
225 | ||
226 | Standard_Real aF, aL, aMid; | |
227 | ||
228 | // | |
229 | aF=aC3D->FirstParameter(); | |
230 | aL=aC3D->LastParameter(); | |
231 | aMid=0.5*(aF+aL); | |
7fd59977 | 232 | GeomAdaptor_Curve aGAC(aC3D); |
233 | GeomAbs_CurveType aCT=aGAC.GetType(); | |
234 | if (aCT==GeomAbs_BSplineCurve || | |
235 | aCT==GeomAbs_BezierCurve) { | |
236 | //aMid=0.5*aMid; | |
237 | aMid=IntTools_Tools::IntermediatePoint(aF, aL); | |
238 | } | |
7fd59977 | 239 | // |
240 | Handle(Geom_Curve) aC3DNewF, aC3DNewL; | |
241 | aC3DNewF =new Geom_TrimmedCurve (aC3D, aF, aMid); | |
242 | aC3DNewL =new Geom_TrimmedCurve (aC3D, aMid, aL); | |
243 | ||
244 | // | |
245 | Handle (Geom2d_Curve) aC2D1F, aC2D1L, aC2D2F, aC2D2L; | |
246 | // | |
247 | if(!aC2D1.IsNull()) { | |
248 | aC2D1F=new Geom2d_TrimmedCurve (aC2D1, aF, aMid); | |
249 | aC2D1L=new Geom2d_TrimmedCurve (aC2D1, aMid, aL); | |
250 | } | |
251 | ||
252 | if(!aC2D2.IsNull()) { | |
253 | aC2D2F=new Geom2d_TrimmedCurve (aC2D2, aF, aMid); | |
254 | aC2D2L=new Geom2d_TrimmedCurve (aC2D2, aMid, aL); | |
255 | } | |
5652dc62 | 256 | // |
257 | IntTools_Curve aIC1(aC3DNewF, aC2D1F, aC2D2F, IC.Tolerance(), IC.TangentialTolerance()); | |
258 | IntTools_Curve aIC2(aC3DNewL, aC2D1L, aC2D2L, IC.Tolerance(), IC.TangentialTolerance()); | |
7fd59977 | 259 | // |
260 | aCvs.Append(aIC1); | |
261 | // | |
262 | aCvs.Append(aIC2); | |
263 | // | |
264 | return 2; | |
265 | } | |
266 | ||
267 | //======================================================================= | |
268 | //function : IntermediatePoint | |
269 | //purpose : | |
270 | //======================================================================= | |
271 | Standard_Real IntTools_Tools::IntermediatePoint (const Standard_Real aFirst, | |
1e143abb | 272 | const Standard_Real aLast) |
7fd59977 | 273 | { |
c6541a0c | 274 | //define parameter division number as 10*e^(-M_PI) = 0.43213918 |
7fd59977 | 275 | const Standard_Real PAR_T = 0.43213918; |
276 | Standard_Real aParm; | |
277 | aParm=(1.-PAR_T)*aFirst + PAR_T*aLast; | |
278 | return aParm; | |
279 | } | |
280 | ||
281 | //======================================================================= | |
282 | //function : IsVertex | |
283 | //purpose : | |
284 | //======================================================================= | |
285 | Standard_Boolean IntTools_Tools::IsVertex (const gp_Pnt& aP, | |
1e143abb | 286 | const Standard_Real aTolPV, |
287 | const TopoDS_Vertex& aV) | |
7fd59977 | 288 | { |
cf8e963a | 289 | Standard_Boolean bRet; |
7fd59977 | 290 | Standard_Real aTolV, aD, dTol; |
291 | gp_Pnt aPv; | |
292 | ||
293 | aTolV=BRep_Tool::Tolerance(aV); | |
294 | // | |
7fd59977 | 295 | dTol=Precision::Confusion(); |
296 | aTolV=aTolV+aTolPV+dTol; | |
7fd59977 | 297 | // |
298 | aPv=BRep_Tool::Pnt(aV); | |
cf8e963a | 299 | // |
cf8e963a | 300 | aD=aPv.SquareDistance(aP); |
301 | aTolV=aTolV*aTolV; | |
302 | bRet=(aD<=aTolV); | |
303 | return bRet; | |
7fd59977 | 304 | } |
305 | ||
306 | ||
307 | //======================================================================= | |
308 | //function : IsVertex | |
309 | //purpose : | |
310 | //======================================================================= | |
311 | Standard_Boolean IntTools_Tools::IsVertex (const IntTools_CommonPrt& aCmnPrt) | |
312 | { | |
313 | Standard_Boolean anIsVertex; | |
314 | Standard_Real aParam; | |
315 | ||
316 | const TopoDS_Edge& aE1=aCmnPrt.Edge1(); | |
317 | const IntTools_Range& aR1=aCmnPrt.Range1(); | |
318 | aParam=0.5*(aR1.First()+aR1.Last()); | |
319 | anIsVertex=IntTools_Tools::IsVertex (aE1, aParam); | |
320 | ||
321 | if (anIsVertex) { | |
322 | return Standard_True; | |
323 | } | |
324 | ||
325 | const TopoDS_Edge& aE2=aCmnPrt.Edge2(); | |
326 | const IntTools_SequenceOfRanges& aRs2=aCmnPrt.Ranges2(); | |
327 | const IntTools_Range& aR2=aRs2(1); | |
328 | aParam=0.5*(aR2.First()+aR2.Last()); | |
329 | anIsVertex=IntTools_Tools::IsVertex (aE2, aParam); | |
330 | if (anIsVertex) { | |
331 | return Standard_True; | |
332 | } | |
333 | return Standard_False; | |
334 | } | |
335 | ||
336 | //======================================================================= | |
337 | //function : IsVertex | |
338 | //purpose : | |
339 | //======================================================================= | |
340 | Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE, | |
1e143abb | 341 | const TopoDS_Vertex& aV, |
342 | const Standard_Real t) | |
7fd59977 | 343 | { |
344 | Standard_Real aTolV, aTolV2, d2; | |
345 | gp_Pnt aPv, aPt; | |
346 | ||
347 | BRepAdaptor_Curve aBAC(aE); | |
348 | aBAC.D0(t, aPt); | |
349 | ||
350 | aTolV=BRep_Tool::Tolerance(aV); | |
351 | aTolV2=aTolV*aTolV; | |
352 | aPv=BRep_Tool::Pnt(aV); | |
353 | d2=aPv.SquareDistance (aPt); | |
354 | if (d2 < aTolV2) { | |
355 | return Standard_True; | |
356 | } | |
357 | return Standard_False; | |
358 | } | |
359 | //======================================================================= | |
360 | //function : IsVertex | |
361 | //purpose : | |
362 | //======================================================================= | |
363 | Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE, | |
1e143abb | 364 | const Standard_Real t) |
7fd59977 | 365 | { |
366 | Standard_Real aTolV, aTolV2, d2; | |
367 | TopoDS_Vertex aV; | |
368 | gp_Pnt aPv, aPt; | |
369 | ||
370 | BRepAdaptor_Curve aBAC(aE); | |
371 | aBAC.D0(t, aPt); | |
372 | ||
373 | TopExp_Explorer anExp(aE, TopAbs_VERTEX); | |
374 | for (; anExp.More(); anExp.Next()) { | |
375 | aV=TopoDS::Vertex (anExp.Current()); | |
376 | aTolV=BRep_Tool::Tolerance(aV); | |
377 | aTolV2=aTolV*aTolV; | |
378 | aTolV2=1.e-12; | |
379 | aPv=BRep_Tool::Pnt(aV); | |
380 | d2=aPv.SquareDistance (aPt); | |
381 | if (d2 < aTolV2) { | |
382 | return Standard_True; | |
383 | } | |
384 | } | |
385 | return Standard_False; | |
386 | } | |
387 | ||
388 | ||
389 | //======================================================================= | |
390 | //function : ComputeVV | |
391 | //purpose : | |
392 | //======================================================================= | |
393 | Standard_Integer IntTools_Tools::ComputeVV(const TopoDS_Vertex& aV1, | |
1e143abb | 394 | const TopoDS_Vertex& aV2) |
7fd59977 | 395 | { |
396 | Standard_Real aTolV1, aTolV2, aTolSum, d; | |
397 | gp_Pnt aP1, aP2; | |
398 | ||
399 | aTolV1=BRep_Tool::Tolerance(aV1); | |
400 | aTolV2=BRep_Tool::Tolerance(aV2); | |
401 | aTolSum=aTolV1+aTolV2; | |
cf8e963a | 402 | |
7fd59977 | 403 | aP1=BRep_Tool::Pnt(aV1); |
404 | aP2=BRep_Tool::Pnt(aV2); | |
cf8e963a | 405 | aTolSum=aTolSum*aTolSum; |
406 | d=aP1.SquareDistance(aP2); | |
7fd59977 | 407 | if (d<aTolSum) { |
408 | return 0; | |
409 | } | |
410 | return -1; | |
411 | } | |
412 | ||
413 | //======================================================================= | |
414 | //function : MakeFaceFromWireAndFace | |
415 | //purpose : | |
416 | //======================================================================= | |
417 | void IntTools_Tools::MakeFaceFromWireAndFace(const TopoDS_Wire& aW, | |
1e143abb | 418 | const TopoDS_Face& aF, |
419 | TopoDS_Face& aFNew) | |
7fd59977 | 420 | { |
421 | TopoDS_Face aFF; | |
422 | aFF=aF; | |
423 | aFF.Orientation(TopAbs_FORWARD); | |
424 | aFNew=TopoDS::Face (aFF.EmptyCopied()); | |
425 | BRep_Builder BB; | |
426 | BB.Add(aFNew, aW); | |
427 | } | |
428 | ||
429 | //======================================================================= | |
430 | //function : ClassifyPointByFace | |
431 | //purpose : | |
432 | //======================================================================= | |
433 | TopAbs_State IntTools_Tools::ClassifyPointByFace(const TopoDS_Face& aF, | |
1e143abb | 434 | const gp_Pnt2d& aP2d) |
7fd59977 | 435 | { |
436 | Standard_Real aFaceTolerance; | |
437 | TopAbs_State aState; | |
438 | ||
439 | aFaceTolerance=BRep_Tool::Tolerance(aF); | |
440 | IntTools_FClass2d aClass2d(aF, aFaceTolerance); | |
441 | aState=aClass2d.Perform(aP2d); | |
442 | ||
443 | return aState; | |
444 | } | |
445 | ||
446 | //======================================================================= | |
447 | //function : IsMiddlePointsEqual | |
448 | //purpose : | |
449 | //======================================================================= | |
450 | Standard_Boolean IntTools_Tools::IsMiddlePointsEqual(const TopoDS_Edge& aE1, | |
1e143abb | 451 | const TopoDS_Edge& aE2) |
452 | ||
7fd59977 | 453 | { |
cf8e963a | 454 | Standard_Boolean bRet; |
455 | Standard_Real f1, l1, m1, f2, l2, m2, aTol1, aTol2, aSumTol, aD2; | |
7fd59977 | 456 | gp_Pnt aP1, aP2; |
457 | ||
458 | aTol1=BRep_Tool::Tolerance(aE1); | |
459 | Handle(Geom_Curve) C1=BRep_Tool::Curve(aE1, f1, l1); | |
460 | m1=0.5*(f1+l1); | |
461 | C1->D0(m1, aP1); | |
462 | ||
463 | aTol2=BRep_Tool::Tolerance(aE2); | |
464 | Handle(Geom_Curve) C2=BRep_Tool::Curve(aE2, f2, l2); | |
465 | m2=0.5*(f2+l2); | |
466 | C2->D0(m2, aP2); | |
467 | ||
468 | aSumTol=aTol1+aTol2; | |
cf8e963a | 469 | aSumTol=aSumTol*aSumTol; |
470 | aD2=aP1.SquareDistance(aP2); | |
471 | bRet=aD2<aSumTol; | |
472 | return bRet; | |
7fd59977 | 473 | } |
474 | ||
475 | //======================================================================= | |
476 | //function : CurveTolerance | |
477 | //purpose : | |
478 | //======================================================================= | |
479 | Standard_Real IntTools_Tools::CurveTolerance(const Handle(Geom_Curve)& aC3D, | |
1e143abb | 480 | const Standard_Real aTolBase) |
7fd59977 | 481 | { |
482 | Standard_Real aTolReached, aTf, aTl, aTolMin, aTolMax; | |
483 | ||
484 | aTolReached=aTolBase; | |
485 | // | |
486 | if (aC3D.IsNull()) { | |
487 | return aTolReached; | |
488 | } | |
489 | // | |
490 | Handle(Geom_TrimmedCurve) aCT3D=Handle(Geom_TrimmedCurve)::DownCast(aC3D); | |
491 | if (aCT3D.IsNull()) { | |
492 | return aTolReached; | |
493 | } | |
494 | // | |
495 | aTolMin=aTolBase; | |
496 | aTolMax=aTolBase; | |
497 | // | |
498 | aTf=aCT3D->FirstParameter(); | |
499 | aTl=aCT3D->LastParameter(); | |
500 | // | |
501 | GeomAdaptor_Curve aGAC(aCT3D); | |
502 | GeomAbs_CurveType aCType=aGAC.GetType(); | |
503 | // | |
504 | if (aCType==GeomAbs_Parabola) { | |
505 | Handle(Geom_Curve) aC3DBase=aCT3D->BasisCurve(); | |
506 | ParabolaTolerance(aC3DBase, aTf, aTl, aTolBase, aTolMin, aTolMax); | |
507 | aTolReached=aTolMax; | |
508 | } | |
509 | // | |
510 | return aTolReached; | |
511 | } | |
512 | ||
513 | #include <Geom_Parabola.hxx> | |
514 | #include <gp_Parab.hxx> | |
1e143abb | 515 | #include <BndLib_Add3dCurve.hxx> |
1b7ae951 | 516 | #include <BRepLib_CheckCurveOnSurface.hxx> |
7fd59977 | 517 | //======================================================================= |
518 | //function : ParabolaTolerance | |
519 | //purpose : | |
520 | //======================================================================= | |
521 | void ParabolaTolerance(const Handle(Geom_Curve)& aC3D, | |
1e143abb | 522 | const Standard_Real aTf, |
523 | const Standard_Real aTl, | |
524 | const Standard_Real aTol, | |
525 | Standard_Real& aTolMin, | |
526 | Standard_Real& aTolMax) | |
7fd59977 | 527 | { |
528 | ||
529 | aTolMin=aTol; | |
530 | aTolMax=aTol; | |
531 | ||
532 | Handle(Geom_Parabola) aGP=Handle(Geom_Parabola)::DownCast(aC3D); | |
533 | if (aGP.IsNull()){ | |
534 | return; | |
535 | } | |
536 | ||
537 | Standard_Integer aNbPoints; | |
538 | Standard_Real aFocal, aX1, aX2, aTol1, aTol2; | |
539 | gp_Pnt aPf, aPl; | |
540 | gp_Parab aParab=aGP->Parab(); | |
541 | gp_Ax1 aXAxis=aParab.XAxis(); | |
542 | Handle(Geom_Line) aGAxis=new Geom_Line(aXAxis); | |
543 | ||
544 | aFocal=aGP->Focal(); | |
545 | if (aFocal==0.) { | |
546 | return; | |
547 | } | |
548 | // | |
549 | // aTol1 | |
550 | aTol1=aTol; | |
551 | aX1=0.; | |
552 | aGP->D0(aTf, aPf); | |
553 | GeomAPI_ProjectPointOnCurve aProj1(aPf, aGAxis); | |
554 | aNbPoints=aProj1.NbPoints(); | |
555 | if (aNbPoints) { | |
556 | aX1=aProj1.LowerDistanceParameter(); | |
557 | } | |
558 | if (aX1>=0.) { | |
559 | aTol1=aTol*sqrt(0.5*aX1/aFocal); | |
560 | } | |
561 | if (aTol1==0.) { | |
562 | aTol1=aTol; | |
563 | } | |
564 | // | |
565 | // aTol2 | |
566 | aTol2=aTol; | |
567 | aX2=0.; | |
568 | aGP->D0(aTl, aPl); | |
569 | GeomAPI_ProjectPointOnCurve aProj2(aPl, aGAxis); | |
570 | aNbPoints=aProj2.NbPoints(); | |
571 | if (aNbPoints) { | |
572 | aX2=aProj2.LowerDistanceParameter(); | |
573 | } | |
574 | ||
575 | if (aX2>=0.) { | |
576 | aTol2=aTol*sqrt(0.5*aX2/aFocal); | |
577 | } | |
578 | if (aTol2==0.) { | |
579 | aTol2=aTol; | |
580 | } | |
581 | // | |
582 | aTolMax=(aTol1>aTol2) ? aTol1 : aTol2; | |
583 | aTolMin=(aTol1<aTol2) ? aTol1 : aTol2; | |
584 | } | |
1e143abb | 585 | ///////////////////////////////////////////////////////////////////////// |
586 | //======================================================================= | |
587 | //function : CheckCurve | |
588 | //purpose : | |
589 | //======================================================================= | |
5652dc62 | 590 | Standard_Boolean IntTools_Tools::CheckCurve(const IntTools_Curve& theCurve, |
591 | Bnd_Box& theBox) | |
1e143abb | 592 | { |
5652dc62 | 593 | const Handle(Geom_Curve)& aC3D = theCurve.Curve(); |
594 | Standard_Boolean bValid = !aC3D.IsNull(); | |
595 | if (!bValid) { | |
596 | return bValid; | |
597 | } | |
1e143abb | 598 | // |
5652dc62 | 599 | // Build bounding box for the curve |
600 | BndLib_Add3dCurve::Add(GeomAdaptor_Curve(aC3D), | |
601 | Max(theCurve.Tolerance(), theCurve.TangentialTolerance()), | |
602 | theBox); | |
1e143abb | 603 | // |
5652dc62 | 604 | // Estimate the bounding box of the curve comparing it with the |
605 | // minimal length for the curve from which the valid edge can be built - | |
606 | // 3*Precision::Confusion(): | |
607 | // - 2 vertices with the Precision::Confusion() tolerance; | |
608 | // - plus Precision::Confusion() as the minimal distance between vertices. | |
609 | Standard_Real aTolCmp = 3*Precision::Confusion(); | |
610 | // | |
611 | // Check the size of the box using the Bnd_Box::IsThin() method | |
612 | // which does not use the gap of the box. | |
613 | bValid = !theBox.IsThin(aTolCmp); | |
614 | // | |
615 | return bValid; | |
1e143abb | 616 | } |
617 | //======================================================================= | |
618 | //function : IsOnPave | |
619 | //purpose : | |
620 | //======================================================================= | |
621 | Standard_Boolean IntTools_Tools::IsOnPave(const Standard_Real aT1, | |
622 | const IntTools_Range& aRange, | |
623 | const Standard_Real aTolerance) | |
624 | { | |
625 | Standard_Boolean firstisonpave1, firstisonpave2, bIsOnPave; | |
626 | // | |
627 | firstisonpave1 = (Abs(aRange.First() - aT1) < aTolerance); | |
628 | firstisonpave2 = (Abs(aRange.Last() - aT1) < aTolerance); | |
629 | bIsOnPave=(firstisonpave1 || firstisonpave2); | |
630 | return bIsOnPave; | |
631 | } | |
632 | //======================================================================= | |
633 | // function: VertexParameters | |
634 | // purpose: | |
635 | //======================================================================= | |
636 | void IntTools_Tools::VertexParameters(const IntTools_CommonPrt& aCPart, | |
637 | Standard_Real& aT1, | |
638 | Standard_Real& aT2) | |
639 | { | |
640 | const IntTools_Range& aR1=aCPart.Range1(); | |
641 | aT1=0.5*(aR1.First()+aR1.Last()); | |
642 | // | |
643 | if((aCPart.VertexParameter1() >= aR1.First()) && | |
644 | (aCPart.VertexParameter1() <= aR1.Last())) { | |
645 | aT1 = aCPart.VertexParameter1(); | |
646 | } | |
647 | // | |
648 | const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2(); | |
649 | const IntTools_Range& aR2=aRanges2(1); | |
650 | aT2=0.5*(aR2.First()+aR2.Last()); | |
651 | // | |
652 | if((aCPart.VertexParameter2() >= aR2.First()) && | |
653 | (aCPart.VertexParameter2() <= aR2.Last())) { | |
654 | aT2 = aCPart.VertexParameter2(); | |
655 | } | |
656 | } | |
657 | //======================================================================= | |
658 | // function: VertexParameter | |
659 | // purpose: | |
660 | //======================================================================= | |
661 | void IntTools_Tools::VertexParameter(const IntTools_CommonPrt& aCPart, | |
662 | Standard_Real& aT) | |
663 | { | |
664 | const IntTools_Range& aR=aCPart.Range1(); | |
665 | aT=0.5*(aR.First()+aR.Last()); | |
666 | if((aCPart.VertexParameter1() >= aR.First()) && | |
667 | (aCPart.VertexParameter1() <= aR.Last())) { | |
668 | aT = aCPart.VertexParameter1(); | |
669 | } | |
670 | } | |
671 | //======================================================================= | |
672 | // function: IsOnPave1 | |
673 | // purpose: | |
674 | //======================================================================= | |
675 | Standard_Boolean IntTools_Tools::IsOnPave1(const Standard_Real aTR, | |
676 | const IntTools_Range& aCPRange, | |
677 | const Standard_Real aTolerance) | |
678 | { | |
679 | Standard_Boolean bIsOnPave; | |
680 | Standard_Real aT1, aT2, dT1, dT2; | |
681 | // | |
682 | aT1=aCPRange.First(); | |
683 | aT2=aCPRange.Last(); | |
3510db62 | 684 | bIsOnPave=(aTR>=aT1 && aTR<=aT2); |
1e143abb | 685 | if (bIsOnPave) { |
686 | return bIsOnPave; | |
687 | } | |
688 | // | |
689 | dT1=Abs(aTR-aT1); | |
690 | dT2=Abs(aTR-aT2); | |
691 | bIsOnPave=(dT1<=aTolerance || dT2<=aTolerance); | |
692 | return bIsOnPave; | |
693 | } | |
694 | //======================================================================= | |
695 | // function: IsInRange | |
696 | // purpose: | |
697 | //======================================================================= | |
698 | Standard_Boolean IntTools_Tools::IsInRange(const IntTools_Range& aRRef, | |
699 | const IntTools_Range& aR, | |
700 | const Standard_Real aTolerance) | |
701 | { | |
702 | Standard_Boolean bIsIn; | |
703 | Standard_Real aT1, aT2, aTRef1, aTRef2; | |
704 | // | |
705 | aR.Range(aT1, aT2); | |
706 | aRRef.Range(aTRef1, aTRef2); | |
707 | // | |
708 | aTRef1-=aTolerance; | |
709 | aTRef2+=aTolerance; | |
710 | // | |
711 | bIsIn = (aT1>=aTRef1 && aT1<=aTRef2) || | |
712 | (aT2>=aTRef1 && aT2<=aTRef2); | |
713 | // | |
714 | return bIsIn; | |
715 | } | |
716 | //======================================================================= | |
717 | //function : SegPln | |
718 | //purpose : | |
719 | //======================================================================= | |
720 | Standard_Integer IntTools_Tools::SegPln(const gp_Lin& theLin, | |
721 | const Standard_Real theTLin1, | |
722 | const Standard_Real theTLin2, | |
723 | const Standard_Real theTolLin, | |
724 | const gp_Pln& thePln, | |
725 | const Standard_Real theTolPln, | |
726 | gp_Pnt& theP, | |
727 | Standard_Real& theTP, | |
728 | Standard_Real& theTolP, | |
729 | Standard_Real& theTPmin, | |
730 | Standard_Real& theTPmax) | |
731 | { | |
732 | Standard_Integer iRet; | |
733 | Standard_Real aTol, aA, aB, aC, aD, aE, aH, aTP, aDist1, aDist2; | |
734 | gp_Pnt aP1, aP2; | |
735 | // | |
736 | iRet=0; | |
737 | aTol=theTolLin+theTolPln; | |
738 | // | |
739 | const gp_Ax3& aPosPln=thePln.Position(); | |
740 | const gp_Dir& aDirPln=aPosPln.Direction(); | |
741 | const gp_Pnt& aLocPln=aPosPln.Location(); | |
742 | // | |
743 | const gp_Dir& aDirLin=theLin.Direction(); | |
744 | const gp_Pnt& aLocLin=theLin.Location(); | |
745 | // | |
746 | aP1.SetXYZ(aLocLin.XYZ()+theTLin1*aDirLin.XYZ()); | |
747 | aDist1=aDirPln.X()*(aP1.X()-aLocPln.X())+ | |
748 | aDirPln.Y()*(aP1.Y()-aLocPln.Y())+ | |
749 | aDirPln.Z()*(aP1.Z()-aLocPln.Z()); | |
750 | // | |
751 | aP2.SetXYZ(aLocLin.XYZ()+theTLin2*aDirLin.XYZ()); | |
752 | aDist2=aDirPln.X()*(aP2.X()-aLocPln.X())+ | |
753 | aDirPln.Y()*(aP2.Y()-aLocPln.Y())+ | |
754 | aDirPln.Z()*(aP2.Z()-aLocPln.Z()); | |
755 | // | |
756 | if (aDist1<aTol && aDist2<aTol){ | |
757 | iRet=1; // common block | |
758 | return iRet; | |
759 | } | |
760 | // | |
761 | if (aDist1*aDist2 > 0.) { | |
762 | iRet=2; // segment lays on one side to the Plane | |
763 | return iRet; | |
764 | } | |
765 | // | |
766 | thePln.Coefficients(aA, aB, aC, aD); | |
767 | aE=aA*aLocLin.X()+aB*aLocLin.Y()+aC*aLocLin.Z()+aD; | |
768 | aH=aA*aDirLin.X()+aB*aDirLin.Y()+aC*aDirLin.Z(); | |
769 | aTP=-aE/aH; | |
770 | if (aTP < theTLin1-aTol || aTP > theTLin2+aTol) { | |
771 | iRet=3; // no intersections due to range of the Line | |
772 | return iRet; | |
773 | } | |
774 | // | |
775 | theTP=aTP; | |
776 | theP.SetXYZ(aLocLin.XYZ()+aTP*aDirLin.XYZ()); | |
777 | theTolP=aTol; | |
778 | theTPmin=theTP-theTolPln; | |
779 | theTPmax=theTP+theTolPln; | |
780 | iRet=0; // intersection point | |
781 | return iRet; | |
782 | } | |
1b7ae951 | 783 | |
784 | //======================================================================= | |
785 | // Function : ComputeTolerance | |
786 | // purpose : | |
787 | //======================================================================= | |
788 | Standard_Boolean IntTools_Tools::ComputeTolerance | |
789 | (const Handle(Geom_Curve)& theCurve3D, | |
790 | const Handle(Geom2d_Curve)& theCurve2D, | |
791 | const Handle(Geom_Surface)& theSurf, | |
792 | const Standard_Real theFirst, | |
793 | const Standard_Real theLast, | |
794 | Standard_Real& theMaxDist, | |
6ca1c746 | 795 | Standard_Real& theMaxPar, |
3738565a | 796 | const Standard_Real theTolRange, |
797 | const Standard_Boolean theToRunParallel) | |
1b7ae951 | 798 | { |
5adae760 | 799 | GeomLib_CheckCurveOnSurface aCS; |
1b7ae951 | 800 | // |
9ae88397 | 801 | const Handle(Adaptor3d_Curve) aGeomAdaptorCurve = new GeomAdaptor_Curve(theCurve3D, theFirst, theLast); |
802 | ||
803 | Handle(Adaptor2d_Curve2d) aGeom2dAdaptorCurve = new Geom2dAdaptor_Curve(theCurve2D, theFirst, theLast); | |
804 | Handle(GeomAdaptor_Surface) aGeomAdaptorSurface = new GeomAdaptor_Surface(theSurf); | |
805 | ||
806 | Handle(Adaptor3d_CurveOnSurface) anAdaptor3dCurveOnSurface = | |
807 | new Adaptor3d_CurveOnSurface(aGeom2dAdaptorCurve, aGeomAdaptorSurface); | |
808 | ||
809 | aCS.Init(aGeomAdaptorCurve, theTolRange); | |
810 | aCS.Perform(anAdaptor3dCurveOnSurface, theToRunParallel); | |
1b7ae951 | 811 | if (!aCS.IsDone()) { |
812 | return Standard_False; | |
813 | } | |
243505b8 | 814 | |
815 | //Obtaining precise result is impossible if we use | |
816 | //numeric methods for solution. Therefore, we must provide | |
817 | //some margin. Otherwise, in the future | |
818 | //(when geometrical properties of the curve will be changed, | |
819 | //e.g. after trimming) we will be able to come | |
820 | //to the more precise minimum point. As result, this curve with the | |
821 | //tolerance computed earlier will become invalid. | |
0d0481c7 | 822 | const Standard_Real anEps = (1.0+1.0e-5); |
243505b8 | 823 | theMaxDist = anEps*aCS.MaxDistance(); |
1b7ae951 | 824 | theMaxPar = aCS.MaxParameter(); |
825 | // | |
826 | return Standard_True; | |
827 | } | |
3510db62 | 828 | |
829 | //======================================================================= | |
830 | // Function : ComputeIntRange | |
831 | // purpose : | |
832 | //======================================================================= | |
833 | Standard_Real IntTools_Tools::ComputeIntRange(const Standard_Real theTol1, | |
834 | const Standard_Real theTol2, | |
835 | const Standard_Real theAngle) | |
836 | { | |
837 | Standard_Real aDt; | |
838 | // | |
839 | if (Abs(M_PI_2 - theAngle) < Precision::Angular()) { | |
840 | aDt = theTol2; | |
841 | } | |
842 | else { | |
843 | Standard_Real a1, a2, anAngle; | |
844 | // | |
845 | anAngle = (theAngle > M_PI_2) ? (M_PI - theAngle) : theAngle; | |
846 | a1 = theTol1 * tan(M_PI_2 - anAngle); | |
847 | a2 = theTol2 / sin(anAngle); | |
848 | aDt = a1 + a2; | |
849 | } | |
850 | // | |
851 | return aDt; | |
852 | } |