b311480e |
1 | // Created by: Peter KURNEV |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
d5f74e42 |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
7fd59977 |
14 | |
7fd59977 |
15 | |
42cf5bc1 |
16 | #include <BOPCol_IndexedMapOfShape.hxx> |
17 | #include <BOPTools.hxx> |
18 | #include <BOPTools_AlgoTools2D.hxx> |
19 | #include <BRep_Builder.hxx> |
20 | #include <BRep_CurveRepresentation.hxx> |
21 | #include <BRep_GCurve.hxx> |
22 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
23 | #include <BRep_TEdge.hxx> |
24 | #include <BRep_Tool.hxx> |
25 | #include <BRepAdaptor_Curve.hxx> |
26 | #include <BRepAdaptor_HSurface.hxx> |
27 | #include <BRepAdaptor_Surface.hxx> |
28 | #include <BRepClass_FaceClassifier.hxx> |
29 | #include <BRepTools.hxx> |
30 | #include <Geom2d_BSplineCurve.hxx> |
7fd59977 |
31 | #include <Geom2d_Circle.hxx> |
42cf5bc1 |
32 | #include <Geom2d_Curve.hxx> |
7fd59977 |
33 | #include <Geom2d_Ellipse.hxx> |
7fd59977 |
34 | #include <Geom2d_Hyperbola.hxx> |
42cf5bc1 |
35 | #include <Geom2d_Line.hxx> |
36 | #include <Geom2d_Parabola.hxx> |
f1baf495 |
37 | #include <Geom2d_TrimmedCurve.hxx> |
f1baf495 |
38 | #include <Geom2dAdaptor.hxx> |
7fd59977 |
39 | #include <Geom_Curve.hxx> |
f1baf495 |
40 | #include <Geom_Plane.hxx> |
42cf5bc1 |
41 | #include <Geom_RectangularTrimmedSurface.hxx> |
42 | #include <Geom_Surface.hxx> |
43 | #include <Geom_TrimmedCurve.hxx> |
f1baf495 |
44 | #include <GeomAdaptor_Curve.hxx> |
45 | #include <GeomAdaptor_HCurve.hxx> |
46 | #include <GeomAdaptor_HSurface.hxx> |
42cf5bc1 |
47 | #include <GeomAdaptor_Surface.hxx> |
48 | #include <GeomInt.hxx> |
f1baf495 |
49 | #include <GeomProjLib.hxx> |
42cf5bc1 |
50 | #include <gp.hxx> |
fc88faf1 |
51 | #include <gp_Cylinder.hxx> |
42cf5bc1 |
52 | #include <gp_Pnt.hxx> |
53 | #include <gp_Pnt2d.hxx> |
54 | #include <gp_Vec.hxx> |
55 | #include <gp_Vec2d.hxx> |
56 | #include <IntTools_Context.hxx> |
57 | #include <IntTools_Tools.hxx> |
58 | #include <Precision.hxx> |
59 | #include <ProjLib_ProjectedCurve.hxx> |
f48cb55d |
60 | #include <ProjLib.hxx> |
42cf5bc1 |
61 | #include <Standard_ConstructionError.hxx> |
62 | #include <Standard_NotImplemented.hxx> |
63 | #include <TopExp.hxx> |
fc88faf1 |
64 | #include <TopExp_Explorer.hxx> |
42cf5bc1 |
65 | #include <TopLoc_Location.hxx> |
66 | #include <TopoDS_Edge.hxx> |
67 | #include <TopoDS_Face.hxx> |
7fd59977 |
68 | |
69 | static |
f1baf495 |
70 | Standard_Boolean CheckEdgeLength (const TopoDS_Edge& ); |
71 | |
72 | static |
73 | Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& , |
74 | const TopoDS_Face& , |
75 | Standard_Real& , |
76 | Standard_Real& , |
77 | Standard_Boolean& ); |
78 | static |
79 | Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& , |
80 | const Handle(Geom_Surface)& , |
81 | const TopLoc_Location& , |
82 | Standard_Real& , |
83 | Standard_Real& , |
84 | Standard_Boolean& ); |
fc88faf1 |
85 | static |
86 | Standard_Real MaxToleranceEdge (const TopoDS_Face& ); |
7fd59977 |
87 | |
4e57c75e |
88 | //======================================================================= |
89 | //function : BuildPCurveForEdgeOnFace |
90 | //purpose : |
91 | //======================================================================= |
f1baf495 |
92 | void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE, |
51db0179 |
93 | const TopoDS_Face& aF, |
94 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
95 | { |
96 | BRep_Builder aBB; |
97 | Handle(Geom2d_Curve) aC2D; |
98 | Standard_Real aTolPC, aTolFact, aTolEdge, aFirst, aLast; |
99 | |
100 | Standard_Boolean aHasOld; |
f1baf495 |
101 | aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, aC2D, |
102 | aFirst, aLast, |
103 | aTolEdge); |
4e57c75e |
104 | if (aHasOld) { |
105 | return; |
106 | } |
107 | |
108 | |
51db0179 |
109 | BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aTolPC, theContext); |
4e57c75e |
110 | |
111 | aTolEdge=BRep_Tool::Tolerance(aE); |
112 | |
113 | aTolFact=Max(aTolEdge, aTolPC); |
114 | |
115 | aBB.UpdateEdge(aE, aC2D, aF, aTolFact); |
116 | return; |
117 | } |
118 | |
7fd59977 |
119 | //======================================================================= |
120 | //function : EdgeTangent |
121 | //purpose : |
122 | //======================================================================= |
f1baf495 |
123 | Standard_Boolean BOPTools_AlgoTools2D::EdgeTangent |
124 | (const TopoDS_Edge& anEdge, |
125 | const Standard_Real aT, |
126 | gp_Vec& aTau) |
7fd59977 |
127 | { |
128 | Standard_Boolean isdgE; |
129 | Standard_Real first, last; |
130 | |
131 | isdgE = BRep_Tool::Degenerated(anEdge); |
132 | if (isdgE) { |
133 | return Standard_False; |
134 | } |
135 | if (!CheckEdgeLength(anEdge)) { |
136 | return Standard_False; |
137 | } |
138 | |
139 | Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last); |
140 | gp_Pnt aP; |
141 | aC->D1(aT, aP, aTau); |
142 | Standard_Real mod = aTau.Magnitude(); |
143 | if(mod > gp::Resolution()) { |
144 | aTau /= mod; |
145 | } |
146 | else { |
147 | return Standard_False; |
148 | } |
149 | //aTau.Normalize(); |
150 | if (anEdge.Orientation() == TopAbs_REVERSED){ |
151 | aTau.Reverse(); |
152 | } |
153 | return Standard_True; |
154 | } |
155 | |
7fd59977 |
156 | //======================================================================= |
157 | //function : PointOnOnSurface |
158 | //purpose : |
159 | //======================================================================= |
f1baf495 |
160 | void BOPTools_AlgoTools2D::PointOnSurface (const TopoDS_Edge& aE, |
161 | const TopoDS_Face& aF, |
162 | const Standard_Real aParameter, |
163 | Standard_Real& U, |
51db0179 |
164 | Standard_Real& V, |
165 | const Handle(IntTools_Context)& theContext) |
7fd59977 |
166 | { |
167 | gp_Pnt2d aP2D; |
168 | Handle(Geom2d_Curve) aC2D; |
169 | Standard_Real aToler, aFirst, aLast; |
170 | |
51db0179 |
171 | BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler, theContext); |
7fd59977 |
172 | aC2D->D0(aParameter, aP2D); |
173 | U=aP2D.X(); |
174 | V=aP2D.Y(); |
175 | return; |
176 | } |
177 | |
178 | //======================================================================= |
179 | //function : CurveOnSurface |
180 | //purpose : |
181 | //======================================================================= |
f1baf495 |
182 | void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE, |
183 | const TopoDS_Face& aF, |
184 | Handle(Geom2d_Curve)& aC2D, |
51db0179 |
185 | Standard_Real& aToler, |
186 | const Handle(IntTools_Context)& theContext) |
7fd59977 |
187 | { |
188 | Standard_Real aFirst, aLast; |
f1baf495 |
189 | // |
51db0179 |
190 | BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aFirst, aLast, aToler, theContext); |
f1baf495 |
191 | // |
7fd59977 |
192 | return; |
193 | } |
194 | //======================================================================= |
195 | //function : CurveOnSurface |
196 | //purpose : |
197 | //======================================================================= |
f1baf495 |
198 | void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE, |
199 | const TopoDS_Face& aF, |
200 | Handle(Geom2d_Curve)& aC2D, |
201 | Standard_Real& aFirst, |
202 | Standard_Real& aLast, |
51db0179 |
203 | Standard_Real& aToler, |
204 | const Handle(IntTools_Context)& theContext) |
7fd59977 |
205 | { |
206 | Standard_Boolean aHasOld; |
207 | Handle(Geom2d_Curve) C2D; |
208 | |
f1baf495 |
209 | aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, C2D, |
210 | aFirst, aLast, |
211 | aToler); |
7fd59977 |
212 | if (aHasOld) { |
213 | aC2D=C2D; |
214 | return; |
215 | } |
216 | |
51db0179 |
217 | BOPTools_AlgoTools2D::Make2D(aE, aF, C2D, aFirst, aLast, aToler, theContext); |
7fd59977 |
218 | aC2D=C2D; |
219 | return; |
220 | } |
7fd59977 |
221 | //======================================================================= |
222 | //function : HasCurveOnSurface |
223 | //purpose : |
224 | //======================================================================= |
f1baf495 |
225 | Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface |
226 | (const TopoDS_Edge& aE, |
227 | const TopoDS_Face& aF, |
228 | Handle(Geom2d_Curve)& aC2D, |
229 | Standard_Real& aFirst, |
230 | Standard_Real& aLast, |
231 | Standard_Real& aToler) |
7fd59977 |
232 | { |
233 | Standard_Boolean aHasOld; |
234 | |
235 | aToler=BRep_Tool::Tolerance(aE); |
236 | BRep_Tool::Range(aE, aFirst, aLast); |
237 | |
238 | if((aLast - aFirst) < Precision::PConfusion()) { |
239 | return Standard_False; |
240 | } |
241 | |
f1baf495 |
242 | aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast); |
7fd59977 |
243 | aHasOld=!aC2D.IsNull(); |
244 | return aHasOld; |
245 | } |
246 | //======================================================================= |
247 | //function : HasCurveOnSurface |
248 | //purpose : |
249 | //======================================================================= |
f1baf495 |
250 | Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface |
251 | (const TopoDS_Edge& aE, |
252 | const TopoDS_Face& aF) |
7fd59977 |
253 | { |
f1baf495 |
254 | Standard_Boolean bHasOld; |
7fd59977 |
255 | Handle(Geom2d_Curve) aC2D; |
256 | Standard_Real aFirst, aLast; |
f1baf495 |
257 | // |
7fd59977 |
258 | BRep_Tool::Range(aE, aFirst, aLast); |
f1baf495 |
259 | // |
7fd59977 |
260 | if((aLast - aFirst) < Precision::PConfusion()) { |
261 | return Standard_False; |
262 | } |
f1baf495 |
263 | // |
264 | aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast); |
265 | bHasOld=!aC2D.IsNull(); |
266 | // |
267 | return bHasOld; |
7fd59977 |
268 | } |
7fd59977 |
269 | //======================================================================= |
270 | //function : AdjustPCurveOnFace |
271 | //purpose : |
272 | //======================================================================= |
51db0179 |
273 | void BOPTools_AlgoTools2D::AdjustPCurveOnFace |
274 | (const TopoDS_Face& theF, |
275 | const Handle(Geom_Curve)& theC3D, |
276 | const Handle(Geom2d_Curve)& theC2D, |
277 | Handle(Geom2d_Curve)& theC2DA, |
278 | const Handle(IntTools_Context)& theContext) |
7fd59977 |
279 | { |
51db0179 |
280 | Standard_Real aT1 = theC3D->FirstParameter(); |
281 | Standard_Real aT2 = theC3D->LastParameter(); |
fd372378 |
282 | // |
51db0179 |
283 | BOPTools_AlgoTools2D::AdjustPCurveOnFace (theF, aT1, aT2, theC2D, theC2DA, theContext); |
fd372378 |
284 | } |
7fd59977 |
285 | //======================================================================= |
286 | //function : AdjustPCurveOnFace |
287 | //purpose : |
288 | //======================================================================= |
f1baf495 |
289 | void BOPTools_AlgoTools2D::AdjustPCurveOnFace |
51db0179 |
290 | (const TopoDS_Face& theF, |
291 | const Standard_Real theFirst, |
292 | const Standard_Real theLast, |
293 | const Handle(Geom2d_Curve)& theC2D, |
294 | Handle(Geom2d_Curve)& theC2DA, |
295 | const Handle(IntTools_Context)& theContext) |
fd372378 |
296 | { |
51db0179 |
297 | BRepAdaptor_Surface aBASTmp; |
298 | const BRepAdaptor_Surface* pBAS; |
299 | if (!theContext.IsNull()) { |
300 | pBAS = &theContext->SurfaceAdaptor(theF); |
301 | } |
302 | else { |
303 | aBASTmp.Initialize(theF, Standard_True); |
304 | pBAS = &aBASTmp; |
305 | } |
fd372378 |
306 | // |
51db0179 |
307 | BOPTools_AlgoTools2D::AdjustPCurveOnSurf(*pBAS, theFirst, theLast, theC2D, theC2DA); |
fd372378 |
308 | } |
fd372378 |
309 | //======================================================================= |
310 | //function : AdjustPCurveOnFace |
311 | //purpose : |
312 | //======================================================================= |
51db0179 |
313 | void BOPTools_AlgoTools2D::AdjustPCurveOnSurf |
fd372378 |
314 | (const BRepAdaptor_Surface& aBAS, |
f1baf495 |
315 | const Standard_Real aFirst, |
316 | const Standard_Real aLast, |
51db0179 |
317 | const Handle(Geom2d_Curve)& aC2D, |
f1baf495 |
318 | Handle(Geom2d_Curve)& aC2DA) |
7fd59977 |
319 | { |
655fddc8 |
320 | Standard_Boolean mincond, maxcond; |
7fd59977 |
321 | Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta; |
655fddc8 |
322 | Standard_Real aUPeriod; |
7fd59977 |
323 | // |
fd372378 |
324 | const TopoDS_Face& aF=aBAS.Face(); |
325 | UMin=aBAS.FirstUParameter(); |
326 | UMax=aBAS.LastUParameter(); |
327 | VMin=aBAS.FirstVParameter(); |
328 | VMax=aBAS.LastVParameter(); |
329 | // |
fd372378 |
330 | aDelta=Precision::PConfusion(); |
7fd59977 |
331 | |
332 | aT =.5*(aFirst+aLast); |
333 | |
334 | gp_Pnt2d pC2D; |
335 | aC2D->D0(aT, pC2D); |
336 | |
337 | u2 = pC2D.X(); |
338 | v2 = pC2D.Y(); |
fc88faf1 |
339 | // |
340 | // du |
7fd59977 |
341 | du = 0.; |
342 | if (aBAS.IsUPeriodic()) { |
655fddc8 |
343 | aUPeriod = aBAS.UPeriod(); |
fd372378 |
344 | |
7fd59977 |
345 | // |
67e36f0c |
346 | // a. try to clarify u2 using the precision (aDelta) |
347 | if (fabs(u2-UMin) < aDelta) { |
348 | u2=UMin; |
349 | } |
350 | else if (fabs(u2-UMin-aUPeriod) < aDelta) { |
9c0b61f3 |
351 | u2=UMin+aUPeriod; |
352 | } |
67e36f0c |
353 | // b. compute du again using clarified value of u2 |
354 | GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, u2, du, 0.); |
fc88faf1 |
355 | // |
356 | if (du==0.) { |
357 | if (aBAS.GetType()==GeomAbs_Cylinder) { |
358 | Standard_Real aR, dFi, aTol; |
359 | // |
360 | gp_Cylinder aCylinder=aBAS.Cylinder(); |
361 | aR=aCylinder.Radius(); |
362 | aTol=MaxToleranceEdge(aF); |
363 | dFi=aTol/aR; |
364 | if (dFi<aDelta) { |
365 | dFi=aDelta; |
366 | } |
367 | // |
368 | mincond = (UMin - u2 > dFi); |
369 | maxcond = (u2 - UMax > dFi); |
370 | if (mincond || maxcond) { |
371 | du = ( mincond ) ? aUPeriod : -aUPeriod; |
372 | } |
373 | } |
374 | } |
655fddc8 |
375 | } |
fc88faf1 |
376 | |
7fd59977 |
377 | // dv |
378 | dv = 0.; |
379 | if (aBAS.IsVPeriodic()) { |
380 | Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr; |
381 | // |
655fddc8 |
382 | aVPeriod = aBAS.VPeriod(); |
7fd59977 |
383 | mincond = (VMin - v2 > aDelta); |
384 | maxcond = (v2 - VMax > aDelta); |
655fddc8 |
385 | // |
386 | if (mincond || maxcond) { |
7fd59977 |
387 | dv = ( mincond ) ? aVPeriod : -aVPeriod; |
388 | } |
389 | // |
7fd59977 |
390 | if ((VMax-VMin<aVPeriod) && dv) { |
391 | aVm=v2; |
392 | aVr=v2+dv; |
393 | aVmid=0.5*(VMin+VMax); |
394 | dVm=fabs(aVm-aVmid); |
395 | dVr=fabs(aVr-aVmid); |
396 | if (dVm<dVr) { |
4e57c75e |
397 | dv=0.; |
7fd59977 |
398 | } |
399 | } |
7fd59977 |
400 | } |
401 | // |
d8a24e83 |
402 | { |
403 | //check the point with classifier |
404 | Standard_Real u,v; |
405 | u = u2 + du; |
406 | v = v2 + dv; |
407 | if (aBAS.IsUPeriodic()) { |
408 | aUPeriod = aBAS.UPeriod(); |
409 | if ((UMax - UMin - 2*aDelta) > aUPeriod) { |
410 | if ((u > (UMin + aDelta + aUPeriod)) || |
411 | (u < (UMax - aDelta - aUPeriod))) { |
412 | BRepClass_FaceClassifier aClassifier; |
413 | aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta); |
414 | TopAbs_State Status = aClassifier.State(); |
415 | if (Status == TopAbs_OUT) { |
416 | du += (u > (UMin + aDelta + aUPeriod)) ? -aUPeriod : aUPeriod; |
417 | } |
418 | } |
419 | } |
420 | } |
421 | // |
422 | u = u2 + du; |
423 | if (aBAS.IsVPeriodic()) { |
424 | Standard_Real aVPeriod = aBAS.VPeriod(); |
425 | if ((VMax - VMin - 2*aDelta) > aVPeriod) { |
426 | if ((v > (VMin + aDelta + aVPeriod)) || |
427 | (v < (VMax - aDelta - aVPeriod))) { |
428 | BRepClass_FaceClassifier aClassifier; |
429 | aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta); |
430 | TopAbs_State Status = aClassifier.State(); |
431 | if (Status == TopAbs_OUT) { |
432 | dv += (v > (VMin + aDelta + aVPeriod)) ? -aVPeriod : aVPeriod; |
433 | } |
434 | } |
435 | } |
436 | } |
437 | } |
7fd59977 |
438 | // Translation if necessary |
439 | Handle(Geom2d_Curve) aC2Dx=aC2D; |
440 | |
441 | if ( du != 0. || dv != 0.) { |
442 | Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(aC2Dx->Copy()); |
443 | gp_Vec2d aV2D(du,dv); |
444 | PCT->Translate(aV2D); |
445 | aC2Dx = PCT; |
446 | } |
447 | |
448 | aC2DA=aC2Dx; |
449 | } |
450 | |
4e57c75e |
451 | //======================================================================= |
452 | //function : IntermediatePoint |
453 | //purpose : |
454 | //======================================================================= |
f1baf495 |
455 | Standard_Real BOPTools_AlgoTools2D::IntermediatePoint |
456 | (const Standard_Real aFirst, |
457 | const Standard_Real aLast) |
4e57c75e |
458 | { |
459 | //define parameter division number as 10*e^(-PI) = 0.43213918 |
460 | const Standard_Real PAR_T = 0.43213918; |
461 | Standard_Real aParm; |
462 | aParm=(1.-PAR_T)*aFirst + PAR_T*aLast; |
463 | return aParm; |
464 | } |
465 | //======================================================================= |
466 | //function : IntermediatePoint |
467 | //purpose : |
468 | //======================================================================= |
f1baf495 |
469 | Standard_Real BOPTools_AlgoTools2D::IntermediatePoint |
470 | (const TopoDS_Edge& aE) |
4e57c75e |
471 | |
472 | { |
473 | Standard_Real aT, aT1, aT2; |
474 | |
475 | Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2); |
476 | if (aC1.IsNull()) |
477 | BRep_Tool::Range(aE, aT1, aT2); |
478 | |
479 | aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2); |
480 | return aT; |
481 | } |
482 | |
483 | //======================================================================= |
484 | //function : BuildPCurveForEdgeOnPlane |
485 | //purpose : |
486 | //======================================================================= |
f1baf495 |
487 | void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane |
488 | (const TopoDS_Edge& aE, |
489 | const TopoDS_Face& aF) |
490 | { |
491 | Standard_Boolean bToUpdate; |
492 | Standard_Real aTolE, aT1, aT2; |
4e57c75e |
493 | Handle(Geom2d_Curve) aC2D; |
4e57c75e |
494 | BRep_Builder aBB; |
495 | // |
f1baf495 |
496 | aC2D=BRep_Tool_CurveOnSurface(aE, aF, aT1, aT2, bToUpdate); |
497 | if (bToUpdate) { |
498 | aTolE=BRep_Tool::Tolerance(aE); |
499 | aBB.UpdateEdge(aE, aC2D, aF, aTolE); |
4e57c75e |
500 | } |
4e57c75e |
501 | } |
2078dfc7 |
502 | |
503 | //======================================================================= |
504 | //function : BuildPCurveForEdgeOnPlane |
505 | //purpose : |
506 | //======================================================================= |
507 | void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane |
508 | (const TopoDS_Edge& aE, |
509 | const TopoDS_Face& aF, |
510 | Handle(Geom2d_Curve)& aC2D, |
511 | Standard_Boolean& bToUpdate) |
512 | { |
513 | Standard_Real aT1, aT2; |
514 | aC2D=BRep_Tool_CurveOnSurface(aE, aF, aT1, aT2, bToUpdate); |
515 | } |
516 | |
acccace3 |
517 | //======================================================================= |
518 | // function: BuildPCurveForEdgesOnPlane |
519 | // purpose: |
520 | //======================================================================= |
521 | void BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane |
f1baf495 |
522 | (const BOPCol_ListOfShape& aLE, |
523 | const TopoDS_Face& aF) |
acccace3 |
524 | { |
acccace3 |
525 | BOPCol_ListIteratorOfListOfShape aIt; |
acccace3 |
526 | // |
f1baf495 |
527 | aIt.Initialize(aLE); |
acccace3 |
528 | for(; aIt.More(); aIt.Next()) { |
529 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value()); |
f1baf495 |
530 | BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (aE, aF); |
acccace3 |
531 | } |
532 | } |
4e57c75e |
533 | //======================================================================= |
534 | //function : Make2D |
535 | //purpose : |
536 | //======================================================================= |
acccace3 |
537 | void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE, |
f1baf495 |
538 | const TopoDS_Face& aF, |
539 | Handle(Geom2d_Curve)& aC2D, |
540 | Standard_Real& aFirst, |
541 | Standard_Real& aLast, |
51db0179 |
542 | Standard_Real& aToler, |
543 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
544 | { |
545 | Standard_Boolean aLocIdentity; |
546 | Standard_Real f3d, l3d; |
547 | TopLoc_Location aLoc; |
548 | |
549 | Handle(Geom2d_Curve) C2D; |
550 | |
551 | |
552 | C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast); |
553 | |
554 | if (!C2D.IsNull()) { |
555 | aC2D=C2D; |
556 | return; |
557 | } |
558 | |
559 | Handle(Geom_Curve) C3D2, C3D; |
560 | C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d); |
561 | // |
562 | if (C3D.IsNull()) { |
563 | // aE has no 3D curve, so nothing is done |
564 | } |
565 | // |
566 | aLocIdentity=aLoc.IsIdentity(); |
567 | |
568 | if (aLocIdentity) { |
569 | C3D2 = C3D; |
570 | } |
571 | else { |
572 | C3D2 = Handle(Geom_Curve):: |
573 | DownCast(C3D->Transformed(aLoc.Transformation())); |
574 | } |
575 | |
576 | // |
ee5ee7db |
577 | aToler = BRep_Tool::Tolerance(aE); |
51db0179 |
578 | BOPTools_AlgoTools2D::MakePCurveOnFace(aF, C3D2, f3d, l3d, aC2D, aToler, theContext); |
4e57c75e |
579 | // |
580 | aFirst = f3d; |
581 | aLast = l3d; |
582 | } |
583 | |
584 | //======================================================================= |
585 | //function : MakePCurveOnFace |
586 | //purpose : |
587 | //======================================================================= |
f1baf495 |
588 | void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF, |
589 | const Handle(Geom_Curve)& aC3D, |
590 | Handle(Geom2d_Curve)& aC2D, //-> |
51db0179 |
591 | Standard_Real& TolReached2d, |
592 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
593 | { |
594 | Standard_Real aFirst, aLast; |
595 | |
596 | aFirst = aC3D -> FirstParameter(); |
597 | aLast = aC3D -> LastParameter(); |
598 | // |
599 | TolReached2d=0.; |
600 | // |
51db0179 |
601 | BOPTools_AlgoTools2D::MakePCurveOnFace |
602 | (aF, aC3D, aFirst, aLast, aC2D, TolReached2d, theContext); |
4e57c75e |
603 | } |
604 | |
605 | //======================================================================= |
606 | //function : MakePCurveOnFace |
607 | //purpose : |
608 | //======================================================================= |
51db0179 |
609 | void BOPTools_AlgoTools2D::MakePCurveOnFace |
f1baf495 |
610 | (const TopoDS_Face& aF, |
611 | const Handle(Geom_Curve)& aC3D, |
fd372378 |
612 | const Standard_Real aT1, |
613 | const Standard_Real aT2, |
51db0179 |
614 | Handle(Geom2d_Curve)& aC2D, |
615 | Standard_Real& TolReached2d, |
616 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
617 | { |
51db0179 |
618 | BRepAdaptor_Surface aBASTmp; |
619 | const BRepAdaptor_Surface* pBAS; |
620 | if (!theContext.IsNull()) { |
621 | pBAS = &theContext->SurfaceAdaptor(aF); |
622 | } |
623 | else { |
624 | aBASTmp.Initialize(aF, Standard_True); |
625 | pBAS = &aBASTmp; |
626 | } |
fd372378 |
627 | // |
51db0179 |
628 | Handle(BRepAdaptor_HSurface) aBAHS = new BRepAdaptor_HSurface(*pBAS); |
629 | Handle(GeomAdaptor_HCurve) aBAHC = new GeomAdaptor_HCurve(aC3D, aT1, aT2); |
f2843558 |
630 | // |
51db0179 |
631 | Standard_Real aTolR; |
f998596a |
632 | Standard_Real aTR = Precision::Confusion();//1.e-7; |
633 | Standard_Real aMaxTol = 1.e3 * aTR; //0.0001 |
634 | Standard_Boolean isAnaSurf = ProjLib::IsAnaSurf(aBAHS); |
635 | |
4e57c75e |
636 | //when the type of surface is GeomAbs_SurfaceOfRevolution |
f998596a |
637 | if (pBAS->GetType() == GeomAbs_SurfaceOfRevolution) |
638 | { |
fd372378 |
639 | if (TolReached2d > aTR) { |
640 | aTR=TolReached2d; |
641 | } |
642 | // |
4e57c75e |
643 | ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR); |
f48cb55d |
644 | ProjLib::MakePCurveOfType(aProj1, aC2D); |
4e57c75e |
645 | aTolR = aProj1.GetTolerance(); |
fd372378 |
646 | } |
f998596a |
647 | else |
648 | { |
649 | ProjLib_ProjectedCurve aProjCurv(aBAHS); |
650 | Standard_Integer aDegMin = -1, aDegMax = -1, aMaxSegments = -1; |
651 | Standard_Real aMaxDist = -1; |
652 | AppParCurves_Constraint aBndPnt = AppParCurves_TangencyPoint; |
653 | if ((TolReached2d >= 10. * aTR) && (TolReached2d <= aMaxTol || isAnaSurf)) |
654 | { |
655 | aTR = Min(aMaxTol, 0.1*TolReached2d); |
656 | aMaxSegments = 100; |
657 | aMaxDist = 1.e3*TolReached2d; |
47a27171 |
658 | if(!isAnaSurf || TolReached2d > 1.) |
f998596a |
659 | { |
660 | aBndPnt = AppParCurves_PassPoint; |
661 | } |
662 | } |
663 | else if(TolReached2d > aMaxTol) |
664 | { |
665 | aTR = Min(TolReached2d, 1.e3 * aMaxTol); |
666 | aMaxDist = 1.e2 * aTR; |
667 | aMaxSegments = 100; |
668 | } |
669 | aProjCurv.Load(aTR); |
670 | aProjCurv.SetDegree(aDegMin, aDegMax); |
671 | aProjCurv.SetMaxSegments(aMaxSegments); |
672 | aProjCurv.SetBndPnt(aBndPnt); |
673 | aProjCurv.SetMaxDist(aMaxDist); |
674 | aProjCurv.Perform(aBAHC); |
f48cb55d |
675 | ProjLib::MakePCurveOfType(aProjCurv, aC2D); |
4e57c75e |
676 | aTolR=aProjCurv.GetTolerance(); |
677 | } |
678 | // |
f998596a |
679 | if (aC2D.IsNull() && (aTR < aMaxTol || aTR < TolReached2d)) |
680 | { |
681 | aTR = Max(TolReached2d, aMaxTol); |
682 | ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, aTR);// 2 |
f48cb55d |
683 | ProjLib::MakePCurveOfType(aProjCurvAgain, aC2D); |
4e57c75e |
684 | aTolR = aProjCurvAgain.GetTolerance(); |
4e57c75e |
685 | } |
b9a7d225 |
686 | // |
687 | if(aC2D.IsNull()) |
688 | { |
9775fa61 |
689 | throw Standard_ConstructionError("BOPTools_AlgoTools2D::MakePCurveOnFace : PCurve is Null"); |
b9a7d225 |
690 | } |
691 | // |
4e57c75e |
692 | TolReached2d=aTolR; |
51db0179 |
693 | // |
694 | Handle(Geom2d_Curve) aC2DA; |
695 | BOPTools_AlgoTools2D::AdjustPCurveOnSurf (*pBAS, aT1, aT2, aC2D, aC2DA); |
fd372378 |
696 | // |
4e57c75e |
697 | aC2D=aC2DA; |
1b7ae951 |
698 | // |
699 | // compute the appropriate tolerance for the edge |
51db0179 |
700 | Handle(Geom_Surface) aS = pBAS->Surface().Surface(); |
701 | aS = Handle(Geom_Surface)::DownCast(aS->Transformed(pBAS->Trsf())); |
702 | // |
703 | Standard_Real aT; |
1b7ae951 |
704 | if (IntTools_Tools::ComputeTolerance |
fd372378 |
705 | (aC3D, aC2D, aS, aT1, aT2, aTolR, aT)) { |
1b7ae951 |
706 | if (aTolR > TolReached2d) { |
707 | TolReached2d = aTolR; |
708 | } |
709 | } |
4e57c75e |
710 | } |
7fd59977 |
711 | |
4e57c75e |
712 | //======================================================================= |
713 | //function : CheckEdgeLength |
714 | //purpose : |
715 | //======================================================================= |
716 | Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E) |
717 | { |
718 | BRepAdaptor_Curve BC(E); |
719 | |
720 | BOPCol_IndexedMapOfShape aM; |
721 | BOPTools::MapShapes(E, TopAbs_VERTEX, aM); |
722 | Standard_Integer i, anExtent, aN=10; |
723 | Standard_Real ln=0., d, t, f, l, dt; |
724 | anExtent=aM.Extent(); |
725 | |
726 | if (anExtent!=1) |
727 | return Standard_True; |
728 | |
729 | gp_Pnt p1, p2; |
730 | f = BC.FirstParameter(); |
731 | l = BC.LastParameter(); |
732 | dt=(l-f)/aN; |
733 | |
734 | BC.D0(f, p1); |
735 | for (i=1; i<=aN; i++) { |
736 | t=f+i*dt; |
737 | |
738 | if (i==aN) |
739 | BC.D0(l, p2); |
740 | else |
741 | BC.D0(t, p2); |
742 | |
743 | d=p1.Distance(p2); |
744 | ln+=d; |
745 | p1=p2; |
746 | } |
f1baf495 |
747 | // |
4e57c75e |
748 | return (ln > Precision::Confusion()); |
749 | } |
4e57c75e |
750 | //======================================================================= |
f1baf495 |
751 | //function : BRep_Tool_CurveOnSurface |
4e57c75e |
752 | //purpose : |
753 | //======================================================================= |
f1baf495 |
754 | Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& E, |
755 | const TopoDS_Face& F, |
756 | Standard_Real& First, |
757 | Standard_Real& Last, |
758 | Standard_Boolean& bToUpdate) |
4e57c75e |
759 | { |
f1baf495 |
760 | TopLoc_Location l; |
761 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l); |
762 | TopoDS_Edge aLocalEdge = E; |
763 | if (F.Orientation() == TopAbs_REVERSED) { |
764 | aLocalEdge.Reverse(); |
4e57c75e |
765 | } |
f1baf495 |
766 | // |
767 | return BRep_Tool_CurveOnSurface(aLocalEdge,S,l,First,Last,bToUpdate); |
4e57c75e |
768 | } |
7fd59977 |
769 | //======================================================================= |
f1baf495 |
770 | //function : BRep_Tool_CurveOnSurface |
7fd59977 |
771 | //purpose : |
772 | //======================================================================= |
f1baf495 |
773 | Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface |
774 | (const TopoDS_Edge& E, |
775 | const Handle(Geom_Surface)& S, |
776 | const TopLoc_Location& L, |
777 | Standard_Real& First, |
778 | Standard_Real& Last, |
779 | Standard_Boolean& bToUpdate) |
7fd59977 |
780 | { |
f1baf495 |
781 | static const Handle(Geom2d_Curve) nullPCurve; |
782 | bToUpdate=Standard_False; |
783 | TopLoc_Location loc = L.Predivided(E.Location()); |
784 | Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED); |
785 | |
786 | // find the representation |
787 | BRep_ListIteratorOfListOfCurveRepresentation itcr |
788 | ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves()); |
789 | |
790 | while (itcr.More()) { |
791 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
792 | if (cr->IsCurveOnSurface(S,loc)) { |
c5f3a425 |
793 | Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr)); |
f1baf495 |
794 | GC->Range(First,Last); |
795 | if (GC->IsCurveOnClosedSurface() && Eisreversed) |
796 | return GC->PCurve2(); |
797 | else |
798 | return GC->PCurve(); |
799 | } |
800 | itcr.Next(); |
7fd59977 |
801 | } |
802 | |
f1baf495 |
803 | // for planar surface and 3d curve try a projection |
804 | // modif 21-05-97 : for RectangularTrimmedSurface, try a projection |
805 | Handle(Geom_Plane) GP; |
806 | Handle(Geom_RectangularTrimmedSurface) GRTS; |
807 | GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S); |
808 | if(!GRTS.IsNull()) |
809 | GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface()); |
810 | else |
811 | GP = Handle(Geom_Plane)::DownCast(S); |
812 | //fin modif du 21-05-97 |
7fd59977 |
813 | |
f1baf495 |
814 | if (!GP.IsNull()) { |
7fd59977 |
815 | |
f1baf495 |
816 | Handle(GeomAdaptor_HCurve) HC; |
817 | Handle(GeomAdaptor_HSurface) HS; |
7fd59977 |
818 | |
f1baf495 |
819 | HC = new GeomAdaptor_HCurve(); |
820 | HS = new GeomAdaptor_HSurface(); |
7fd59977 |
821 | |
f1baf495 |
822 | TopLoc_Location LC; |
7fd59977 |
823 | |
f1baf495 |
824 | Standard_Real f, l;// for those who call with (u,u). |
825 | Handle(Geom_Curve) C3d = |
826 | BRep_Tool::Curve(E,/*LC,*/f,l); // transforming plane instead of curve |
827 | // we can loose scale factor of Curve transformation (eap 13 May 2002) |
7fd59977 |
828 | |
f1baf495 |
829 | LC = L/*.Predivided(LC)*/; |
7fd59977 |
830 | |
f1baf495 |
831 | if (C3d.IsNull()) return nullPCurve; |
7fd59977 |
832 | |
f1baf495 |
833 | Handle(Geom_Plane) Plane = GP; |
834 | if (!LC.IsIdentity()) { |
835 | const gp_Trsf& T = LC.Transformation(); |
836 | Handle(Geom_Geometry) GPT = GP->Transformed(T); |
c5f3a425 |
837 | Plane = Handle(Geom_Plane)::DownCast (GPT); |
f1baf495 |
838 | } |
839 | GeomAdaptor_Surface& GAS = HS->ChangeSurface(); |
840 | GAS.Load(Plane); |
841 | |
842 | Handle(Geom_Curve) ProjOnPlane = |
843 | GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,f,l), |
844 | Plane, |
845 | Plane->Position().Direction(), |
846 | Standard_True); |
847 | |
848 | GeomAdaptor_Curve& GAC = HC->ChangeCurve(); |
849 | GAC.Load(ProjOnPlane); |
850 | |
851 | ProjLib_ProjectedCurve Proj(HS,HC); |
852 | Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj); |
7fd59977 |
853 | |
f1baf495 |
854 | if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) { |
855 | Handle(Geom2d_TrimmedCurve) TC = |
c5f3a425 |
856 | Handle(Geom2d_TrimmedCurve)::DownCast (pc); |
f1baf495 |
857 | pc = TC->BasisCurve(); |
858 | } |
859 | First = f; Last = l; |
860 | // |
861 | bToUpdate=Standard_True; |
862 | // |
863 | return pc; |
864 | } |
865 | |
866 | return nullPCurve; |
867 | } |
fc88faf1 |
868 | //======================================================================= |
869 | //function : MaxToleranceEdge |
870 | //purpose : |
871 | //======================================================================= |
872 | Standard_Real MaxToleranceEdge (const TopoDS_Face& aF) |
873 | { |
874 | Standard_Real aTol, aTolMax; |
875 | TopExp_Explorer aExp; |
876 | // |
877 | aTolMax=0.; |
878 | aExp.Init(aF, TopAbs_EDGE); |
879 | for (; aExp.More(); aExp.Next()) { |
880 | const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current()); |
881 | aTol=BRep_Tool::Tolerance(aE); |
882 | if (aTol>aTolMax) { |
883 | aTolMax=aTol; |
884 | } |
885 | } |
886 | return aTolMax; |
887 | } |
39067947 |
888 | |
889 | //======================================================================= |
890 | //function : IsEdgeIsoline |
891 | //purpose : |
892 | //======================================================================= |
893 | void BOPTools_AlgoTools2D::IsEdgeIsoline( const TopoDS_Edge& theE, |
894 | const TopoDS_Face& theF, |
895 | Standard_Boolean& isTheUIso, |
896 | Standard_Boolean& isTheVIso) |
897 | { |
898 | isTheUIso = isTheVIso = Standard_False; |
899 | |
900 | gp_Vec2d aT; |
901 | gp_Pnt2d aP; |
902 | Standard_Real aFirst = 0.0, aLast = 0.0; |
903 | const Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnSurface(theE, theF, aFirst, aLast); |
904 | |
905 | aPC->D1(0.5*(aFirst+aLast), aP, aT); |
906 | |
907 | const Standard_Real aSqMagn = aT.SquareMagnitude(); |
908 | if(aSqMagn <= gp::Resolution()) |
909 | return; |
910 | |
911 | //Normalyze aT |
912 | aT /= sqrt(aSqMagn); |
913 | |
914 | //sin(da) ~ da, when da->0. |
915 | const Standard_Real aTol = Precision::Angular(); |
916 | const gp_Vec2d aRefVDir(0.0, 1.0), aRefUDir(1.0, 0.0); |
917 | |
918 | const Standard_Real aDPv = aT.CrossMagnitude(aRefVDir), |
919 | aDPu = aT.CrossMagnitude(aRefUDir); |
920 | |
921 | isTheUIso = (aDPv <= aTol); |
922 | isTheVIso = (aDPu <= aTol); |
f48cb55d |
923 | } |