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 <BOPTools_AlgoTools2D.hxx> |
17 | #include <BRep_Builder.hxx> |
18 | #include <BRep_CurveRepresentation.hxx> |
19 | #include <BRep_GCurve.hxx> |
20 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
21 | #include <BRep_TEdge.hxx> |
22 | #include <BRep_Tool.hxx> |
23 | #include <BRepAdaptor_Curve.hxx> |
24 | #include <BRepAdaptor_HSurface.hxx> |
25 | #include <BRepAdaptor_Surface.hxx> |
26 | #include <BRepClass_FaceClassifier.hxx> |
27 | #include <BRepTools.hxx> |
28 | #include <Geom2d_BSplineCurve.hxx> |
7fd59977 |
29 | #include <Geom2d_Circle.hxx> |
42cf5bc1 |
30 | #include <Geom2d_Curve.hxx> |
7fd59977 |
31 | #include <Geom2d_Ellipse.hxx> |
7fd59977 |
32 | #include <Geom2d_Hyperbola.hxx> |
42cf5bc1 |
33 | #include <Geom2d_Line.hxx> |
34 | #include <Geom2d_Parabola.hxx> |
f1baf495 |
35 | #include <Geom2d_TrimmedCurve.hxx> |
f1baf495 |
36 | #include <Geom2dAdaptor.hxx> |
7fd59977 |
37 | #include <Geom_Curve.hxx> |
f1baf495 |
38 | #include <Geom_Plane.hxx> |
42cf5bc1 |
39 | #include <Geom_RectangularTrimmedSurface.hxx> |
40 | #include <Geom_Surface.hxx> |
41 | #include <Geom_TrimmedCurve.hxx> |
f1baf495 |
42 | #include <GeomAdaptor_Curve.hxx> |
43 | #include <GeomAdaptor_HCurve.hxx> |
44 | #include <GeomAdaptor_HSurface.hxx> |
42cf5bc1 |
45 | #include <GeomAdaptor_Surface.hxx> |
46 | #include <GeomInt.hxx> |
0a807dd9 |
47 | #include <GeomLib.hxx> |
f1baf495 |
48 | #include <GeomProjLib.hxx> |
42cf5bc1 |
49 | #include <gp.hxx> |
fc88faf1 |
50 | #include <gp_Cylinder.hxx> |
42cf5bc1 |
51 | #include <gp_Pnt.hxx> |
52 | #include <gp_Pnt2d.hxx> |
53 | #include <gp_Vec.hxx> |
54 | #include <gp_Vec2d.hxx> |
55 | #include <IntTools_Context.hxx> |
56 | #include <IntTools_Tools.hxx> |
57 | #include <Precision.hxx> |
58 | #include <ProjLib_ProjectedCurve.hxx> |
f48cb55d |
59 | #include <ProjLib.hxx> |
42cf5bc1 |
60 | #include <Standard_ConstructionError.hxx> |
61 | #include <Standard_NotImplemented.hxx> |
62 | #include <TopExp.hxx> |
fc88faf1 |
63 | #include <TopExp_Explorer.hxx> |
42cf5bc1 |
64 | #include <TopLoc_Location.hxx> |
65 | #include <TopoDS_Edge.hxx> |
66 | #include <TopoDS_Face.hxx> |
7fd59977 |
67 | |
fc88faf1 |
68 | static |
69 | Standard_Real MaxToleranceEdge (const TopoDS_Face& ); |
7fd59977 |
70 | |
4e57c75e |
71 | //======================================================================= |
72 | //function : BuildPCurveForEdgeOnFace |
73 | //purpose : |
74 | //======================================================================= |
f1baf495 |
75 | void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE, |
51db0179 |
76 | const TopoDS_Face& aF, |
77 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
78 | { |
79 | BRep_Builder aBB; |
80 | Handle(Geom2d_Curve) aC2D; |
81 | Standard_Real aTolPC, aTolFact, aTolEdge, aFirst, aLast; |
82 | |
83 | Standard_Boolean aHasOld; |
f1baf495 |
84 | aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, aC2D, |
85 | aFirst, aLast, |
86 | aTolEdge); |
4e57c75e |
87 | if (aHasOld) { |
88 | return; |
89 | } |
90 | |
91 | |
51db0179 |
92 | BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aTolPC, theContext); |
4e57c75e |
93 | |
94 | aTolEdge=BRep_Tool::Tolerance(aE); |
95 | |
96 | aTolFact=Max(aTolEdge, aTolPC); |
97 | |
98 | aBB.UpdateEdge(aE, aC2D, aF, aTolFact); |
99 | return; |
100 | } |
101 | |
7fd59977 |
102 | //======================================================================= |
103 | //function : EdgeTangent |
104 | //purpose : |
105 | //======================================================================= |
f1baf495 |
106 | Standard_Boolean BOPTools_AlgoTools2D::EdgeTangent |
107 | (const TopoDS_Edge& anEdge, |
108 | const Standard_Real aT, |
109 | gp_Vec& aTau) |
7fd59977 |
110 | { |
111 | Standard_Boolean isdgE; |
112 | Standard_Real first, last; |
113 | |
114 | isdgE = BRep_Tool::Degenerated(anEdge); |
115 | if (isdgE) { |
116 | return Standard_False; |
117 | } |
7fd59977 |
118 | |
119 | Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last); |
120 | gp_Pnt aP; |
121 | aC->D1(aT, aP, aTau); |
122 | Standard_Real mod = aTau.Magnitude(); |
123 | if(mod > gp::Resolution()) { |
124 | aTau /= mod; |
125 | } |
126 | else { |
127 | return Standard_False; |
128 | } |
129 | //aTau.Normalize(); |
130 | if (anEdge.Orientation() == TopAbs_REVERSED){ |
131 | aTau.Reverse(); |
132 | } |
133 | return Standard_True; |
134 | } |
135 | |
7fd59977 |
136 | //======================================================================= |
137 | //function : PointOnOnSurface |
138 | //purpose : |
139 | //======================================================================= |
f1baf495 |
140 | void BOPTools_AlgoTools2D::PointOnSurface (const TopoDS_Edge& aE, |
141 | const TopoDS_Face& aF, |
142 | const Standard_Real aParameter, |
143 | Standard_Real& U, |
51db0179 |
144 | Standard_Real& V, |
145 | const Handle(IntTools_Context)& theContext) |
7fd59977 |
146 | { |
147 | gp_Pnt2d aP2D; |
148 | Handle(Geom2d_Curve) aC2D; |
149 | Standard_Real aToler, aFirst, aLast; |
150 | |
51db0179 |
151 | BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler, theContext); |
7fd59977 |
152 | aC2D->D0(aParameter, aP2D); |
153 | U=aP2D.X(); |
154 | V=aP2D.Y(); |
155 | return; |
156 | } |
157 | |
158 | //======================================================================= |
159 | //function : CurveOnSurface |
160 | //purpose : |
161 | //======================================================================= |
f1baf495 |
162 | void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE, |
163 | const TopoDS_Face& aF, |
164 | Handle(Geom2d_Curve)& aC2D, |
51db0179 |
165 | Standard_Real& aToler, |
166 | const Handle(IntTools_Context)& theContext) |
7fd59977 |
167 | { |
168 | Standard_Real aFirst, aLast; |
f1baf495 |
169 | // |
51db0179 |
170 | BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aFirst, aLast, aToler, theContext); |
f1baf495 |
171 | // |
7fd59977 |
172 | return; |
173 | } |
174 | //======================================================================= |
175 | //function : CurveOnSurface |
176 | //purpose : |
177 | //======================================================================= |
f1baf495 |
178 | void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE, |
179 | const TopoDS_Face& aF, |
180 | Handle(Geom2d_Curve)& aC2D, |
181 | Standard_Real& aFirst, |
182 | Standard_Real& aLast, |
51db0179 |
183 | Standard_Real& aToler, |
184 | const Handle(IntTools_Context)& theContext) |
7fd59977 |
185 | { |
186 | Standard_Boolean aHasOld; |
187 | Handle(Geom2d_Curve) C2D; |
188 | |
f1baf495 |
189 | aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, C2D, |
190 | aFirst, aLast, |
191 | aToler); |
7fd59977 |
192 | if (aHasOld) { |
193 | aC2D=C2D; |
194 | return; |
195 | } |
196 | |
51db0179 |
197 | BOPTools_AlgoTools2D::Make2D(aE, aF, C2D, aFirst, aLast, aToler, theContext); |
7fd59977 |
198 | aC2D=C2D; |
199 | return; |
200 | } |
7fd59977 |
201 | //======================================================================= |
202 | //function : HasCurveOnSurface |
203 | //purpose : |
204 | //======================================================================= |
f1baf495 |
205 | Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface |
206 | (const TopoDS_Edge& aE, |
207 | const TopoDS_Face& aF, |
208 | Handle(Geom2d_Curve)& aC2D, |
209 | Standard_Real& aFirst, |
210 | Standard_Real& aLast, |
211 | Standard_Real& aToler) |
7fd59977 |
212 | { |
213 | Standard_Boolean aHasOld; |
214 | |
215 | aToler=BRep_Tool::Tolerance(aE); |
216 | BRep_Tool::Range(aE, aFirst, aLast); |
217 | |
218 | if((aLast - aFirst) < Precision::PConfusion()) { |
219 | return Standard_False; |
220 | } |
221 | |
f1baf495 |
222 | aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast); |
7fd59977 |
223 | aHasOld=!aC2D.IsNull(); |
224 | return aHasOld; |
225 | } |
226 | //======================================================================= |
227 | //function : HasCurveOnSurface |
228 | //purpose : |
229 | //======================================================================= |
f1baf495 |
230 | Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface |
231 | (const TopoDS_Edge& aE, |
232 | const TopoDS_Face& aF) |
7fd59977 |
233 | { |
f1baf495 |
234 | Standard_Boolean bHasOld; |
7fd59977 |
235 | Handle(Geom2d_Curve) aC2D; |
236 | Standard_Real aFirst, aLast; |
f1baf495 |
237 | // |
7fd59977 |
238 | BRep_Tool::Range(aE, aFirst, aLast); |
f1baf495 |
239 | // |
7fd59977 |
240 | if((aLast - aFirst) < Precision::PConfusion()) { |
241 | return Standard_False; |
242 | } |
f1baf495 |
243 | // |
244 | aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast); |
245 | bHasOld=!aC2D.IsNull(); |
246 | // |
247 | return bHasOld; |
7fd59977 |
248 | } |
7fd59977 |
249 | //======================================================================= |
250 | //function : AdjustPCurveOnFace |
251 | //purpose : |
252 | //======================================================================= |
51db0179 |
253 | void BOPTools_AlgoTools2D::AdjustPCurveOnFace |
254 | (const TopoDS_Face& theF, |
255 | const Handle(Geom_Curve)& theC3D, |
256 | const Handle(Geom2d_Curve)& theC2D, |
257 | Handle(Geom2d_Curve)& theC2DA, |
258 | const Handle(IntTools_Context)& theContext) |
7fd59977 |
259 | { |
51db0179 |
260 | Standard_Real aT1 = theC3D->FirstParameter(); |
261 | Standard_Real aT2 = theC3D->LastParameter(); |
fd372378 |
262 | // |
51db0179 |
263 | BOPTools_AlgoTools2D::AdjustPCurveOnFace (theF, aT1, aT2, theC2D, theC2DA, theContext); |
fd372378 |
264 | } |
7fd59977 |
265 | //======================================================================= |
266 | //function : AdjustPCurveOnFace |
267 | //purpose : |
268 | //======================================================================= |
f1baf495 |
269 | void BOPTools_AlgoTools2D::AdjustPCurveOnFace |
51db0179 |
270 | (const TopoDS_Face& theF, |
271 | const Standard_Real theFirst, |
272 | const Standard_Real theLast, |
273 | const Handle(Geom2d_Curve)& theC2D, |
274 | Handle(Geom2d_Curve)& theC2DA, |
275 | const Handle(IntTools_Context)& theContext) |
fd372378 |
276 | { |
51db0179 |
277 | BRepAdaptor_Surface aBASTmp; |
278 | const BRepAdaptor_Surface* pBAS; |
279 | if (!theContext.IsNull()) { |
280 | pBAS = &theContext->SurfaceAdaptor(theF); |
281 | } |
282 | else { |
283 | aBASTmp.Initialize(theF, Standard_True); |
284 | pBAS = &aBASTmp; |
285 | } |
fd372378 |
286 | // |
51db0179 |
287 | BOPTools_AlgoTools2D::AdjustPCurveOnSurf(*pBAS, theFirst, theLast, theC2D, theC2DA); |
fd372378 |
288 | } |
fd372378 |
289 | //======================================================================= |
290 | //function : AdjustPCurveOnFace |
291 | //purpose : |
292 | //======================================================================= |
51db0179 |
293 | void BOPTools_AlgoTools2D::AdjustPCurveOnSurf |
fd372378 |
294 | (const BRepAdaptor_Surface& aBAS, |
f1baf495 |
295 | const Standard_Real aFirst, |
296 | const Standard_Real aLast, |
51db0179 |
297 | const Handle(Geom2d_Curve)& aC2D, |
f1baf495 |
298 | Handle(Geom2d_Curve)& aC2DA) |
7fd59977 |
299 | { |
655fddc8 |
300 | Standard_Boolean mincond, maxcond; |
7fd59977 |
301 | Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta; |
655fddc8 |
302 | Standard_Real aUPeriod; |
7fd59977 |
303 | // |
fd372378 |
304 | const TopoDS_Face& aF=aBAS.Face(); |
305 | UMin=aBAS.FirstUParameter(); |
306 | UMax=aBAS.LastUParameter(); |
307 | VMin=aBAS.FirstVParameter(); |
308 | VMax=aBAS.LastVParameter(); |
309 | // |
fd372378 |
310 | aDelta=Precision::PConfusion(); |
7fd59977 |
311 | |
312 | aT =.5*(aFirst+aLast); |
313 | |
314 | gp_Pnt2d pC2D; |
315 | aC2D->D0(aT, pC2D); |
316 | |
317 | u2 = pC2D.X(); |
318 | v2 = pC2D.Y(); |
fc88faf1 |
319 | // |
320 | // du |
7fd59977 |
321 | du = 0.; |
322 | if (aBAS.IsUPeriodic()) { |
655fddc8 |
323 | aUPeriod = aBAS.UPeriod(); |
fd372378 |
324 | |
7fd59977 |
325 | // |
67e36f0c |
326 | // a. try to clarify u2 using the precision (aDelta) |
327 | if (fabs(u2-UMin) < aDelta) { |
328 | u2=UMin; |
329 | } |
330 | else if (fabs(u2-UMin-aUPeriod) < aDelta) { |
9c0b61f3 |
331 | u2=UMin+aUPeriod; |
332 | } |
67e36f0c |
333 | // b. compute du again using clarified value of u2 |
334 | GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, u2, du, 0.); |
fc88faf1 |
335 | // |
336 | if (du==0.) { |
337 | if (aBAS.GetType()==GeomAbs_Cylinder) { |
338 | Standard_Real aR, dFi, aTol; |
339 | // |
340 | gp_Cylinder aCylinder=aBAS.Cylinder(); |
341 | aR=aCylinder.Radius(); |
342 | aTol=MaxToleranceEdge(aF); |
343 | dFi=aTol/aR; |
344 | if (dFi<aDelta) { |
345 | dFi=aDelta; |
346 | } |
347 | // |
348 | mincond = (UMin - u2 > dFi); |
349 | maxcond = (u2 - UMax > dFi); |
350 | if (mincond || maxcond) { |
351 | du = ( mincond ) ? aUPeriod : -aUPeriod; |
352 | } |
353 | } |
354 | } |
655fddc8 |
355 | } |
fc88faf1 |
356 | |
7fd59977 |
357 | // dv |
358 | dv = 0.; |
359 | if (aBAS.IsVPeriodic()) { |
360 | Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr; |
361 | // |
655fddc8 |
362 | aVPeriod = aBAS.VPeriod(); |
7fd59977 |
363 | mincond = (VMin - v2 > aDelta); |
364 | maxcond = (v2 - VMax > aDelta); |
655fddc8 |
365 | // |
366 | if (mincond || maxcond) { |
7fd59977 |
367 | dv = ( mincond ) ? aVPeriod : -aVPeriod; |
368 | } |
369 | // |
7fd59977 |
370 | if ((VMax-VMin<aVPeriod) && dv) { |
371 | aVm=v2; |
372 | aVr=v2+dv; |
373 | aVmid=0.5*(VMin+VMax); |
374 | dVm=fabs(aVm-aVmid); |
375 | dVr=fabs(aVr-aVmid); |
376 | if (dVm<dVr) { |
4e57c75e |
377 | dv=0.; |
7fd59977 |
378 | } |
379 | } |
7fd59977 |
380 | } |
381 | // |
d8a24e83 |
382 | { |
383 | //check the point with classifier |
384 | Standard_Real u,v; |
385 | u = u2 + du; |
386 | v = v2 + dv; |
387 | if (aBAS.IsUPeriodic()) { |
388 | aUPeriod = aBAS.UPeriod(); |
389 | if ((UMax - UMin - 2*aDelta) > aUPeriod) { |
390 | if ((u > (UMin + aDelta + aUPeriod)) || |
391 | (u < (UMax - aDelta - aUPeriod))) { |
392 | BRepClass_FaceClassifier aClassifier; |
393 | aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta); |
394 | TopAbs_State Status = aClassifier.State(); |
395 | if (Status == TopAbs_OUT) { |
396 | du += (u > (UMin + aDelta + aUPeriod)) ? -aUPeriod : aUPeriod; |
397 | } |
398 | } |
399 | } |
400 | } |
401 | // |
402 | u = u2 + du; |
403 | if (aBAS.IsVPeriodic()) { |
404 | Standard_Real aVPeriod = aBAS.VPeriod(); |
405 | if ((VMax - VMin - 2*aDelta) > aVPeriod) { |
406 | if ((v > (VMin + aDelta + aVPeriod)) || |
407 | (v < (VMax - aDelta - aVPeriod))) { |
408 | BRepClass_FaceClassifier aClassifier; |
409 | aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta); |
410 | TopAbs_State Status = aClassifier.State(); |
411 | if (Status == TopAbs_OUT) { |
412 | dv += (v > (VMin + aDelta + aVPeriod)) ? -aVPeriod : aVPeriod; |
413 | } |
414 | } |
415 | } |
416 | } |
417 | } |
7fd59977 |
418 | // Translation if necessary |
419 | Handle(Geom2d_Curve) aC2Dx=aC2D; |
420 | |
421 | if ( du != 0. || dv != 0.) { |
422 | Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(aC2Dx->Copy()); |
423 | gp_Vec2d aV2D(du,dv); |
424 | PCT->Translate(aV2D); |
425 | aC2Dx = PCT; |
426 | } |
427 | |
428 | aC2DA=aC2Dx; |
429 | } |
430 | |
4e57c75e |
431 | //======================================================================= |
432 | //function : IntermediatePoint |
433 | //purpose : |
434 | //======================================================================= |
f1baf495 |
435 | Standard_Real BOPTools_AlgoTools2D::IntermediatePoint |
436 | (const Standard_Real aFirst, |
437 | const Standard_Real aLast) |
4e57c75e |
438 | { |
439 | //define parameter division number as 10*e^(-PI) = 0.43213918 |
440 | const Standard_Real PAR_T = 0.43213918; |
441 | Standard_Real aParm; |
442 | aParm=(1.-PAR_T)*aFirst + PAR_T*aLast; |
443 | return aParm; |
444 | } |
445 | //======================================================================= |
446 | //function : IntermediatePoint |
447 | //purpose : |
448 | //======================================================================= |
f1baf495 |
449 | Standard_Real BOPTools_AlgoTools2D::IntermediatePoint |
450 | (const TopoDS_Edge& aE) |
4e57c75e |
451 | |
452 | { |
453 | Standard_Real aT, aT1, aT2; |
454 | |
455 | Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2); |
456 | if (aC1.IsNull()) |
457 | BRep_Tool::Range(aE, aT1, aT2); |
458 | |
459 | aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2); |
460 | return aT; |
461 | } |
4e57c75e |
462 | //======================================================================= |
463 | //function : Make2D |
464 | //purpose : |
465 | //======================================================================= |
acccace3 |
466 | void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE, |
f1baf495 |
467 | const TopoDS_Face& aF, |
468 | Handle(Geom2d_Curve)& aC2D, |
469 | Standard_Real& aFirst, |
470 | Standard_Real& aLast, |
51db0179 |
471 | Standard_Real& aToler, |
472 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
473 | { |
474 | Standard_Boolean aLocIdentity; |
475 | Standard_Real f3d, l3d; |
476 | TopLoc_Location aLoc; |
477 | |
478 | Handle(Geom2d_Curve) C2D; |
479 | |
480 | |
481 | C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast); |
482 | |
483 | if (!C2D.IsNull()) { |
484 | aC2D=C2D; |
485 | return; |
486 | } |
487 | |
488 | Handle(Geom_Curve) C3D2, C3D; |
489 | C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d); |
490 | // |
491 | if (C3D.IsNull()) { |
492 | // aE has no 3D curve, so nothing is done |
493 | } |
494 | // |
495 | aLocIdentity=aLoc.IsIdentity(); |
496 | |
497 | if (aLocIdentity) { |
498 | C3D2 = C3D; |
499 | } |
500 | else { |
501 | C3D2 = Handle(Geom_Curve):: |
502 | DownCast(C3D->Transformed(aLoc.Transformation())); |
503 | } |
504 | |
505 | // |
ee5ee7db |
506 | aToler = BRep_Tool::Tolerance(aE); |
51db0179 |
507 | BOPTools_AlgoTools2D::MakePCurveOnFace(aF, C3D2, f3d, l3d, aC2D, aToler, theContext); |
4e57c75e |
508 | // |
509 | aFirst = f3d; |
510 | aLast = l3d; |
511 | } |
512 | |
513 | //======================================================================= |
514 | //function : MakePCurveOnFace |
515 | //purpose : |
516 | //======================================================================= |
f1baf495 |
517 | void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF, |
518 | const Handle(Geom_Curve)& aC3D, |
519 | Handle(Geom2d_Curve)& aC2D, //-> |
51db0179 |
520 | Standard_Real& TolReached2d, |
521 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
522 | { |
523 | Standard_Real aFirst, aLast; |
524 | |
525 | aFirst = aC3D -> FirstParameter(); |
526 | aLast = aC3D -> LastParameter(); |
527 | // |
528 | TolReached2d=0.; |
529 | // |
51db0179 |
530 | BOPTools_AlgoTools2D::MakePCurveOnFace |
531 | (aF, aC3D, aFirst, aLast, aC2D, TolReached2d, theContext); |
4e57c75e |
532 | } |
533 | |
534 | //======================================================================= |
535 | //function : MakePCurveOnFace |
536 | //purpose : |
537 | //======================================================================= |
51db0179 |
538 | void BOPTools_AlgoTools2D::MakePCurveOnFace |
f1baf495 |
539 | (const TopoDS_Face& aF, |
540 | const Handle(Geom_Curve)& aC3D, |
fd372378 |
541 | const Standard_Real aT1, |
542 | const Standard_Real aT2, |
51db0179 |
543 | Handle(Geom2d_Curve)& aC2D, |
544 | Standard_Real& TolReached2d, |
545 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
546 | { |
51db0179 |
547 | BRepAdaptor_Surface aBASTmp; |
548 | const BRepAdaptor_Surface* pBAS; |
549 | if (!theContext.IsNull()) { |
550 | pBAS = &theContext->SurfaceAdaptor(aF); |
551 | } |
552 | else { |
553 | aBASTmp.Initialize(aF, Standard_True); |
554 | pBAS = &aBASTmp; |
555 | } |
fd372378 |
556 | // |
51db0179 |
557 | Handle(BRepAdaptor_HSurface) aBAHS = new BRepAdaptor_HSurface(*pBAS); |
558 | Handle(GeomAdaptor_HCurve) aBAHC = new GeomAdaptor_HCurve(aC3D, aT1, aT2); |
f2843558 |
559 | // |
51db0179 |
560 | Standard_Real aTolR; |
f998596a |
561 | Standard_Real aTR = Precision::Confusion();//1.e-7; |
562 | Standard_Real aMaxTol = 1.e3 * aTR; //0.0001 |
563 | Standard_Boolean isAnaSurf = ProjLib::IsAnaSurf(aBAHS); |
564 | |
4e57c75e |
565 | //when the type of surface is GeomAbs_SurfaceOfRevolution |
f998596a |
566 | if (pBAS->GetType() == GeomAbs_SurfaceOfRevolution) |
567 | { |
fd372378 |
568 | if (TolReached2d > aTR) { |
569 | aTR=TolReached2d; |
570 | } |
571 | // |
4e57c75e |
572 | ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR); |
f48cb55d |
573 | ProjLib::MakePCurveOfType(aProj1, aC2D); |
4e57c75e |
574 | aTolR = aProj1.GetTolerance(); |
fd372378 |
575 | } |
f998596a |
576 | else |
577 | { |
578 | ProjLib_ProjectedCurve aProjCurv(aBAHS); |
579 | Standard_Integer aDegMin = -1, aDegMax = -1, aMaxSegments = -1; |
580 | Standard_Real aMaxDist = -1; |
581 | AppParCurves_Constraint aBndPnt = AppParCurves_TangencyPoint; |
582 | if ((TolReached2d >= 10. * aTR) && (TolReached2d <= aMaxTol || isAnaSurf)) |
583 | { |
584 | aTR = Min(aMaxTol, 0.1*TolReached2d); |
585 | aMaxSegments = 100; |
586 | aMaxDist = 1.e3*TolReached2d; |
47a27171 |
587 | if(!isAnaSurf || TolReached2d > 1.) |
f998596a |
588 | { |
589 | aBndPnt = AppParCurves_PassPoint; |
590 | } |
591 | } |
592 | else if(TolReached2d > aMaxTol) |
593 | { |
594 | aTR = Min(TolReached2d, 1.e3 * aMaxTol); |
595 | aMaxDist = 1.e2 * aTR; |
596 | aMaxSegments = 100; |
597 | } |
598 | aProjCurv.Load(aTR); |
599 | aProjCurv.SetDegree(aDegMin, aDegMax); |
600 | aProjCurv.SetMaxSegments(aMaxSegments); |
601 | aProjCurv.SetBndPnt(aBndPnt); |
602 | aProjCurv.SetMaxDist(aMaxDist); |
603 | aProjCurv.Perform(aBAHC); |
f48cb55d |
604 | ProjLib::MakePCurveOfType(aProjCurv, aC2D); |
4e57c75e |
605 | aTolR=aProjCurv.GetTolerance(); |
606 | } |
607 | // |
f998596a |
608 | if (aC2D.IsNull() && (aTR < aMaxTol || aTR < TolReached2d)) |
609 | { |
610 | aTR = Max(TolReached2d, aMaxTol); |
611 | ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, aTR);// 2 |
f48cb55d |
612 | ProjLib::MakePCurveOfType(aProjCurvAgain, aC2D); |
4e57c75e |
613 | aTolR = aProjCurvAgain.GetTolerance(); |
4e57c75e |
614 | } |
b9a7d225 |
615 | // |
616 | if(aC2D.IsNull()) |
617 | { |
9775fa61 |
618 | throw Standard_ConstructionError("BOPTools_AlgoTools2D::MakePCurveOnFace : PCurve is Null"); |
b9a7d225 |
619 | } |
620 | // |
4e57c75e |
621 | TolReached2d=aTolR; |
0a807dd9 |
622 | |
623 | // Adjust curve for periodic surface |
51db0179 |
624 | Handle(Geom2d_Curve) aC2DA; |
625 | BOPTools_AlgoTools2D::AdjustPCurveOnSurf (*pBAS, aT1, aT2, aC2D, aC2DA); |
0a807dd9 |
626 | aC2D = aC2DA; |
627 | |
628 | // Make sure that the range of the 2D curve is sufficient for representation of the 3D curve. |
629 | Standard_Real aTCFirst = aC2D->FirstParameter(); |
630 | Standard_Real aTCLast = aC2D->LastParameter(); |
631 | if ((aTCFirst - aT1) > Precision::PConfusion() || |
632 | (aT2 - aTCLast ) > Precision::PConfusion()) |
633 | { |
634 | if (aTCFirst < aT1) aTCFirst = aT1; |
635 | if (aTCLast > aT2) aTCLast = aT2; |
636 | |
637 | GeomLib::SameRange(Precision::PConfusion(), aC2D, |
638 | aTCFirst, aTCLast, aT1, aT2, aC2D); |
639 | } |
640 | |
1b7ae951 |
641 | // compute the appropriate tolerance for the edge |
51db0179 |
642 | Handle(Geom_Surface) aS = pBAS->Surface().Surface(); |
643 | aS = Handle(Geom_Surface)::DownCast(aS->Transformed(pBAS->Trsf())); |
644 | // |
645 | Standard_Real aT; |
1b7ae951 |
646 | if (IntTools_Tools::ComputeTolerance |
fd372378 |
647 | (aC3D, aC2D, aS, aT1, aT2, aTolR, aT)) { |
1b7ae951 |
648 | if (aTolR > TolReached2d) { |
649 | TolReached2d = aTolR; |
650 | } |
651 | } |
4e57c75e |
652 | } |
7fd59977 |
653 | |
fc88faf1 |
654 | //======================================================================= |
655 | //function : MaxToleranceEdge |
656 | //purpose : |
657 | //======================================================================= |
658 | Standard_Real MaxToleranceEdge (const TopoDS_Face& aF) |
659 | { |
660 | Standard_Real aTol, aTolMax; |
661 | TopExp_Explorer aExp; |
662 | // |
663 | aTolMax=0.; |
664 | aExp.Init(aF, TopAbs_EDGE); |
665 | for (; aExp.More(); aExp.Next()) { |
666 | const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current()); |
667 | aTol=BRep_Tool::Tolerance(aE); |
668 | if (aTol>aTolMax) { |
669 | aTolMax=aTol; |
670 | } |
671 | } |
672 | return aTolMax; |
673 | } |
39067947 |
674 | |
675 | //======================================================================= |
676 | //function : IsEdgeIsoline |
677 | //purpose : |
678 | //======================================================================= |
679 | void BOPTools_AlgoTools2D::IsEdgeIsoline( const TopoDS_Edge& theE, |
680 | const TopoDS_Face& theF, |
681 | Standard_Boolean& isTheUIso, |
682 | Standard_Boolean& isTheVIso) |
683 | { |
684 | isTheUIso = isTheVIso = Standard_False; |
685 | |
686 | gp_Vec2d aT; |
687 | gp_Pnt2d aP; |
688 | Standard_Real aFirst = 0.0, aLast = 0.0; |
689 | const Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnSurface(theE, theF, aFirst, aLast); |
690 | |
691 | aPC->D1(0.5*(aFirst+aLast), aP, aT); |
692 | |
693 | const Standard_Real aSqMagn = aT.SquareMagnitude(); |
694 | if(aSqMagn <= gp::Resolution()) |
695 | return; |
696 | |
697 | //Normalyze aT |
698 | aT /= sqrt(aSqMagn); |
699 | |
700 | //sin(da) ~ da, when da->0. |
701 | const Standard_Real aTol = Precision::Angular(); |
702 | const gp_Vec2d aRefVDir(0.0, 1.0), aRefUDir(1.0, 0.0); |
703 | |
704 | const Standard_Real aDPv = aT.CrossMagnitude(aRefVDir), |
705 | aDPu = aT.CrossMagnitude(aRefUDir); |
706 | |
707 | isTheUIso = (aDPv <= aTol); |
708 | isTheVIso = (aDPu <= aTol); |
f48cb55d |
709 | } |