4e57c75e |
1 | // Created by: Peter KURNEV |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
4e57c75e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
4e57c75e |
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. |
4e57c75e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
4e57c75e |
14 | |
42cf5bc1 |
15 | #include <BOPAlgo_WireEdgeSet.hxx> |
16 | #include <BOPAlgo_WireSplitter.hxx> |
42cf5bc1 |
17 | #include <BOPTools_AlgoTools2D.hxx> |
18 | #include <BRep_Builder.hxx> |
19 | #include <BRep_Tool.hxx> |
20 | #include <BRepAdaptor_Surface.hxx> |
4e57c75e |
21 | #include <Geom2d_Curve.hxx> |
c5face6f |
22 | #include <Geom2d_Line.hxx> |
c5face6f |
23 | #include <Geom2dAdaptor_Curve.hxx> |
c5face6f |
24 | #include <Geom2dInt_GInter.hxx> |
42cf5bc1 |
25 | #include <Geom_Plane.hxx> |
26 | #include <Geom_RectangularTrimmedSurface.hxx> |
27 | #include <Geom_Surface.hxx> |
28 | #include <GeomAdaptor_Surface.hxx> |
29 | #include <gp_Dir2d.hxx> |
30 | #include <gp_Pnt2d.hxx> |
31 | #include <gp_Vec2d.hxx> |
c5face6f |
32 | #include <IntRes2d_Domain.hxx> |
33 | #include <IntRes2d_IntersectionPoint.hxx> |
42cf5bc1 |
34 | #include <Precision.hxx> |
35 | #include <TopExp.hxx> |
36 | #include <TopExp_Explorer.hxx> |
c5face6f |
37 | #include <TopLoc_Location.hxx> |
f80842e3 |
38 | #include <TopoDS.hxx> |
4e57c75e |
39 | #include <TopoDS_Edge.hxx> |
42cf5bc1 |
40 | #include <TopoDS_Face.hxx> |
41 | #include <TopoDS_Iterator.hxx> |
4e57c75e |
42 | #include <TopoDS_Vertex.hxx> |
43 | #include <TopoDS_Wire.hxx> |
c5face6f |
44 | #include <TopTools_ShapeMapHasher.hxx> |
3ba87fdb |
45 | #include <Geom2dLProp_CLProps2d.hxx> |
1155d05a |
46 | #include <TColgp_SequenceOfPnt2d.hxx> |
47 | #include <TColStd_SequenceOfReal.hxx> |
48 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
49 | #include <TopTools_ListOfShape.hxx> |
50 | #include <TopTools_MapOfShape.hxx> |
51 | #include <TopTools_SequenceOfShape.hxx> |
52 | |
f56518cd |
53 | typedef NCollection_DataMap \ |
54 | <TopoDS_Shape, Standard_Boolean, TopTools_ShapeMapHasher> \ |
1155d05a |
55 | MyDataMapOfShapeBoolean; |
f56518cd |
56 | // |
57 | |
4e57c75e |
58 | static |
59 | Standard_Real Angle (const gp_Dir2d& aDir2D); |
60 | |
61 | static |
62 | Standard_Real Angle2D (const TopoDS_Vertex& aV, |
63 | const TopoDS_Edge& anEdge, |
64 | const TopoDS_Face& myFace, |
65 | const GeomAdaptor_Surface& aGAS, |
51db0179 |
66 | const Standard_Boolean aFlag, |
67 | const Handle(IntTools_Context)& theContext); |
4e57c75e |
68 | |
69 | static |
70 | void GetNextVertex(const TopoDS_Vertex& aV, |
71 | const TopoDS_Edge& aE, |
72 | TopoDS_Vertex& aV1); |
73 | |
74 | static |
75 | Standard_Real AngleIn(const TopoDS_Edge& aEIn, |
76 | const BOPAlgo_ListOfEdgeInfo& aLEInfo); |
77 | |
78 | static |
79 | Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo); |
80 | |
81 | static |
82 | gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE, |
83 | const TopoDS_Face& aF); |
84 | |
85 | static |
86 | gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1, |
87 | const TopoDS_Edge& aE1, |
88 | const TopoDS_Face& aF); |
89 | |
f56518cd |
90 | static |
4e57c75e |
91 | Standard_Real ClockWiseAngle(const Standard_Real aAngleIn, |
92 | const Standard_Real aAngleOut); |
93 | |
94 | static |
95 | void Path (const GeomAdaptor_Surface& aGAS, |
96 | const TopoDS_Face& myFace, |
97 | const TopoDS_Vertex& aVa, |
98 | const TopoDS_Edge& aEOuta, |
99 | BOPAlgo_EdgeInfo& anEdgeInfo, |
1155d05a |
100 | TopTools_SequenceOfShape& aLS, |
101 | TopTools_SequenceOfShape& aVertVa, |
102 | TColgp_SequenceOfPnt2d& aCoordVa, |
4e57c75e |
103 | BOPTools_ConnexityBlock& aCB, |
f56518cd |
104 | BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap, |
1155d05a |
105 | MyDataMapOfShapeBoolean aVertMap); |
f56518cd |
106 | |
4e57c75e |
107 | static |
108 | Standard_Real Angle (const gp_Dir2d& aDir2D); |
109 | |
110 | static |
111 | Standard_Real Tolerance2D (const TopoDS_Vertex& aV, |
112 | const GeomAdaptor_Surface& aGAS); |
113 | |
acccace3 |
114 | |
4e57c75e |
115 | |
116 | static |
117 | Standard_Real UTolerance2D (const TopoDS_Vertex& aV, |
118 | const GeomAdaptor_Surface& aGAS); |
119 | static |
120 | Standard_Real VTolerance2D (const TopoDS_Vertex& aV, |
121 | const GeomAdaptor_Surface& aGAS); |
122 | |
c5face6f |
123 | static |
124 | void RefineAngles(const TopoDS_Face& myFace, |
1155d05a |
125 | const TopTools_ListOfShape&, |
51db0179 |
126 | BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo&, |
127 | const Handle(IntTools_Context)&); |
c5face6f |
128 | |
129 | |
130 | static |
131 | void RefineAngles(const TopoDS_Vertex& , |
132 | const TopoDS_Face& , |
1155d05a |
133 | const TopTools_MapOfShape& , |
51db0179 |
134 | BOPAlgo_ListOfEdgeInfo&, |
135 | const Handle(IntTools_Context)&); |
c5face6f |
136 | |
137 | static |
138 | Standard_Boolean RefineAngle2D(const TopoDS_Vertex& , |
139 | const TopoDS_Edge& , |
140 | const TopoDS_Face& , |
141 | const Standard_Real , |
142 | const Standard_Real , |
24542bc0 |
143 | const Standard_Real, |
51db0179 |
144 | Standard_Real& , |
145 | const Handle(IntTools_Context)& ); |
c5face6f |
146 | |
4e57c75e |
147 | //======================================================================= |
148 | //function : SplitBlock |
149 | //purpose : |
150 | //======================================================================= |
db8e4b9a |
151 | void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace, |
51db0179 |
152 | BOPTools_ConnexityBlock& aCB, |
153 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
154 | { |
f56518cd |
155 | Standard_Boolean bNothingToDo, bIsClosed, bIsIN; |
4e57c75e |
156 | Standard_Integer aIx, aNb, i, aCntIn, aCntOut; |
157 | Standard_Real aAngle; |
158 | TopAbs_Orientation aOr; |
159 | TopoDS_Iterator aItS; |
160 | TopoDS_Vertex aVV; |
f56518cd |
161 | TopoDS_Shape aV1; |
1155d05a |
162 | TopTools_ListIteratorOfListOfShape aIt; |
4e57c75e |
163 | BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI; |
164 | // |
db8e4b9a |
165 | BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo mySmartMap(100); |
1155d05a |
166 | MyDataMapOfShapeBoolean aVertMap; |
4e57c75e |
167 | // |
1155d05a |
168 | const TopTools_ListOfShape& myEdges=aCB.Shapes(); |
4e57c75e |
169 | // |
170 | // 1.Filling mySmartMap |
4e57c75e |
171 | aIt.Initialize(myEdges); |
172 | for(; aIt.More(); aIt.Next()) { |
173 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value()); |
174 | if (!BOPTools_AlgoTools2D::HasCurveOnSurface (aE, myFace)) { |
175 | continue; |
176 | } |
177 | // |
f56518cd |
178 | bIsClosed = BRep_Tool::Degenerated(aE) || |
179 | BRep_Tool::IsClosed(aE, myFace); |
180 | // |
4e57c75e |
181 | aItS.Initialize(aE); |
f56518cd |
182 | for(i = 0; aItS.More(); aItS.Next(), ++i) { |
183 | const TopoDS_Shape& aV = aItS.Value(); |
184 | aIx = mySmartMap.FindIndex(aV); |
4e57c75e |
185 | if (!aIx) { |
db8e4b9a |
186 | BOPAlgo_ListOfEdgeInfo aLEIx; |
f56518cd |
187 | aIx = mySmartMap.Add(aV, aLEIx); |
4e57c75e |
188 | } |
189 | // |
f56518cd |
190 | BOPAlgo_ListOfEdgeInfo& aLEI = mySmartMap(aIx); |
4e57c75e |
191 | BOPAlgo_EdgeInfo aEI; |
192 | // |
193 | aEI.SetEdge(aE); |
f56518cd |
194 | aOr = aV.Orientation(); |
195 | bIsIN = (aOr == TopAbs_REVERSED); |
196 | aEI.SetInFlag(bIsIN); |
197 | aLEI.Append(aEI); |
198 | // |
199 | if (!i) { |
200 | aV1 = aV; |
201 | } else { |
202 | bIsClosed = bIsClosed || aV1.IsSame(aV); |
4e57c75e |
203 | } |
f56518cd |
204 | // |
205 | if (aVertMap.IsBound(aV)) { |
206 | if (bIsClosed) { |
207 | aVertMap.ChangeFind(aV) = bIsClosed; |
208 | } |
209 | } else { |
210 | aVertMap.Bind(aV, bIsClosed); |
4e57c75e |
211 | } |
4e57c75e |
212 | } |
213 | } |
214 | // |
215 | aNb=mySmartMap.Extent(); |
216 | // |
217 | bNothingToDo=Standard_True; |
218 | for (i=1; i<=aNb; i++) { |
219 | aCntIn=0; |
220 | aCntOut=0; |
221 | const BOPAlgo_ListOfEdgeInfo& aLEInfo= mySmartMap(i); |
222 | BOPAlgo_ListIteratorOfListOfEdgeInfo anIt(aLEInfo); |
223 | for (; anIt.More(); anIt.Next()) { |
224 | const BOPAlgo_EdgeInfo& aEI=anIt.Value(); |
225 | if (aEI.IsIn()) { |
226 | aCntIn++; |
227 | } |
228 | else { |
229 | aCntOut++; |
230 | } |
231 | } |
232 | if (aCntIn!=1 || aCntOut!=1) { |
233 | bNothingToDo=Standard_False; |
234 | break; |
235 | } |
236 | } |
237 | // |
238 | // Each vertex has one edge In and one - Out. Good. But it is not enought |
239 | // to consider that nothing to do with this. We must check edges on TShape |
240 | // coinsidence. If there are such edges there is something to do with. |
241 | if (bNothingToDo) { |
242 | Standard_Integer aNbE, aNbMapEE; |
243 | Standard_Boolean bFlag; |
244 | // |
1155d05a |
245 | TopTools_IndexedDataMapOfShapeListOfShape aMapEE(100); |
4e57c75e |
246 | aNbE=myEdges.Extent(); |
247 | // |
248 | aIt.Initialize(myEdges); |
249 | for (; aIt.More(); aIt.Next()) { |
250 | const TopoDS_Shape& aE = aIt.Value(); |
251 | if (!aMapEE.Contains(aE)) { |
1155d05a |
252 | TopTools_ListOfShape aLEx; |
4e57c75e |
253 | aLEx.Append(aE); |
254 | aMapEE.Add(aE, aLEx); |
255 | } |
256 | else { |
1155d05a |
257 | TopTools_ListOfShape& aLEx=aMapEE.ChangeFromKey(aE); |
4e57c75e |
258 | aLEx.Append(aE); |
259 | } |
260 | } |
261 | // |
262 | bFlag=Standard_True; |
263 | aNbMapEE=aMapEE.Extent(); |
264 | for (i=1; i<=aNbMapEE; ++i) { |
1155d05a |
265 | const TopTools_ListOfShape& aLEx=aMapEE(i); |
4e57c75e |
266 | aNbE=aLEx.Extent(); |
267 | if (aNbE==1) {// usual case |
268 | continue; |
269 | } |
270 | else if (aNbE==2){ |
271 | const TopoDS_Shape& aE1=aLEx.First(); |
272 | const TopoDS_Shape& aE2=aLEx.Last(); |
273 | if (aE1.IsSame(aE2)) { |
274 | bFlag=Standard_False; |
275 | break; |
276 | } |
277 | } |
278 | else { |
279 | bFlag=Standard_False; |
280 | break; |
281 | } |
282 | } |
283 | bNothingToDo=bNothingToDo && bFlag; |
284 | } // if (bNothingToDo) { |
285 | if (bNothingToDo) { |
286 | TopoDS_Wire aW; |
287 | // |
1155d05a |
288 | TopTools_ListOfShape& aLECB=aCB.ChangeShapes(); |
4e57c75e |
289 | BOPAlgo_WireSplitter::MakeWire(aLECB, aW); |
1155d05a |
290 | TopTools_ListOfShape& aLoops=aCB.ChangeLoops(); |
4e57c75e |
291 | aLoops.Append(aW); |
292 | // |
4e57c75e |
293 | return; |
294 | } |
295 | // |
296 | // 3. Angles in mySmartMap |
51db0179 |
297 | const BRepAdaptor_Surface& aBAS = theContext->SurfaceAdaptor(myFace); |
4e57c75e |
298 | const GeomAdaptor_Surface& aGAS=aBAS.Surface(); |
299 | // |
300 | for (i=1; i<=aNb; i++) { |
f56518cd |
301 | const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&mySmartMap.FindKey(i))); |
4e57c75e |
302 | const BOPAlgo_ListOfEdgeInfo& aLEI= mySmartMap(i); |
4e57c75e |
303 | aItLEI.Initialize(aLEI); |
304 | for (; aItLEI.More(); aItLEI.Next()) { |
305 | BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue(); |
306 | const TopoDS_Edge& aE=aEI.Edge(); |
307 | // |
f56518cd |
308 | aVV = aV; |
309 | bIsIN = aEI.IsIn(); |
310 | aOr = bIsIN ? TopAbs_REVERSED : TopAbs_FORWARD; |
311 | aVV.Orientation(aOr); |
51db0179 |
312 | aAngle = Angle2D(aVV, aE, myFace, aGAS, bIsIN, theContext); |
4e57c75e |
313 | aEI.SetAngle(aAngle); |
314 | } |
315 | }// for (i=1; i<=aNb; i++) { |
316 | // |
c5face6f |
317 | //Theme: The treatment p-curves convergent in node. |
318 | //The refining the angles of p-curves taking into account |
51db0179 |
319 | //bounding curves if exist. |
320 | RefineAngles(myFace, myEdges, mySmartMap, theContext); |
c5face6f |
321 | // |
4e57c75e |
322 | // 4. Do |
323 | // |
324 | Standard_Boolean bIsOut, bIsNotPassed; |
1155d05a |
325 | TopTools_SequenceOfShape aLS, aVertVa; |
326 | TColgp_SequenceOfPnt2d aCoordVa; |
4e57c75e |
327 | // |
328 | for (i=1; i<=aNb; ++i) { |
329 | const TopoDS_Vertex& aVa=(*(TopoDS_Vertex *)(&mySmartMap.FindKey(i))); |
330 | const BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(i); |
331 | aItLEI.Initialize(aLEI); |
332 | for (; aItLEI.More(); aItLEI.Next()) { |
333 | BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue(); |
334 | const TopoDS_Edge& aEOuta=aEI.Edge(); |
335 | // |
336 | bIsOut=!aEI.IsIn(); |
337 | bIsNotPassed=!aEI.Passed(); |
338 | if (bIsOut && bIsNotPassed) { |
339 | // |
340 | aLS.Clear(); |
341 | aVertVa.Clear(); |
342 | aCoordVa.Clear(); |
343 | // |
344 | Path(aGAS, myFace, aVa, aEOuta, aEI, aLS, |
f56518cd |
345 | aVertVa, aCoordVa, aCB, mySmartMap, aVertMap); |
4e57c75e |
346 | } |
347 | } |
348 | }// for (i=1; i<=aNb; ++i) { |
349 | } |
350 | //======================================================================= |
351 | // function: Path |
352 | // purpose: |
353 | //======================================================================= |
354 | void Path (const GeomAdaptor_Surface& aGAS, |
355 | const TopoDS_Face& myFace, |
b7357c8b |
356 | const TopoDS_Vertex& aVFirst, |
357 | const TopoDS_Edge& aEFirst, |
358 | BOPAlgo_EdgeInfo& aEIFirst, |
1155d05a |
359 | TopTools_SequenceOfShape& aLS, |
360 | TopTools_SequenceOfShape& aVertVa, |
361 | TColgp_SequenceOfPnt2d& aCoordVa, |
4e57c75e |
362 | BOPTools_ConnexityBlock& aCB, |
f56518cd |
363 | BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap, |
1155d05a |
364 | MyDataMapOfShapeBoolean aVertMap) |
4e57c75e |
365 | { |
366 | Standard_Integer i, j, aNb, aNbj; |
ecba6de3 |
367 | Standard_Real anAngleIn, anAngleOut, anAngle, aMinAngle; |
368 | Standard_Real aTol2D, aTol2D2, aD2, aTwoPI; |
4e57c75e |
369 | Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed; |
f56518cd |
370 | Standard_Boolean bIsClosed; |
b7357c8b |
371 | TopoDS_Vertex aVa, aVb; |
372 | TopoDS_Edge aEOuta; |
4e57c75e |
373 | BOPAlgo_ListIteratorOfListOfEdgeInfo anIt; |
3ba87fdb |
374 | Standard_Real eps = Epsilon(1.); |
4e57c75e |
375 | // |
b7357c8b |
376 | aVa = aVFirst; |
377 | aEOuta = aEFirst; |
378 | BOPAlgo_EdgeInfo* anEdgeInfo = &aEIFirst; |
379 | // |
b20eeb13 |
380 | aTwoPI = M_PI + M_PI; |
4e57c75e |
381 | // |
382 | // append block |
383 | // |
b7357c8b |
384 | for (;;) { |
385 | // Do not escape through edge from which you enter |
386 | aNb=aLS.Length(); |
387 | if (aNb==1) { |
388 | const TopoDS_Shape& anEPrev=aLS(aNb); |
389 | if (anEPrev.IsSame(aEOuta)) { |
390 | return; |
391 | } |
4e57c75e |
392 | } |
4e57c75e |
393 | // |
b7357c8b |
394 | anEdgeInfo->SetPassed(Standard_True); |
395 | aLS.Append(aEOuta); |
396 | aVertVa.Append(aVa); |
397 | |
398 | TopoDS_Vertex pVa=aVa; |
399 | pVa.Orientation(TopAbs_FORWARD); |
400 | gp_Pnt2d aPa=Coord2d(pVa, aEOuta, myFace); |
401 | aCoordVa.Append(aPa); |
402 | |
403 | GetNextVertex (pVa, aEOuta, aVb); |
404 | |
405 | gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace); |
406 | |
ecba6de3 |
407 | const BOPAlgo_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb); |
4e57c75e |
408 | // |
ecba6de3 |
409 | aTol2D = 2.*Tolerance2D(aVb, aGAS); |
410 | aTol2D2 = aTol2D * aTol2D; |
411 | // |
f56518cd |
412 | bIsClosed = aVertMap.Find(aVb); |
24542bc0 |
413 | { |
1155d05a |
414 | TopTools_ListOfShape aBuf; |
f80842e3 |
415 | Standard_Boolean bHasEdge = Standard_False; |
b7357c8b |
416 | // |
24542bc0 |
417 | aNb = aLS.Length(); |
418 | for (i = aNb; i>0; --i) { |
b7357c8b |
419 | const TopoDS_Shape& aVPrev=aVertVa(i); |
420 | const gp_Pnt2d& aPaPrev=aCoordVa(i); |
f80842e3 |
421 | const TopoDS_Edge& aEPrev = TopoDS::Edge(aLS(i)); |
422 | // |
b7357c8b |
423 | aBuf.Append(aEPrev); |
f80842e3 |
424 | if (!bHasEdge) { |
425 | bHasEdge = !BRep_Tool::Degenerated(aEPrev); |
426 | // do not create wire from degenerated edges only |
427 | if (!bHasEdge) { |
428 | continue; |
429 | } |
430 | } |
431 | // |
ecba6de3 |
432 | anIsSameV = aVPrev.IsSame(aVb); |
433 | anIsSameV2d = anIsSameV; |
b7357c8b |
434 | if (anIsSameV) { |
ecba6de3 |
435 | if(bIsClosed) { |
436 | aD2 = aPaPrev.SquareDistance(aPb); |
437 | anIsSameV2d = aD2 < aTol2D2; |
438 | if (anIsSameV2d) { |
439 | Standard_Real udist = fabs(aPaPrev.X() - aPb.X()); |
440 | Standard_Real vdist = fabs(aPaPrev.Y() - aPb.Y()); |
441 | Standard_Real aTolU = 2.*UTolerance2D(aVb, aGAS); |
442 | Standard_Real aTolV = 2.*VTolerance2D(aVb, aGAS); |
443 | // |
444 | if((udist > aTolU) || (vdist > aTolV)) { |
445 | anIsSameV2d = Standard_False; |
446 | } |
b7357c8b |
447 | } |
448 | } |
449 | }//if (anIsSameV) { |
4e57c75e |
450 | // |
b7357c8b |
451 | if (anIsSameV && anIsSameV2d) { |
452 | Standard_Integer iPriz; |
453 | iPriz=1; |
454 | if (aBuf.Extent()==2) { |
455 | if(aBuf.First().IsSame(aBuf.Last())) { |
456 | iPriz=0; |
457 | } |
458 | } |
459 | if (iPriz) { |
460 | TopoDS_Wire aW; |
461 | BOPAlgo_WireSplitter::MakeWire(aBuf, aW); |
462 | aCB.ChangeLoops().Append(aW); |
463 | } |
4e57c75e |
464 | // |
b7357c8b |
465 | aNbj=i-1; |
466 | if (aNbj<1) { |
467 | // |
468 | aLS.Clear(); |
469 | aVertVa.Clear(); |
470 | aCoordVa.Clear(); |
471 | // |
472 | return; |
4e57c75e |
473 | } |
b7357c8b |
474 | // |
1155d05a |
475 | TopTools_SequenceOfShape aLSt, aVertVat; |
476 | TColgp_SequenceOfPnt2d aCoordVat; |
b7357c8b |
477 | // |
478 | aVb=(*(TopoDS_Vertex *)(&aVertVa(i))); |
479 | // |
480 | for (j=1; j<=aNbj; ++j) { |
481 | aLSt.Append(aLS(j)); |
482 | aVertVat.Append(aVertVa(j)); |
483 | aCoordVat.Append(aCoordVa(j)); |
4e57c75e |
484 | } |
4e57c75e |
485 | // |
486 | aLS.Clear(); |
487 | aVertVa.Clear(); |
488 | aCoordVa.Clear(); |
b7357c8b |
489 | |
490 | aLS=aLSt; |
491 | aVertVa=aVertVat; |
492 | aCoordVa=aCoordVat; |
4e57c75e |
493 | // |
b7357c8b |
494 | break; |
4e57c75e |
495 | } |
4e57c75e |
496 | } |
497 | } |
b7357c8b |
498 | // |
b7357c8b |
499 | // aEOutb |
500 | BOPAlgo_EdgeInfo *pEdgeInfo=NULL; |
501 | // |
ecba6de3 |
502 | anAngleIn = AngleIn(aEOuta, aLEInfo); |
503 | aMinAngle = 100.; |
504 | anIsFound = Standard_False; |
24542bc0 |
505 | Standard_Integer iCnt = NbWaysOut(aLEInfo); |
b7357c8b |
506 | Standard_Integer aCurIndexE = 0; |
507 | anIt.Initialize(aLEInfo); |
508 | for (; anIt.More(); anIt.Next()) { |
509 | BOPAlgo_EdgeInfo& anEI=anIt.ChangeValue(); |
510 | const TopoDS_Edge& aE=anEI.Edge(); |
511 | anIsOut=!anEI.IsIn(); |
512 | anIsNotPassed=!anEI.Passed(); |
f56518cd |
513 | // |
b7357c8b |
514 | if (anIsOut && anIsNotPassed) { |
515 | aCurIndexE++; |
b20eeb13 |
516 | // |
b7357c8b |
517 | // Is there one way to go out of the vertex |
518 | // we have to use it only. |
b20eeb13 |
519 | // |
b7357c8b |
520 | if (!iCnt) { |
521 | // no way to go . (Error) |
522 | return; |
4e57c75e |
523 | } |
b20eeb13 |
524 | // |
b7357c8b |
525 | if (iCnt==1) { |
526 | // the one and only way to go out . |
527 | pEdgeInfo=&anEI; |
528 | anIsFound=Standard_True; |
529 | break; |
530 | } |
b20eeb13 |
531 | // |
b7357c8b |
532 | if (aE.IsSame(aEOuta)) { |
533 | anAngle = aTwoPI; |
534 | } else { |
ecba6de3 |
535 | //check 2d distance |
536 | if (bIsClosed) { |
537 | gp_Pnt2d aP2Dx; |
538 | // |
539 | aP2Dx = Coord2dVf(aE, myFace); |
540 | // |
541 | aD2 = aP2Dx.SquareDistance(aPb); |
542 | if (aD2 > aTol2D2){ |
543 | continue; |
544 | } |
b20eeb13 |
545 | } |
b7357c8b |
546 | // |
ecba6de3 |
547 | // Look for minimal angle and make the choice. |
b7357c8b |
548 | anAngleOut=anEI.Angle(); |
b7357c8b |
549 | anAngle=ClockWiseAngle(anAngleIn, anAngleOut); |
550 | } |
3ba87fdb |
551 | if (anAngle < aMinAngle - eps) { |
b7357c8b |
552 | aMinAngle=anAngle; |
553 | pEdgeInfo=&anEI; |
554 | anIsFound=Standard_True; |
b20eeb13 |
555 | } |
4e57c75e |
556 | } |
b7357c8b |
557 | } // for (; anIt.More(); anIt.Next()) |
558 | // |
559 | if (!anIsFound) { |
560 | // no way to go . (Error) |
561 | return; |
4e57c75e |
562 | } |
b7357c8b |
563 | // |
564 | aVa = aVb; |
565 | aEOuta = pEdgeInfo->Edge(); |
566 | anEdgeInfo = pEdgeInfo; |
4e57c75e |
567 | } |
4e57c75e |
568 | } |
569 | //======================================================================= |
570 | // function: ClockWiseAngle |
571 | // purpose: |
572 | //======================================================================= |
573 | Standard_Real ClockWiseAngle(const Standard_Real aAngleIn, |
574 | const Standard_Real aAngleOut) |
575 | { |
576 | Standard_Real aTwoPi=M_PI+M_PI; |
577 | Standard_Real dA, A1, A2, AIn, AOut ; |
578 | |
579 | AIn=aAngleIn; |
580 | AOut=aAngleOut; |
581 | if (AIn >= aTwoPi) { |
582 | AIn=AIn-aTwoPi; |
583 | } |
584 | |
585 | if (AOut >= aTwoPi) { |
586 | AOut=AOut-aTwoPi; |
587 | } |
588 | |
589 | A1=AIn+M_PI; |
590 | |
591 | if (A1 >= aTwoPi) { |
592 | A1=A1-aTwoPi; |
593 | } |
594 | |
595 | A2=AOut; |
596 | |
597 | dA=A1-A2; |
598 | if (dA <= 0.) { |
599 | dA=aTwoPi+dA; |
600 | } |
601 | //xx |
602 | //else if (dA <= 1.e-15) { |
603 | else if (dA <= 1.e-14) { |
604 | dA=aTwoPi; |
605 | } |
606 | return dA; |
607 | } |
608 | //======================================================================= |
609 | // function: Coord2d |
610 | // purpose: |
611 | //======================================================================= |
612 | gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1, |
613 | const TopoDS_Edge& aE1, |
614 | const TopoDS_Face& aF) |
615 | { |
616 | Standard_Real aT, aFirst, aLast; |
617 | Handle(Geom2d_Curve) aC2D; |
618 | gp_Pnt2d aP2D1; |
619 | // |
620 | aT=BRep_Tool::Parameter (aV1, aE1, aF); |
621 | aC2D=BRep_Tool::CurveOnSurface(aE1, aF, aFirst, aLast); |
622 | aC2D->D0 (aT, aP2D1); |
623 | // |
624 | return aP2D1; |
625 | } |
626 | //======================================================================= |
627 | // function: Coord2dVf |
628 | // purpose: |
629 | //======================================================================= |
630 | gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE, |
631 | const TopoDS_Face& aF) |
632 | { |
633 | Standard_Real aCoord=99.; |
634 | gp_Pnt2d aP2D1(aCoord, aCoord); |
635 | TopoDS_Iterator aIt; |
636 | // |
637 | aIt.Initialize(aE); |
638 | for (; aIt.More(); aIt.Next()) { |
639 | const TopoDS_Shape& aVx=aIt.Value(); |
640 | if (aVx.Orientation()==TopAbs_FORWARD) { |
641 | |
642 | const TopoDS_Vertex& aVxx=(*(TopoDS_Vertex *)(&aVx));// TopoDS::Vertex(aVx); |
643 | aP2D1=Coord2d(aVxx, aE, aF); |
644 | return aP2D1; |
645 | } |
646 | } |
647 | return aP2D1; |
648 | } |
649 | |
650 | //======================================================================= |
651 | // function: NbWaysOut |
652 | // purpose: |
653 | //======================================================================= |
654 | Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo) |
655 | { |
656 | Standard_Boolean bIsOut, bIsNotPassed; |
657 | Standard_Integer iCnt=0; |
658 | BOPAlgo_ListIteratorOfListOfEdgeInfo anIt; |
659 | // |
660 | anIt.Initialize(aLEInfo); |
661 | for (; anIt.More(); anIt.Next()) { |
662 | const BOPAlgo_EdgeInfo& anEI=anIt.Value(); |
663 | // |
664 | bIsOut=!anEI.IsIn(); |
665 | bIsNotPassed=!anEI.Passed(); |
666 | if (bIsOut && bIsNotPassed) { |
667 | iCnt++; |
668 | } |
669 | } |
670 | return iCnt; |
671 | } |
672 | |
673 | //======================================================================= |
674 | // function: AngleIn |
675 | // purpose: |
676 | //======================================================================= |
677 | Standard_Real AngleIn(const TopoDS_Edge& aEIn, |
678 | const BOPAlgo_ListOfEdgeInfo& aLEInfo) |
679 | { |
680 | Standard_Real anAngleIn; |
681 | Standard_Boolean anIsIn; |
682 | BOPAlgo_ListIteratorOfListOfEdgeInfo anIt; |
683 | |
684 | anIt.Initialize(aLEInfo); |
685 | for (; anIt.More(); anIt.Next()) { |
686 | const BOPAlgo_EdgeInfo& anEdgeInfo=anIt.Value(); |
687 | const TopoDS_Edge& aE=anEdgeInfo.Edge(); |
688 | anIsIn=anEdgeInfo.IsIn(); |
689 | // |
690 | if (anIsIn && aE==aEIn) { |
691 | anAngleIn=anEdgeInfo.Angle(); |
692 | return anAngleIn; |
693 | } |
694 | } |
695 | anAngleIn=0.; |
696 | return anAngleIn; |
697 | } |
698 | //======================================================================= |
699 | // function: GetNextVertex |
700 | // purpose: |
701 | //======================================================================= |
702 | void GetNextVertex(const TopoDS_Vertex& aV, |
703 | const TopoDS_Edge& aE, |
704 | TopoDS_Vertex& aV1) |
705 | { |
706 | TopoDS_Iterator aIt; |
707 | // |
708 | aIt.Initialize(aE); |
709 | for (; aIt.More(); aIt.Next()) { |
710 | const TopoDS_Shape& aVx=aIt.Value(); |
711 | if (!aVx.IsEqual(aV)) { |
712 | aV1=(*(TopoDS_Vertex *)(&aVx)); |
713 | return ; |
714 | } |
715 | } |
716 | aV1=aV; |
717 | } |
718 | //======================================================================= |
719 | // function: Angle2D |
720 | // purpose: |
721 | //======================================================================= |
722 | Standard_Real Angle2D (const TopoDS_Vertex& aV, |
723 | const TopoDS_Edge& anEdge, |
724 | const TopoDS_Face& myFace, |
725 | const GeomAdaptor_Surface& aGAS, |
51db0179 |
726 | const Standard_Boolean bIsIN, |
727 | const Handle(IntTools_Context)& theContext) |
4e57c75e |
728 | { |
729 | Standard_Real aFirst, aLast, aToler, dt, aTV, aTV1, anAngle, aTX; |
730 | gp_Pnt2d aPV, aPV1; |
731 | gp_Vec2d aV2D; |
732 | Handle(Geom2d_Curve) aC2D; |
733 | // |
734 | aTV=BRep_Tool::Parameter (aV, anEdge, myFace); |
735 | if (Precision::IsInfinite(aTV)) { |
736 | return 0.; |
737 | } |
738 | // |
739 | BOPTools_AlgoTools2D::CurveOnSurface (anEdge, myFace, aC2D, |
51db0179 |
740 | aFirst, aLast, aToler, theContext); |
3ba87fdb |
741 | Standard_Real tol2d =2.*Tolerance2D(aV, aGAS); |
742 | // |
743 | GeomAbs_CurveType aType; |
744 | Geom2dAdaptor_Curve aGAC2D(aC2D); |
745 | // |
746 | dt = Max(aGAC2D.Resolution(tol2d), Precision::PConfusion()); |
4e57c75e |
747 | // |
3ba87fdb |
748 | aType=aGAC2D.GetType(); |
749 | if (aType != GeomAbs_Line ) |
750 | { |
751 | Geom2dLProp_CLProps2d LProp(aC2D, aTV, 2, Precision::PConfusion()); |
752 | if(LProp.IsTangentDefined()) |
753 | { |
754 | Standard_Real R = LProp.Curvature(); |
755 | if(R > Precision::PConfusion()) |
756 | { |
757 | R = 1./R; |
758 | Standard_Real cosphi = R / (R + tol2d); |
759 | dt = Max(dt, ACos(cosphi)); //to avoid small dt for big R. |
760 | } |
761 | } |
762 | } |
4e57c75e |
763 | //for case chl/927/r9 |
3ba87fdb |
764 | aTX=0.05*(aLast - aFirst);//aTX=0.25*(aLast - aFirst); |
4e57c75e |
765 | if (aTX < 5.e-5) { |
766 | aTX = 5.e-5; |
767 | } |
768 | if(dt > aTX) { |
769 | // to save direction of the curve as much as it possible |
770 | // in the case of big tolerances |
771 | dt = aTX; |
772 | } |
3ba87fdb |
773 | |
4e57c75e |
774 | if (fabs (aTV-aFirst) < fabs(aTV - aLast)) { |
775 | aTV1=aTV + dt; |
776 | } |
777 | else { |
778 | aTV1=aTV - dt; |
779 | } |
780 | // |
3ba87fdb |
781 | aGAC2D.D0 (aTV1, aPV1); |
782 | aGAC2D.D0 (aTV, aPV); |
783 | // |
784 | aV2D = bIsIN ? gp_Vec2d(aPV1, aPV) : gp_Vec2d(aPV, aPV1); |
4e57c75e |
785 | // |
786 | gp_Dir2d aDir2D(aV2D); |
787 | anAngle=Angle(aDir2D); |
788 | // |
789 | return anAngle; |
790 | } |
791 | //======================================================================= |
792 | // function: Angle |
793 | // purpose: |
794 | //======================================================================= |
795 | Standard_Real Angle (const gp_Dir2d& aDir2D) |
796 | { |
797 | gp_Dir2d aRefDir(1., 0.); |
798 | Standard_Real anAngle; |
799 | |
800 | anAngle = aRefDir.Angle(aDir2D); |
801 | if (anAngle < 0.) |
802 | anAngle += M_PI + M_PI; |
803 | return anAngle; |
804 | } |
805 | //======================================================================= |
806 | // function: Tolerance2D |
807 | // purpose: |
808 | //======================================================================= |
809 | Standard_Real Tolerance2D (const TopoDS_Vertex& aV, |
810 | const GeomAdaptor_Surface& aGAS) |
811 | { |
812 | Standard_Real aTol2D, anUr, aVr, aTolV3D; |
813 | GeomAbs_SurfaceType aType; |
814 | // |
815 | aType=aGAS.GetType(); |
816 | aTolV3D=BRep_Tool::Tolerance(aV); |
817 | |
818 | anUr=aGAS.UResolution(aTolV3D); |
819 | aVr =aGAS.VResolution(aTolV3D); |
820 | aTol2D=(aVr>anUr) ? aVr : anUr; |
821 | // |
822 | if (aTol2D < aTolV3D) { |
823 | aTol2D=aTolV3D; |
824 | } |
825 | if (aType==GeomAbs_BSplineSurface) { |
826 | aTol2D=1.1*aTol2D; |
827 | } |
828 | // |
829 | return aTol2D; |
830 | } |
acccace3 |
831 | |
4e57c75e |
832 | //======================================================================= |
833 | //function : UTolerance2D |
834 | //purpose : |
835 | //======================================================================= |
836 | Standard_Real UTolerance2D (const TopoDS_Vertex& aV, |
837 | const GeomAdaptor_Surface& aGAS) |
838 | { |
839 | const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV); |
840 | const Standard_Real anUr = aGAS.UResolution(aTolV3D); |
841 | // |
842 | return anUr; |
843 | } |
844 | |
845 | //======================================================================= |
846 | //function : VTolerance2D |
847 | //purpose : |
848 | //======================================================================= |
849 | Standard_Real VTolerance2D (const TopoDS_Vertex& aV, |
850 | const GeomAdaptor_Surface& aGAS) |
851 | { |
852 | const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV); |
853 | const Standard_Real anVr = aGAS.VResolution(aTolV3D); |
854 | // |
855 | return anVr; |
856 | } |
857 | |
c5face6f |
858 | //======================================================================= |
859 | //function : RefineAngles |
860 | //purpose : |
861 | //======================================================================= |
862 | void RefineAngles(const TopoDS_Face& myFace, |
1155d05a |
863 | const TopTools_ListOfShape& myEdges, |
51db0179 |
864 | BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap, |
865 | const Handle(IntTools_Context)& theContext) |
c5face6f |
866 | { |
867 | Standard_Integer aNb, i; |
1155d05a |
868 | NCollection_IndexedDataMap<TopoDS_Shape, |
869 | Standard_Integer, |
870 | TopTools_ShapeMapHasher> aMSI; |
871 | TopTools_MapOfShape aMBE; |
872 | TopTools_ListIteratorOfListOfShape aIt; |
c5face6f |
873 | // |
874 | // 1. Boundary Edges |
875 | aIt.Initialize(myEdges); |
876 | for(; aIt.More(); aIt.Next()) { |
877 | const TopoDS_Shape& aE=aIt.Value(); |
319da2e4 |
878 | if(aMSI.Contains(aE)) { |
879 | Standard_Integer& iCnt = aMSI.ChangeFromKey(aE); |
c5face6f |
880 | ++iCnt; |
881 | } |
882 | else { |
319da2e4 |
883 | Standard_Integer iCnt = 1; |
884 | aMSI.Add(aE, iCnt); |
c5face6f |
885 | } |
886 | } |
887 | // |
319da2e4 |
888 | aNb = aMSI.Extent(); |
889 | for (i = 1; i <= aNb; ++i) { |
890 | Standard_Integer iCnt = aMSI(i); |
891 | if (iCnt == 1) { |
892 | const TopoDS_Shape& aE = aMSI.FindKey(i); |
c5face6f |
893 | aMBE.Add(aE); |
894 | } |
c5face6f |
895 | } |
896 | // |
897 | aMSI.Clear(); |
898 | // |
319da2e4 |
899 | aNb = mySmartMap.Extent(); |
900 | for (i = 1; i <= aNb; ++i) { |
c5face6f |
901 | const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&mySmartMap.FindKey(i)); |
902 | BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(i); |
903 | // |
51db0179 |
904 | RefineAngles(aV, myFace, aMBE, aLEI, theContext); |
c5face6f |
905 | } |
906 | } |
907 | //======================================================================= |
908 | typedef NCollection_DataMap \ |
909 | <TopoDS_Shape, Standard_Real, TopTools_ShapeMapHasher> \ |
1155d05a |
910 | TopTools_DataMapOfShapeReal; |
911 | typedef TopTools_DataMapOfShapeReal::Iterator \ |
912 | TopTools_DataMapIteratorOfDataMapOfShapeReal; |
c5face6f |
913 | // |
914 | //======================================================================= |
915 | //function : RefineAngles |
916 | //purpose : |
917 | //======================================================================= |
918 | void RefineAngles(const TopoDS_Vertex& aV, |
919 | const TopoDS_Face& myFace, |
1155d05a |
920 | const TopTools_MapOfShape& aMBE, |
51db0179 |
921 | BOPAlgo_ListOfEdgeInfo& aLEI, |
922 | const Handle(IntTools_Context)& theContext) |
c5face6f |
923 | { |
924 | Standard_Boolean bIsIn, bIsBoundary, bRefined; |
f56518cd |
925 | Standard_Integer iCntBnd, iCntInt; |
c5face6f |
926 | Standard_Real aA, aA1, aA2; |
1155d05a |
927 | TopTools_DataMapOfShapeReal aDMSR; |
c5face6f |
928 | BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI; |
929 | // |
24542bc0 |
930 | aA1=0.; // angle of outgoing edge |
931 | aA2=0.; // angle of incoming edge |
f56518cd |
932 | iCntBnd=0; |
933 | iCntInt=0; |
c5face6f |
934 | aItLEI.Initialize(aLEI); |
935 | for (; aItLEI.More(); aItLEI.Next()) { |
936 | BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue(); |
937 | const TopoDS_Edge& aE=aEI.Edge(); |
938 | bIsIn=aEI.IsIn(); |
939 | aA=aEI.Angle(); |
940 | // |
941 | if (aMBE.Contains(aE)) { |
f56518cd |
942 | ++iCntBnd; |
c5face6f |
943 | if (!bIsIn) { |
944 | aA1=aA; |
945 | } |
946 | else { |
24542bc0 |
947 | aA2=aA; |
c5face6f |
948 | } |
949 | } |
f56518cd |
950 | else { |
951 | ++iCntInt; |
952 | } |
c5face6f |
953 | } |
954 | // |
f56518cd |
955 | if (iCntBnd!=2) { |
c5face6f |
956 | return; |
957 | } |
958 | // |
24542bc0 |
959 | Standard_Real aDelta = ClockWiseAngle(aA2, aA1); |
c5face6f |
960 | aItLEI.Initialize(aLEI); |
961 | for (; aItLEI.More(); aItLEI.Next()) { |
962 | BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue(); |
963 | const TopoDS_Edge& aE=aEI.Edge(); |
964 | // |
965 | bIsBoundary=aMBE.Contains(aE); |
966 | bIsIn=aEI.IsIn(); |
967 | if (bIsBoundary || bIsIn) { |
968 | continue; |
969 | } |
970 | // |
971 | aA=aEI.Angle(); |
24542bc0 |
972 | Standard_Real aDA = ClockWiseAngle(aA2, aA); |
973 | if (aDA < aDelta) { |
974 | continue; // already inside |
c5face6f |
975 | } |
976 | // |
24542bc0 |
977 | bRefined=RefineAngle2D(aV, aE, myFace, aA1, aA2, aDelta, aA, theContext); |
c5face6f |
978 | if (bRefined) { |
979 | aDMSR.Bind(aE, aA); |
980 | } |
f56518cd |
981 | else if (iCntInt == 2) { |
982 | aA = (aA <= aA1) ? (aA1 + Precision::Angular()) : |
983 | (aA2 - Precision::Angular()); |
984 | aDMSR.Bind(aE, aA); |
985 | } |
c5face6f |
986 | } |
987 | |
988 | if (aDMSR.IsEmpty()) { |
989 | return; |
990 | } |
991 | // |
992 | // update Angles |
993 | aItLEI.Initialize(aLEI); |
994 | for (; aItLEI.More(); aItLEI.Next()) { |
995 | BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue(); |
996 | const TopoDS_Edge& aE=aEI.Edge(); |
997 | // |
998 | bIsIn=aEI.IsIn(); |
999 | if (!aDMSR.IsBound(aE)) { |
1000 | continue; |
1001 | } |
1002 | // |
1003 | aA=aDMSR.Find(aE); |
1004 | if (bIsIn) { |
1005 | aA=aA+M_PI; |
1006 | } |
1007 | // |
1008 | aEI.SetAngle(aA); |
1009 | } |
1010 | } |
1011 | //======================================================================= |
1012 | //function : RefineAngle2D |
1013 | //purpose : |
1014 | //======================================================================= |
1015 | Standard_Boolean RefineAngle2D(const TopoDS_Vertex& aV, |
1016 | const TopoDS_Edge& aE, |
1017 | const TopoDS_Face& myFace, |
1018 | const Standard_Real aA1, |
1019 | const Standard_Real aA2, |
24542bc0 |
1020 | const Standard_Real aDelta, |
51db0179 |
1021 | Standard_Real& aA, |
1022 | const Handle(IntTools_Context)& theContext) |
c5face6f |
1023 | { |
1024 | Standard_Boolean bRet; |
f56518cd |
1025 | Standard_Integer i, j, aNbP; |
1026 | Standard_Real aTV, aTol, aT1, aT2, dT, aAngle, aT, aTOp; |
c5face6f |
1027 | Standard_Real aTolInt, aAi, aXi, aYi, aT1j, aT2j, aT1max, aT2max, aCf; |
1028 | gp_Pnt2d aPV, aP, aP1, aP2; |
1029 | Handle(Geom2d_Curve) aC2D; |
1030 | Handle(Geom2d_Line) aLi; |
1031 | Geom2dAdaptor_Curve aGAC1, aGAC2; |
1032 | Geom2dInt_GInter aGInter; |
1033 | IntRes2d_Domain aDomain1, aDomain2; |
1034 | // |
1035 | bRet=Standard_True; |
1036 | aCf=0.01; |
1037 | aTolInt=1.e-10; |
1038 | // |
51db0179 |
1039 | BOPTools_AlgoTools2D::CurveOnSurface(aE, myFace, aC2D, aT1, aT2, aTol, theContext); |
94f71cad |
1040 | aGAC1.Load(aC2D, aT1, aT2); |
c5face6f |
1041 | // |
1042 | aTV=BRep_Tool::Parameter (aV, aE, myFace); |
94f71cad |
1043 | aGAC1.D0(aTV, aPV); |
c5face6f |
1044 | // |
f56518cd |
1045 | aTOp = (fabs(aTV-aT1) < fabs(aTV-aT2)) ? aT2 : aT1; |
c5face6f |
1046 | // |
24542bc0 |
1047 | const Standard_Real MaxDT = 0.3 * (aT2 - aT1); |
94f71cad |
1048 | aGAC1.D0(aT1, aP1); |
1049 | aGAC1.D0(aT2, aP2); |
c5face6f |
1050 | aDomain1.SetValues(aP1, aT1, aTolInt, aP2, aT2, aTolInt); |
1051 | // |
1052 | for (i=0; i<2; ++i) { |
24542bc0 |
1053 | aAi=(!i) ? aA1 : (aA2 + M_PI); |
c5face6f |
1054 | aXi=cos(aAi); |
1055 | aYi=sin(aAi); |
1056 | gp_Dir2d aDiri(aXi, aYi); |
1057 | aLi=new Geom2d_Line(aPV, aDiri); |
1058 | // |
1059 | aGAC2.Load(aLi); |
c5face6f |
1060 | // |
1061 | aGInter.Perform(aGAC1, aDomain1, aGAC2, aDomain2, aTolInt, aTolInt); |
1062 | if (!aGInter.IsDone()) { |
1063 | continue; |
1064 | } |
1065 | // |
24542bc0 |
1066 | aNbP = aGInter.NbPoints(); |
1067 | aT1max = aTV; |
1068 | aT2max = -1.; |
1069 | for (j = 1; j <= aNbP; ++j) { |
1070 | const IntRes2d_IntersectionPoint& aIPj = aGInter.Point(j); |
1071 | aT1j = aIPj.ParamOnFirst(); |
1072 | aT2j = aIPj.ParamOnSecond(); |
c5face6f |
1073 | // |
24542bc0 |
1074 | if (aT2j > aT2max && Abs(aT1j - aTV) < MaxDT) { |
1075 | aT2max = aT2j; |
1076 | aT1max = aT1j; |
c5face6f |
1077 | } |
1078 | } |
1079 | // |
24542bc0 |
1080 | if (aT2max > 0) { |
1081 | dT = aTOp - aT1max; |
1082 | if (Abs(dT) < aTolInt) { |
1083 | continue; |
1084 | } |
1085 | // |
1086 | aT = aT1max + aCf*dT; |
1087 | aGAC1.D0(aT, aP); |
1088 | gp_Vec2d aV2D(aPV, aP); |
1089 | gp_Dir2d aDir2D(aV2D); |
1090 | // |
1091 | aAngle = Angle(aDir2D); |
1092 | Standard_Real aDA = ClockWiseAngle(aA2, aAngle); |
1093 | if (aDA < aDelta) { |
1094 | aA = aAngle; |
1095 | return bRet; |
1096 | } |
c5face6f |
1097 | } |
1098 | }// for (i=0; i<2; ++i) { |
1099 | return !bRet; |
24542bc0 |
1100 | } |