b311480e |
1 | // Created on: 2001-01-16 |
2 | // Created by: Michael SAZONOV |
3 | // Copyright (c) 2001-2012 OPEN CASCADE SAS |
4 | // |
5 | // The content of this file is subject to the Open CASCADE Technology Public |
6 | // License Version 6.5 (the "License"). You may not use the content of this file |
7 | // except in compliance with the License. Please obtain a copy of the License |
8 | // at http://www.opencascade.org and read it completely before using this file. |
9 | // |
10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
12 | // |
13 | // The Original Code and all software distributed under the License is |
14 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
15 | // Initial Developer hereby disclaims all such warranties, including without |
16 | // limitation, any warranties of merchantability, fitness for a particular |
17 | // purpose or non-infringement. Please see the License for the specific terms |
18 | // and conditions governing the rights and limitations under the License. |
7fd59977 |
19 | |
20 | #include <QANewModTopOpe_Glue.ixx> |
21 | #include <Precision.hxx> |
22 | #include <TColgp_SequenceOfPnt.hxx> |
23 | #include <Geom_Curve.hxx> |
24 | #include <GeomProjLib.hxx> |
25 | #include <GeomAPI_ProjectPointOnSurf.hxx> |
26 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
27 | #include <TopoDS.hxx> |
28 | #include <TopoDS_Iterator.hxx> |
29 | #include <BRep_Tool.hxx> |
30 | #include <BRep_Builder.hxx> |
31 | #include <TopExp.hxx> |
32 | #include <TopExp_Explorer.hxx> |
33 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
34 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
35 | #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx> |
36 | #include <BRepExtrema_DistShapeShape.hxx> |
37 | //#include <BRepClass_FaceClassifier.hxx> |
38 | #include <BRepAlgo_EdgeConnector.hxx> |
39 | #include <BRepBuilderAPI_MakeWire.hxx> |
40 | #include <TopoDS_Iterator.hxx> |
41 | #include <BRepTopAdaptor_FClass2d.hxx> |
42 | #include <TColStd_SequenceOfReal.hxx> |
43 | #include <BRepIntCurveSurface_Inter.hxx> |
44 | #include <GeomAdaptor_Curve.hxx> |
45 | #include <TColStd_SequenceOfInteger.hxx> |
46 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
47 | #include <TColStd_Array2OfInteger.hxx> |
48 | #include <TopTools_Array2OfShape.hxx> |
49 | #include <TopOpeBRepTool_TOOL.hxx> |
50 | #include <TopTools_IndexedMapOfShape.hxx> |
51 | |
52 | //======================================================================= |
53 | //function : IsOnSurface |
54 | //purpose : static |
55 | //======================================================================= |
56 | |
57 | static Standard_Boolean |
58 | IsOnSurface (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace) |
59 | { |
60 | Standard_Real aParF, aParL, aTolEdge; |
61 | Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aParF, aParL); |
62 | if (aCurve.IsNull()) return Standard_False; |
63 | aTolEdge = BRep_Tool::Tolerance(theEdge); |
64 | Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace); |
65 | |
66 | // define check points |
67 | Standard_Real aParams[4]; |
68 | Standard_Real aDeltaRange = aParL - aParF; |
69 | aParams[0] = aParF; |
70 | aParams[1] = aParF + aDeltaRange * 0.382; |
71 | aParams[2] = aParF + aDeltaRange * 0.618; |
72 | aParams[3] = aParL; |
73 | gp_Pnt aPnt; |
74 | |
75 | // check distance to the surface |
76 | Standard_Real aTol = aTolEdge + BRep_Tool::Tolerance(theFace); |
77 | Standard_Integer i; |
78 | for (i=0; i < 4; i++) { |
79 | aPnt = aCurve->Value(aParams[i]); |
80 | GeomAPI_ProjectPointOnSurf aProjector(aPnt, aSurf); |
81 | if (!aProjector.IsDone() || aProjector.LowerDistance() > aTol) |
82 | return Standard_False; |
83 | } |
84 | |
85 | return Standard_True; |
86 | } |
87 | |
88 | //======================================================================= |
89 | //function : ProcessEdgeFaceInterference |
90 | //purpose : static |
91 | //======================================================================= |
92 | |
93 | static void |
94 | ProcessEdgeFaceInterference (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, |
95 | TopoDS_Shape& theNewFace, |
96 | TopTools_ListOfShape& theListE, |
97 | TColgp_SequenceOfPnt& thePoints1, |
98 | TColgp_SequenceOfPnt& thePoints2, |
99 | TColStd_SequenceOfInteger& theEdgeOnSurface, |
100 | TopTools_DataMapOfShapeListOfShape& theMapSubst, |
101 | TopTools_DataMapOfShapeListOfShape& theMapGener) |
102 | { |
103 | BRep_Builder aBld; |
104 | |
105 | |
106 | Standard_Boolean anIsOnSurface = IsOnSurface(theEdge, theFace); |
107 | TColgp_SequenceOfPnt aPntOfInter; |
108 | TColStd_SequenceOfReal aW; |
109 | TopTools_ListOfShape aListOfIntVert; |
110 | if(!anIsOnSurface) { |
111 | //check intersection points |
112 | BRepIntCurveSurface_Inter anInter; |
113 | Standard_Real f, l; |
114 | const TopoDS_Edge& anE = TopoDS::Edge(theEdge.Oriented(TopAbs_FORWARD)); |
115 | Handle(Geom_Curve) aC = |
116 | BRep_Tool::Curve(anE, f, l); |
117 | GeomAdaptor_Curve anAdC(aC, f, l); |
118 | anInter.Init(theFace, anAdC, Precision::PConfusion()); |
119 | for(; anInter.More(); anInter.Next()) { |
120 | if(anInter.State() == TopAbs_ON) { continue;} |
121 | aPntOfInter.Append(anInter.Pnt()); |
122 | aW.Append(anInter.W()); |
123 | } |
124 | // check vertices |
125 | |
126 | |
127 | TopoDS_Vertex aV1, aV2; |
128 | TopExp::Vertices(anE, aV1, aV2); |
129 | TopoDS_Shape aCmp; |
130 | aBld.MakeCompound(TopoDS::Compound(aCmp)); |
131 | aBld.Add(aCmp, aV1); |
132 | if(!aV1.IsSame(aV2)) aBld.Add(aCmp, aV2); |
133 | |
134 | TopoDS_Iterator anItV(theEdge); |
135 | for(; anItV.More(); anItV.Next()) { |
136 | if(anItV.Value().Orientation() == TopAbs_INTERNAL) |
137 | aBld.Add(aCmp, anItV.Value()); |
138 | } |
139 | |
140 | BRepExtrema_DistShapeShape aExtrema (theFace, aCmp); |
141 | if (aExtrema.IsDone()) { |
142 | Standard_Integer nbSol = aExtrema.NbSolution(), i, j; |
143 | Standard_Real aDist = aExtrema.Value(), aTol; |
144 | Standard_Integer n = aPntOfInter.Length(); |
145 | for (i=1; i <= nbSol; i++) { |
146 | if(aExtrema.SupportTypeShape1(i) != BRepExtrema_IsInFace) continue; |
147 | TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i); |
148 | aTol = BRep_Tool::Tolerance(TopoDS::Vertex(aS2)); |
149 | if(aDist > aTol) continue; |
150 | aListOfIntVert.Append(aS2); |
151 | //check intersection points on coincidence with vertex |
152 | gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aS2)); |
153 | for(j=1; j <= n; j++) { |
154 | if(aP.Distance(aPntOfInter(j)) > aTol) continue; |
155 | aPntOfInter.Remove(j); |
156 | aW.Remove(j); |
157 | j--; |
158 | n--; |
159 | } |
160 | } |
161 | } |
162 | } |
163 | |
164 | |
165 | TopExp_Explorer aExp (theFace.Oriented(TopAbs_FORWARD), TopAbs_EDGE); |
166 | Standard_Boolean IsNotInternal = Standard_True; |
167 | Standard_Boolean InsertVertexInBoundary = Standard_True; |
168 | Standard_Integer aN = thePoints1.Length(); |
169 | for (; aExp.More(); aExp.Next()) { |
170 | const TopoDS_Edge& aE = TopoDS::Edge (aExp.Current()); |
171 | IsNotInternal = Standard_True; |
172 | InsertVertexInBoundary = Standard_True; |
173 | if(aE.Orientation() == TopAbs_EXTERNAL) continue; |
174 | if(aE.Orientation() == TopAbs_INTERNAL) IsNotInternal = Standard_False; |
175 | // if (aE.Orientation() != TopAbs_FORWARD && |
176 | // aE.Orientation() != TopAbs_REVERSED) continue; |
177 | |
178 | BRepExtrema_DistShapeShape aExtrema (aE.Oriented(TopAbs_FORWARD), |
179 | theEdge.Oriented(TopAbs_FORWARD)); |
180 | if (!aExtrema.IsDone()) continue; |
181 | Standard_Integer nbSol = aExtrema.NbSolution(), i; |
182 | Standard_Real aDist = aExtrema.Value(); |
183 | for (i=1; i <= nbSol; i++) { |
184 | TopoDS_Shape aS1 = aExtrema.SupportOnShape1(i); |
185 | TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i); |
186 | |
187 | // check distance against tolerances |
188 | Standard_Real aTol1, aTol2; |
189 | if (aS1.ShapeType() == TopAbs_VERTEX) |
190 | aTol1 = BRep_Tool::Tolerance (TopoDS::Vertex(aS1)); |
191 | else |
192 | aTol1 = BRep_Tool::Tolerance (TopoDS::Edge(aS1)); |
193 | if (aS2.ShapeType() == TopAbs_VERTEX) |
194 | aTol2 = BRep_Tool::Tolerance (TopoDS::Vertex(aS2)); |
195 | else |
196 | aTol2 = BRep_Tool::Tolerance (TopoDS::Edge(aS2)); |
197 | if (aDist > aTol1 + aTol2) continue; |
198 | |
199 | // avoid to process the same points twice |
200 | gp_Pnt aPnt1 = aExtrema.PointOnShape1(i); |
201 | gp_Pnt aPnt2 = aExtrema.PointOnShape2(i); |
202 | Standard_Integer j; |
203 | for (j=1; j<=thePoints1.Length(); j++) { |
204 | if (aPnt1.IsEqual(thePoints1(j),Precision::Confusion()) && |
205 | aPnt2.IsEqual(thePoints2(j),Precision::Confusion())) { |
206 | // if(anIsOnSurface && (theEdgeOnSurface(j) == 1)) break; |
207 | // if(!anIsOnSurface && (theEdgeOnSurface(j) == 0)) break; |
208 | break; |
209 | } |
210 | } |
211 | if (j > aN && j <= thePoints1.Length()) continue; |
212 | if (j <= aN) { |
213 | thePoints1.Remove(j); |
214 | thePoints2.Remove(j); |
215 | theEdgeOnSurface.Remove(j); |
216 | InsertVertexInBoundary = Standard_False; |
217 | aN--; |
218 | } |
219 | thePoints1.Append (aPnt1); |
220 | thePoints2.Append (aPnt2); |
221 | theEdgeOnSurface.Append(anIsOnSurface ? 1 : 0); |
222 | // find or make the intersection vertex |
223 | TopoDS_Vertex aVerInt; |
224 | if (aS2.ShapeType() == TopAbs_VERTEX) |
225 | aVerInt = TopoDS::Vertex (aS2); |
226 | else if (aS1.ShapeType() == TopAbs_VERTEX) |
227 | aVerInt = TopoDS::Vertex (aS1); |
228 | else { |
229 | // make new vertex |
230 | Standard_Real aTol = Max (aTol1+aDist, aTol2); |
231 | aBld.MakeVertex (aVerInt, aPnt2, aTol); |
232 | } |
233 | |
234 | if (aS1.ShapeType() == TopAbs_VERTEX) { |
235 | if (!aS1.IsSame(aVerInt) && !theMapSubst.IsBound(aS1)) { |
236 | // replace vertex from Face with vertex from Edge |
237 | const TopoDS_Vertex& aVer1 = TopoDS::Vertex(aS1); |
238 | // update intersection vertex |
239 | aTol2 = Max (aTol2, aTol1 + aDist); |
240 | // Standard_Real aPar = BRep_Tool::Parameter (aVer1, aE); |
241 | gp_Pnt aP = BRep_Tool::Pnt(aVerInt); |
242 | // aBld.UpdateVertex (aVerInt, aPar, aE, aTol2); |
243 | aBld.UpdateVertex (aVerInt, aP, aTol2); |
244 | // do substitution |
245 | TopTools_ListOfShape aList; |
246 | aList.Append (aVerInt); |
247 | theMapSubst.Bind (aVer1, aList); |
248 | } |
249 | } |
250 | |
251 | else { // aS1 is the same edge as aE |
252 | // insert intersection vertex in edge from Shell as internal |
253 | Standard_Real aPar; |
254 | aExtrema.ParOnEdgeS1(i, aPar); |
255 | |
256 | if (!theMapSubst.IsBound(aS1)) { |
257 | // for Mandrake-10 - mkv,02.06.06 - theMapSubst.Bind (aE, TopTools_ListOfShape()); |
258 | TopTools_ListOfShape aListOfShape1; |
259 | theMapSubst.Bind (aE, aListOfShape1); |
260 | } |
261 | TopTools_ListOfShape& aListSubst = theMapSubst(aS1); |
262 | TopoDS_Edge aEdge; |
263 | Standard_Boolean aListWasEmpty = Standard_False; |
264 | if (aListSubst.IsEmpty()) { |
265 | aListWasEmpty = Standard_True; |
266 | aEdge = TopoDS::Edge (aS1); |
267 | } |
268 | else { |
269 | // find split by parameter |
270 | TopTools_ListIteratorOfListOfShape aIt (aListSubst); |
271 | for (; aIt.More(); aIt.Next()) { |
272 | Standard_Real aParF, aParL; |
273 | const TopoDS_Edge& aE1 = TopoDS::Edge (aIt.Value()); |
274 | BRep_Tool::Range (aE1, aParF, aParL); |
275 | if (aParF < aPar && aPar < aParL) { |
276 | aEdge = aE1; |
277 | break; |
278 | } |
279 | } |
280 | if (aIt.More()) { |
281 | aListSubst.Remove (aIt); |
282 | } |
283 | else |
284 | // unusual, needed split not found, skip to next extrema solution |
285 | continue; |
286 | } |
287 | |
288 | if(InsertVertexInBoundary) { |
289 | // TopoDS_Edge aNewEdge; |
290 | // QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVerInt, aPar, aNewEdge); |
291 | TopTools_ListOfShape aListE; |
292 | QANewModTopOpe_Glue::SplitEdgeByVertex (aEdge, aVerInt, aPar, aListE); |
293 | // aListSubst.Append (aNewEdge); |
294 | aListSubst.Append (aListE); |
295 | if (!theMapGener.IsBound(aS1)) { |
296 | // for Mandrake-10 - mkv,02.06.06 - theMapGener.Bind(aS1, TopTools_ListOfShape()); |
297 | TopTools_ListOfShape aListOfShape2; |
298 | theMapGener.Bind(aS1, aListOfShape2); |
299 | } |
300 | theMapGener(aS1).Append (aVerInt); |
301 | } |
302 | else { |
303 | if(!aListWasEmpty) aListSubst.Append(aEdge); |
304 | } |
305 | } |
306 | |
307 | Standard_Boolean isS2InternalVertex = |
308 | (aS2.ShapeType() == TopAbs_VERTEX && aS2.Orientation() == TopAbs_INTERNAL); |
309 | |
310 | if (aS2.ShapeType() == TopAbs_EDGE || isS2InternalVertex) { |
311 | // split theEdge |
312 | Standard_Real aPar; |
313 | if (isS2InternalVertex) |
314 | aPar = BRep_Tool::Parameter (aVerInt, theEdge); |
315 | else |
316 | aExtrema.ParOnEdgeS2(i, aPar); |
317 | |
318 | TopoDS_Edge aEdge; |
319 | if (theListE.IsEmpty()) { |
320 | aEdge = theEdge; |
321 | } |
322 | else { |
323 | // find split by parameter |
324 | TopTools_ListIteratorOfListOfShape aIt (theListE); |
325 | for (; aIt.More(); aIt.Next()) { |
326 | Standard_Real aParF, aParL; |
327 | const TopoDS_Edge& aE1 = TopoDS::Edge (aIt.Value()); |
328 | BRep_Tool::Range (aE1, aParF, aParL); |
329 | if (aParF < aPar && aPar < aParL) { |
330 | aEdge = aE1; |
331 | break; |
332 | } |
333 | } |
334 | if (aIt.More()) |
335 | theListE.Remove (aIt); |
336 | else |
337 | // unusual, needed split not found, skip to next extrema solution |
338 | continue; |
339 | } |
340 | |
341 | TopTools_ListOfShape aListE; |
342 | if(anIsOnSurface && IsNotInternal) { |
343 | // split aEdge |
344 | QANewModTopOpe_Glue::SplitEdgeByVertex (aEdge, aVerInt, aPar, aListE); |
345 | theListE.Append (aListE); |
346 | } |
347 | else { |
348 | //insert internal vertex in aEdge |
349 | if(!isS2InternalVertex) { |
350 | TopoDS_Edge aNewEdge; |
351 | // QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVerInt, aPar, aNewEdge); |
352 | QANewModTopOpe_Glue::SplitEdgeByVertex (aEdge, aVerInt, aPar, aListE); |
353 | // theListE.Append(aNewEdge); |
354 | theListE.Append (aListE); |
355 | if (!theMapGener.IsBound(aS2)) { |
356 | // for Mandrake-10 - mkv,02.06.06 - theMapGener.Bind(aS2, TopTools_ListOfShape()); |
357 | TopTools_ListOfShape aListOfShape3; |
358 | theMapGener.Bind(aS2, aListOfShape3); |
359 | } |
360 | theMapGener(aS2).Append (aVerInt); |
361 | } |
362 | } |
363 | |
364 | } |
365 | } |
366 | |
367 | } |
368 | |
369 | // treatmen intersection points |
370 | // insert internal vertices in face |
371 | TopTools_ListIteratorOfListOfShape aIt (aListOfIntVert); |
372 | gp_Pnt aP; |
373 | Standard_Real aTol; |
374 | theNewFace = theFace; |
375 | for(; aIt.More(); aIt.Next()) { |
376 | aP = BRep_Tool::Pnt(TopoDS::Vertex(aIt.Value())); |
377 | aTol = BRep_Tool::Tolerance(TopoDS::Vertex(aIt.Value())); |
378 | Standard_Integer j; |
379 | for (j=1; j<=thePoints1.Length(); j++) { |
380 | if (aP.IsEqual(thePoints1(j),aTol)) break; |
381 | } |
382 | if (j <= thePoints1.Length()) continue; |
383 | thePoints1.Append (aP); |
384 | thePoints2.Append (aP); |
385 | theEdgeOnSurface.Append(anIsOnSurface ? 1 : 0); |
386 | |
387 | // insert internal vertex in face; |
388 | QANewModTopOpe_Glue aFVGluing(theNewFace, aIt.Value()); |
389 | theNewFace = aFVGluing.Shape(); |
390 | } |
391 | // insert intersection vertices in face and in edge |
392 | Standard_Integer k; |
393 | for(k = 1; k <= aPntOfInter.Length(); k++) { |
394 | Standard_Integer j; |
395 | for (j=1; j<=thePoints1.Length(); j++) { |
396 | if (aPntOfInter(k).IsEqual(thePoints1(j),Precision::Confusion())) break; |
397 | } |
398 | if (j <= thePoints1.Length()) continue; |
399 | |
400 | thePoints1.Append (aPntOfInter(k)); |
401 | thePoints2.Append (aPntOfInter(k)); |
402 | theEdgeOnSurface.Append(anIsOnSurface ? 1 : 0); |
403 | |
404 | Standard_Real aPar = aW(k); |
405 | TopoDS_Vertex aV; |
406 | aBld.MakeVertex (aV, aPntOfInter(k), Precision::Confusion()); |
407 | |
408 | QANewModTopOpe_Glue aFVGluing(theNewFace, aV); |
409 | theNewFace = aFVGluing.Shape(); |
410 | if (!theMapGener.IsBound(theFace)) { |
411 | // for Mandrake-10 - mkv,02.06.06 - theMapGener.Bind(theFace, TopTools_ListOfShape()); |
412 | TopTools_ListOfShape aListOfShape4; |
413 | theMapGener.Bind(theFace, aListOfShape4); |
414 | } |
415 | theMapGener(theFace).Append (aV); |
416 | |
417 | TopoDS_Edge aEdge; |
418 | if (theListE.IsEmpty()) |
419 | aEdge = theEdge; |
420 | else { |
421 | // find split by parameter |
422 | aIt.Initialize (theListE); |
423 | for (; aIt.More(); aIt.Next()) { |
424 | Standard_Real aParF, aParL; |
425 | const TopoDS_Edge& aE1 = TopoDS::Edge (aIt.Value()); |
426 | BRep_Tool::Range (aE1, aParF, aParL); |
427 | if (aParF < aPar && aPar < aParL) { |
428 | aEdge = aE1; |
429 | break; |
430 | } |
431 | } |
432 | if (aIt.More()) |
433 | theListE.Remove (aIt); |
434 | else |
435 | // unusual, needed split not found, skip to next intersection solution |
436 | continue; |
437 | } |
438 | |
439 | // TopoDS_Edge aNewEdge; |
440 | // QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aV, aPar, aNewEdge); |
441 | // theListE.Append(aNewEdge); |
442 | TopTools_ListOfShape aListE; |
443 | QANewModTopOpe_Glue::SplitEdgeByVertex (aEdge, aV, aPar, aListE); |
444 | theListE.Append (aListE); |
445 | if (!theMapGener.IsBound(theEdge)) { |
446 | // for Mandrake-10 - mkv,02.06.06 - theMapGener.Bind(theEdge, TopTools_ListOfShape()); |
447 | TopTools_ListOfShape aListOfShape5; |
448 | theMapGener.Bind(theEdge, aListOfShape5); |
449 | } |
450 | theMapGener(theEdge).Append (aV); |
451 | |
452 | } |
453 | |
454 | |
455 | |
456 | if (theListE.IsEmpty()) |
457 | theListE.Append (theEdge); |
458 | } |
459 | |
460 | |
461 | //======================================================================= |
462 | //function : ClassifyEdgeFace |
463 | //purpose : static |
464 | //======================================================================= |
465 | |
466 | static TopAbs_State |
467 | ClassifyEdgeFace (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, |
468 | TopoDS_Edge& theEdgeOn, |
469 | const TopTools_DataMapOfShapeListOfShape& theMapSubst) |
470 | { |
471 | Standard_Real aParF, aParL, aTolEdge; |
472 | Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aParF, aParL); |
473 | if (aCurve.IsNull()) return TopAbs_OUT; |
474 | aTolEdge = BRep_Tool::Tolerance(theEdge); |
475 | Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace); |
476 | |
477 | // define check points |
478 | Standard_Real aParams[4]; |
479 | Standard_Real aDeltaRange = aParL - aParF; |
480 | aParams[0] = aParF; |
481 | aParams[1] = aParF + aDeltaRange * 0.382; |
482 | aParams[2] = aParF + aDeltaRange * 0.618; |
483 | aParams[3] = aParL; |
484 | gp_Pnt aPnts[4]; |
485 | gp_Pnt2d aPnts2d[4]; |
486 | |
487 | // check distance to the surface |
488 | Standard_Real aTol = aTolEdge + BRep_Tool::Tolerance(theFace); |
489 | Standard_Integer i; |
490 | for (i=0; i < 4; i++) { |
491 | aPnts[i] = aCurve->Value(aParams[i]); |
492 | GeomAPI_ProjectPointOnSurf aProjector(aPnts[i], aSurf); |
493 | if (!aProjector.IsDone() || aProjector.LowerDistance() > aTol) |
494 | return TopAbs_OUT; |
495 | Standard_Real u,v; |
496 | aProjector.LowerDistanceParameters(u,v); |
497 | aPnts2d[i].SetCoord(u,v); |
498 | } |
499 | |
500 | // check distance to edges |
501 | TopExp_Explorer aExp (theFace, TopAbs_EDGE); |
502 | for (; aExp.More(); aExp.Next()) { |
503 | const TopoDS_Shape& aE = aExp.Current(); |
504 | // if (aE.Orientation() == TopAbs_FORWARD || aE.Orientation() == TopAbs_REVERSED) { |
505 | if (aE.Orientation() != TopAbs_EXTERNAL) { |
506 | TopTools_ListOfShape aListSingle; |
507 | TopTools_ListIteratorOfListOfShape aIt; |
508 | if (theMapSubst.IsBound(aE)) { |
509 | aIt.Initialize (theMapSubst(aE)); |
510 | } |
511 | else { |
512 | aListSingle.Append (aE); |
513 | aIt.Initialize (aListSingle); |
514 | } |
515 | |
516 | for (; aIt.More(); aIt.Next()) { // for each split |
517 | const TopoDS_Edge& aE1 = TopoDS::Edge (aIt.Value()); |
518 | Standard_Real aPF, aPL; |
519 | Handle(Geom_Curve) aCrv = BRep_Tool::Curve(aE1, aPF, aPL); |
520 | if (aCrv.IsNull()) continue; |
521 | Standard_Real aTol1 = aTolEdge + BRep_Tool::Tolerance(aE1); |
522 | |
523 | for (i=0; i < 4; i++) { |
524 | GeomAPI_ProjectPointOnCurve aProjector(aPnts[i], aCrv, aPF, aPL); |
525 | if (aProjector.NbPoints() == 0 || aProjector.LowerDistance() > aTol1) |
526 | break; |
527 | } |
528 | if (i == 4) { // all points are on an edge |
529 | theEdgeOn = aE1; |
530 | return TopAbs_ON; |
531 | } |
532 | } |
533 | } |
534 | } |
535 | |
536 | // use 2d face classifier |
537 | // BRepClass_FaceClassifier aClf; |
538 | BRepTopAdaptor_FClass2d aClf(theFace, Precision::PConfusion()); |
539 | for (i=0; i < 4; i++) { |
540 | if (aClf.Perform (aPnts2d[i]) == TopAbs_OUT) |
541 | return TopAbs_OUT; |
542 | } |
543 | |
544 | return TopAbs_IN; |
545 | } |
546 | |
547 | //======================================================================= |
548 | //function : UpdateEdgeOnFace |
549 | //purpose : static |
550 | //======================================================================= |
551 | |
552 | static Standard_Boolean |
553 | UpdateEdgeOnFace (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace) |
554 | { |
555 | BRep_Builder aBld; |
556 | Standard_Real aPF, aPL, aTolEdge; |
557 | Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aPF, aPL); |
558 | if (aCurve.IsNull()) return Standard_False; |
559 | Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace); |
560 | if (aSurf.IsNull()) return Standard_False; |
561 | aTolEdge = BRep_Tool::Tolerance(theEdge); |
562 | |
563 | Standard_Real aTolApprox = Max (aTolEdge, BRep_Tool::Tolerance(theFace)); |
564 | Handle(Geom2d_Curve) aCrv2d = GeomProjLib::Curve2d (aCurve, aPF, aPL, aSurf, |
565 | aTolApprox); |
566 | if (!aCrv2d.IsNull()) { |
567 | aTolEdge = Max (aTolEdge, aTolApprox); |
568 | aBld.UpdateEdge (theEdge, aCrv2d, theFace, aTolEdge); |
569 | return Standard_True; |
570 | } |
571 | return Standard_False; |
572 | } |
573 | |
574 | //======================================================================= |
575 | //function : PerformShellWire |
576 | //purpose : |
577 | //======================================================================= |
578 | |
579 | void |
580 | QANewModTopOpe_Glue::PerformShellWire() |
581 | { |
582 | Standard_Boolean anOnlyOneFace = Standard_False; |
583 | BRep_Builder aBld; |
584 | if(myS1.ShapeType() == TopAbs_FACE) { |
585 | TopoDS_Shape aShell; |
586 | aBld.MakeShell(TopoDS::Shell(aShell)); |
587 | aBld.Add(aShell, myS1); |
588 | myS1 = aShell; |
589 | anOnlyOneFace = Standard_True; |
590 | } |
591 | |
592 | if(myS2.ShapeType() == TopAbs_EDGE) { |
593 | myS2 = BRepBuilderAPI_MakeWire(TopoDS::Edge(myS2)); |
594 | } |
595 | |
596 | TopoDS_Shape aS1F = myS1.Oriented(TopAbs_FORWARD); |
597 | TopoDS_Shape aS2F = myS2.Oriented(TopAbs_FORWARD); |
598 | BRepExtrema_DistShapeShape aExtrema (aS1F, aS2F); |
599 | if (!aExtrema.IsDone()) |
600 | return; |
601 | |
602 | TopTools_IndexedDataMapOfShapeListOfShape aMapAnc1; |
603 | TopExp::MapShapesAndAncestors (aS1F, TopAbs_VERTEX, TopAbs_EDGE, aMapAnc1); |
604 | TopExp::MapShapesAndAncestors (aS1F, TopAbs_VERTEX, TopAbs_FACE, aMapAnc1); |
605 | TopExp::MapShapesAndAncestors (aS1F, TopAbs_EDGE, TopAbs_FACE, aMapAnc1); |
606 | TopTools_IndexedDataMapOfShapeListOfShape aMapAnc2; |
607 | TopExp::MapShapesAndAncestors (aS2F, TopAbs_VERTEX, TopAbs_EDGE, aMapAnc2); |
608 | TopExp::MapShapesAndAncestors (aS2F, TopAbs_EDGE, TopAbs_WIRE, aMapAnc2); |
609 | TopTools_IndexedDataMapOfShapeListOfShape aMapFE; |
610 | |
611 | // process extrema points |
612 | Standard_Boolean anIsCoincided = Standard_False; |
613 | Standard_Integer nbSol = aExtrema.NbSolution(), i; |
614 | Standard_Real aDist = aExtrema.Value(); |
615 | for (i=1; i <= nbSol; i++) { |
616 | TopoDS_Shape aS1 = aExtrema.SupportOnShape1(i); |
617 | TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i); |
618 | |
619 | // check distance against tolerances |
620 | Standard_Real aTol1, aTol2; |
621 | if (aS1.ShapeType() == TopAbs_VERTEX) |
622 | aTol1 = BRep_Tool::Tolerance (TopoDS::Vertex(aS1)); |
623 | else if (aS1.ShapeType() == TopAbs_EDGE) |
624 | aTol1 = BRep_Tool::Tolerance (TopoDS::Edge(aS1)); |
625 | else |
626 | aTol1 = BRep_Tool::Tolerance (TopoDS::Face(aS1)); |
627 | if (aS2.ShapeType() == TopAbs_VERTEX) |
628 | aTol2 = BRep_Tool::Tolerance (TopoDS::Vertex(aS2)); |
629 | else |
630 | aTol2 = BRep_Tool::Tolerance (TopoDS::Edge(aS2)); |
631 | if (aDist > aTol1 + aTol2) continue; |
632 | |
633 | anIsCoincided = Standard_True; |
634 | |
635 | // determine contacted faces from Shell and edges from Wire |
636 | // and remember them in the map |
637 | TopTools_ListOfShape aListF, aListE; |
638 | if (aS1.ShapeType() == TopAbs_FACE) { |
639 | aListF.Append (aS1); |
640 | } |
641 | else { |
642 | TopTools_ListIteratorOfListOfShape aIt (aMapAnc1.FindFromKey(aS1)); |
643 | for (; aIt.More(); aIt.Next()) |
644 | if (aIt.Value().ShapeType() == TopAbs_FACE) |
645 | aListF.Append (aIt.Value()); |
646 | } |
647 | if (aS2.ShapeType() == TopAbs_EDGE) { |
648 | aListE.Append (aS2); |
649 | } |
650 | else { |
651 | TopTools_ListIteratorOfListOfShape aIt (aMapAnc2.FindFromKey(aS2)); |
652 | for (; aIt.More(); aIt.Next()) |
653 | aListE.Append (aIt.Value()); |
654 | } |
655 | TopTools_ListIteratorOfListOfShape aItF (aListF); |
656 | for (; aItF.More(); aItF.Next()) { |
657 | if (!aMapFE.Contains (aItF.Value())) { |
658 | // for Mandrake-10 - mkv,02.06.06 - aMapFE.Add (aItF.Value(), TopTools_ListOfShape()); |
659 | TopTools_ListOfShape aListOfShape1; |
660 | aMapFE.Add (aItF.Value(), aListOfShape1); |
661 | } |
662 | TopTools_ListOfShape& aLE = aMapFE.ChangeFromKey(aItF.Value()); |
663 | TopTools_MapOfShape aMapE; |
664 | TopTools_ListIteratorOfListOfShape aItE (aLE); |
665 | for (; aItE.More(); aItE.Next()) |
666 | aMapE.Add (aItE.Value()); |
667 | for (aItE.Initialize (aListE); aItE.More(); aItE.Next()) |
668 | if (!aMapE.Contains (aItE.Value())) |
669 | aLE.Append(aItE.Value()); |
670 | } |
671 | } |
672 | |
673 | |
674 | if(!anIsCoincided) return; |
675 | |
676 | // for each touched face make wire and add it in face as internal |
677 | |
678 | TopTools_MapOfShape aMapUsedEdges; |
679 | TColgp_SequenceOfPnt aPoints1; |
680 | TColgp_SequenceOfPnt aPoints2; |
681 | TColStd_SequenceOfInteger aEdgeOnSurface; |
682 | TopTools_DataMapOfShapeListOfShape aMapSubst; |
683 | for (i=1; i <= aMapFE.Extent(); i++) { |
684 | const TopoDS_Face& aFace = TopoDS::Face (aMapFE.FindKey(i)); |
685 | TopoDS_Shape aNewFace; |
686 | |
687 | // form the new wire: |
688 | // get all edges contacting the face, split them by the face boundary, |
689 | // get those splits which are inside the face. |
690 | Standard_Boolean isWireMade = Standard_False; |
691 | TopoDS_Shape aWire; |
692 | aBld.MakeWire (TopoDS::Wire (aWire)); |
693 | TopTools_ListIteratorOfListOfShape aIt (aMapFE(i)); |
694 | for (; aIt.More(); aIt.Next()) { // for each edge contacting the face |
695 | const TopoDS_Shape& aEdge = aIt.Value(); |
696 | if (aMapUsedEdges.Contains(aEdge)) continue; |
697 | |
698 | TopTools_ListOfShape aListSingle; |
699 | aListSingle.Append (aEdge); |
700 | TopTools_ListOfShape& aListRef = (aMapSubst.IsBound(aEdge) |
701 | ? aMapSubst(aEdge) |
702 | : aListSingle); |
703 | TopTools_ListIteratorOfListOfShape aIt1 (aListRef); |
704 | while (aIt1.More()) { // for each old split |
705 | const TopoDS_Edge& aE1 = TopoDS::Edge (aIt1.Value()); |
706 | if (!aMapUsedEdges.Contains(aE1)) { |
707 | TopTools_ListOfShape aListE; |
708 | ProcessEdgeFaceInterference (aE1, aFace, aNewFace, aListE, aPoints1, aPoints2, |
709 | aEdgeOnSurface, aMapSubst, myMapGener); |
710 | TopTools_ListIteratorOfListOfShape aIt2 (aListE); |
711 | for (aIt2.Initialize(aListE); aIt2.More(); aIt2.Next()) { |
712 | const TopoDS_Edge& aE2 = TopoDS::Edge (aIt2.Value()); |
713 | TopoDS_Edge aEon; |
714 | TopAbs_State aState = ClassifyEdgeFace (aE2, aFace, aEon, aMapSubst); |
715 | if (aState == TopAbs_IN ) { |
716 | if (UpdateEdgeOnFace (aE2, aFace)) { |
717 | isWireMade = Standard_True; |
718 | aBld.Add (aWire, aE2); |
719 | aMapUsedEdges.Add (aE2); |
720 | if (!myMapGener.IsBound(aFace)) { |
721 | // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aFace, TopTools_ListOfShape()); |
722 | TopTools_ListOfShape aListOfShape2; |
723 | myMapGener.Bind(aFace, aListOfShape2); |
724 | } |
725 | myMapGener(aFace).Append (aE2); |
726 | } |
727 | } |
728 | else if(aState == TopAbs_ON) { |
729 | aMapUsedEdges.Add (aE2); |
730 | } |
731 | } |
732 | Standard_Boolean IsTheSame = Standard_False; |
733 | if(aListE.Extent() == 1) { |
734 | IsTheSame = aE1.IsSame(aListE.First()); |
735 | } |
736 | if (aListE.Extent() > 1 || !IsTheSame) { |
737 | // replace old split with new splits |
738 | if (aMapSubst.IsBound(aEdge)) { |
739 | aListRef.InsertBefore (aListE, aIt1); |
740 | aListRef.Remove (aIt1); |
741 | continue; |
742 | } |
743 | else aMapSubst.Bind (aEdge, aListE); |
744 | } |
745 | } |
746 | aIt1.Next(); |
747 | } |
748 | } |
749 | |
750 | if(!aNewFace.IsSame(aFace) && !aNewFace.IsNull()) { |
751 | if(!aMapSubst.IsBound(aFace)) { |
752 | // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aFace, TopTools_ListOfShape()); |
753 | TopTools_ListOfShape aListOfShape3; |
754 | aMapSubst.Bind (aFace, aListOfShape3); |
755 | } |
756 | aMapSubst(aFace).Append(aNewFace); |
757 | } |
758 | |
759 | if (isWireMade) { |
760 | // add new wire to face |
761 | TopoDS_Shape aDummy = aNewFace.EmptyCopied().Oriented(TopAbs_FORWARD); |
762 | TopoDS_Face aNewFace1 = TopoDS::Face (aDummy); |
763 | aBld.NaturalRestriction (aNewFace1, BRep_Tool::NaturalRestriction(aFace)); |
764 | TopoDS_Iterator aIterF (aNewFace, Standard_False); |
765 | for (; aIterF.More(); aIterF.Next()) { |
766 | aBld.Add (aNewFace1, aIterF.Value()); |
767 | } |
768 | aWire = FindWireOrUpdateMap (aWire, aMapAnc2); |
769 | aBld.Add (aNewFace1, aWire.Oriented(TopAbs_INTERNAL)); |
770 | // do substitution |
771 | TopTools_ListOfShape aList; |
772 | aList.Append (aNewFace1.Oriented(aFace.Orientation())); |
773 | if(aMapSubst.IsBound(aFace)) aMapSubst.UnBind(aFace); |
774 | aMapSubst.Bind (aFace, aList); |
775 | } |
776 | } |
777 | |
778 | // make wires from the left edges |
779 | |
780 | // if (!aMapUsedEdges.IsEmpty()) { |
781 | Handle(BRepAlgo_EdgeConnector) aConnector = new BRepAlgo_EdgeConnector; |
782 | // TopoDS_Iterator aIterW (myS2, Standard_False); |
783 | TopExp_Explorer anExpW (myS2, TopAbs_EDGE); |
784 | for (; anExpW.More(); anExpW.Next()) { |
785 | const TopoDS_Edge& aEdge = TopoDS::Edge (anExpW.Current()); |
786 | if (aMapUsedEdges.Contains(aEdge)) continue; |
787 | |
788 | if (aMapSubst.IsBound(aEdge)) { |
789 | TopTools_ListIteratorOfListOfShape aIt (aMapSubst(aEdge)); |
790 | for (; aIt.More(); aIt.Next()) { // for each old split |
791 | if (aMapUsedEdges.Contains(aIt.Value())) continue; |
792 | aConnector->Add (TopoDS::Edge(aIt.Value())); |
793 | aConnector->AddStart (TopoDS::Edge(aIt.Value())); |
794 | } |
795 | } |
796 | else { |
797 | aConnector->Add (aEdge); |
798 | aConnector->AddStart (aEdge); |
799 | } |
800 | } |
801 | |
802 | // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind (myS2, TopTools_ListOfShape()); |
803 | TopTools_ListOfShape aListOfShape4; |
804 | myMapModif.Bind (myS2, aListOfShape4); |
805 | TopTools_ListOfShape& aListW = aConnector->MakeBlock(); |
806 | if (aConnector->IsDone()) { |
807 | // TopAbs_Orientation aOri = myS2.Orientation(); |
808 | TopTools_ListIteratorOfListOfShape aIt (aListW); |
809 | // for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri); |
810 | myMapModif(myS2).Append (aListW); |
811 | } |
812 | // } |
813 | |
814 | // construct the result |
815 | |
816 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aIterM(aMapSubst); |
817 | |
818 | for (; aIterM.More(); aIterM.Next()) { |
819 | TopAbs_Orientation aOri = TopAbs_FORWARD; |
820 | TopTools_ListIteratorOfListOfShape aIt (aIterM.Value()); |
821 | for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri); |
822 | if(!aIterM.Value().IsEmpty()) mySubst.Substitute (aIterM.Key(), aIterM.Value()); |
823 | aOri = aIterM.Key().Orientation(); |
824 | aIt.Initialize (aIterM.Value()); |
825 | for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri); |
826 | if(!aIterM.Value().IsEmpty()) myMapModif.Bind (aIterM.Key(), aIterM.Value()); |
827 | } |
828 | |
829 | if(anIsCoincided) { |
830 | TopoDS_Shape aNewS1 = myS1; |
831 | mySubst.Build(myS1); |
832 | if (mySubst.IsCopied(myS1)) { |
833 | aNewS1 = mySubst.Copy(myS1).First(); |
834 | if(aNewS1.ShapeType() == TopAbs_SHELL && anOnlyOneFace) { |
835 | TopoDS_Iterator anIter(aNewS1); |
836 | aNewS1 = anIter.Value(); |
837 | } |
838 | aNewS1.Orientation(myS1.Orientation()); |
839 | } |
840 | |
841 | if (myMapModif.IsBound (myS2) && myMapModif(myS2).IsEmpty()) { |
842 | // all wire is on shell |
843 | myShape = aNewS1; |
844 | myMapModif.UnBind (myS2); |
845 | } |
846 | else { |
847 | // all wire or part of wire is out of shell |
848 | aBld.MakeCompound (TopoDS::Compound(myShape)); |
849 | aBld.Add(myShape, aNewS1); |
850 | if (myMapModif.IsBound (myS2)) { |
851 | TopTools_ListIteratorOfListOfShape aIt (myMapModif(myS2)); |
852 | for (; aIt.More(); aIt.Next()) { |
853 | // check if wire contains only one edge |
854 | TopoDS_Iterator aTDIt(aIt.Value()); |
855 | TopoDS_Shape anE = aTDIt.Value(); |
856 | aTDIt.Next(); |
857 | if(aTDIt.More()) aBld.Add (myShape, aIt.Value()); |
858 | else aBld.Add (myShape, anE); |
859 | } |
860 | } |
861 | else aBld.Add (myShape, myS2); |
862 | } |
863 | |
864 | Done(); |
865 | } |
866 | } |
867 | |
868 | //======================================================================= |
869 | //function : IsOverlapped |
870 | //purpose : Checks if theEdge2 lies on theEdge1. It is known that the |
871 | // boundary vertices of theEdge2 lie on theEdge1. |
872 | //======================================================================= |
873 | |
874 | static Standard_Boolean IsOverlapped(const TopoDS_Edge &theEdge1, |
875 | const TopoDS_Edge &theEdge2) |
876 | { |
877 | Standard_Real aParF1, aParL1; |
878 | Standard_Real aParF2, aParL2; |
879 | Handle(Geom_Curve) aC1 = BRep_Tool::Curve(theEdge1, aParF1, aParL1); |
880 | Handle(Geom_Curve) aC2 = BRep_Tool::Curve(theEdge2, aParF2, aParL2); |
881 | |
882 | if (aC1.IsNull() || aC2.IsNull()) |
883 | return Standard_False; |
884 | |
885 | GeomAdaptor_Curve aGAC1(aC1, aParF1, aParL1); |
886 | GeomAdaptor_Curve aGAC2(aC2, aParF2, aParL2); |
887 | Extrema_ExtPC anExtPC; |
888 | Standard_Integer aNbPoints = 5; |
889 | Standard_Real aDelta = (aParL2 - aParF2)/(aNbPoints + 1.); |
890 | Standard_Real aCurPar = aParF2 + aDelta; |
891 | Standard_Integer i; |
892 | Standard_Real aMaxDist = Max(BRep_Tool::Tolerance(theEdge1), |
893 | BRep_Tool::Tolerance(theEdge2)); |
894 | |
895 | anExtPC.Initialize(aGAC1, aParF1, aParL1); |
896 | |
897 | for (i = 1; i <= aNbPoints; i++) { |
898 | gp_Pnt aPnt = aGAC2.Value(aCurPar); |
899 | |
900 | anExtPC.Perform(aPnt); |
901 | |
902 | if (!anExtPC.IsDone()) |
903 | return Standard_False; |
904 | |
905 | Standard_Integer j; |
906 | Standard_Integer aNbExt = anExtPC.NbExt(); |
907 | Standard_Boolean isPOnC1 = Standard_False; |
908 | |
909 | for (j = 1; j <= aNbExt && !isPOnC1; j++) { |
910 | if (anExtPC.IsMin(j)) { |
911 | gp_Pnt anExtP = anExtPC.Point(j).Value(); |
912 | |
913 | isPOnC1 = (aPnt.Distance(anExtP) <= aMaxDist); |
914 | } |
915 | } |
916 | if (!isPOnC1) |
917 | return Standard_False; |
918 | |
919 | aCurPar += aDelta; |
920 | } |
921 | |
922 | return Standard_True; |
923 | } |
924 | |
925 | //======================================================================= |
926 | //function : SplitEdge |
927 | //purpose : This function splits the edge into subedges by two given vertices. |
928 | //======================================================================= |
929 | |
930 | static void SplitEdge(const TopoDS_Edge &theEdge, |
d3f26155 |
931 | const TopTools_IndexedMapOfShape &theVertices, |
932 | TopTools_ListOfShape &theSplits) |
7fd59977 |
933 | { |
934 | //const TopoDS_Edge aNewEdge; |
935 | TopoDS_Vertex aV1; |
936 | TopoDS_Vertex aV2; |
937 | BRep_Builder aBuilder; |
938 | |
939 | TopoDS_Edge aNewEdge = TopoDS::Edge(theEdge.Oriented(TopAbs_FORWARD).EmptyCopied()); |
940 | TopExp::Vertices(theEdge, aV1, aV2); |
941 | aBuilder.Add(aNewEdge, aV1); |
942 | |
943 | // Construction of the copied edge with |
944 | // the internal vertices of the map theVertices. |
945 | |
946 | Standard_Integer i; |
947 | |
d3f26155 |
948 | for (i = 1; i <= theVertices.Extent(); i++) |
949 | { |
7fd59977 |
950 | const TopoDS_Shape &theVtx = theVertices.FindKey(i); |
951 | |
952 | if (!aV1.IsSame(theVtx) && !aV2.IsSame(theVtx)) |
953 | aBuilder.Add(aNewEdge, theVtx.Oriented(TopAbs_INTERNAL)); |
954 | } |
955 | |
956 | aBuilder.Add(aNewEdge, aV2); |
957 | |
958 | theSplits.Clear(); |
959 | |
d3f26155 |
960 | // Splitting of the new edge. |
7fd59977 |
961 | if (!TopOpeBRepTool_TOOL::SplitE(aNewEdge, theSplits)) { |
962 | theSplits.Clear(); |
963 | theSplits.Append(theEdge); |
964 | |
965 | return; |
966 | } |
967 | |
d3f26155 |
968 | // Addition of the other internal vertices into the corresponding splits. |
7fd59977 |
969 | TopoDS_Iterator anIter(theEdge, Standard_False); |
970 | |
d3f26155 |
971 | for (; anIter.More(); anIter.Next()) |
972 | { |
7fd59977 |
973 | TopoDS_Vertex aCurVtx = TopoDS::Vertex(anIter.Value()); |
974 | |
d3f26155 |
975 | // for each vertex which is not the same as aV1, aV2, theIntV1 or theIntV2. |
976 | if (!aCurVtx.IsSame(aV1) && !aCurVtx.IsSame(aV2) && !theVertices.Contains(aCurVtx)) |
977 | { |
7fd59977 |
978 | TopTools_ListIteratorOfListOfShape anEdgeIter(theSplits); |
d3f26155 |
979 | Standard_Real aCurPar = BRep_Tool::Parameter(aCurVtx, theEdge); |
7fd59977 |
980 | |
d3f26155 |
981 | // Search for the split the current vertex belongs to. |
982 | for (; anEdgeIter.More(); anEdgeIter.Next()) |
983 | { |
984 | TopoDS_Edge anEdge = TopoDS::Edge(anEdgeIter.Value()); |
985 | Standard_Real aFPar; |
986 | Standard_Real aLPar; |
7fd59977 |
987 | |
d3f26155 |
988 | BRep_Tool::Range(anEdge, aFPar, aLPar); |
7fd59977 |
989 | |
d3f26155 |
990 | if (aCurPar > aFPar && aCurPar < aLPar) |
991 | { |
992 | aBuilder.Add(anEdge, aCurVtx); |
993 | } |
994 | break; |
7fd59977 |
995 | } |
996 | } |
997 | } |
998 | |
999 | // Setting the orientation of each split equal to the orientation of theEdge. |
1000 | TopTools_ListIteratorOfListOfShape anEdgeIter(theSplits); |
1001 | TopAbs_Orientation anOri = theEdge.Orientation(); |
1002 | |
d3f26155 |
1003 | for (; anEdgeIter.More(); anEdgeIter.Next()) |
1004 | { |
7fd59977 |
1005 | TopoDS_Shape &anEdge = anEdgeIter.Value(); |
7fd59977 |
1006 | anEdge.Orientation(anOri); |
1007 | } |
1008 | } |
1009 | |
1010 | //======================================================================= |
1011 | //function : RemoveCommonPart |
1012 | //purpose : |
1013 | //======================================================================= |
1014 | |
1015 | static void RemoveCommonPart |
1016 | (const TopoDS_Edge &theE1, |
1017 | const TopoDS_Edge &theE2, |
1018 | TopTools_DataMapOfShapeListOfShape &theMapSubst) |
1019 | { |
1020 | if (theMapSubst.IsBound(theE1)) { |
1021 | const TopTools_ListOfShape &aLOfE1 = theMapSubst.Find(theE1); |
1022 | TopTools_ListIteratorOfListOfShape anIter(aLOfE1); |
1023 | |
1024 | // For each split in the list aLOfE1 recursively call this function. |
1025 | for (; anIter.More(); anIter.Next()) { |
1026 | TopoDS_Edge anEdge1 = TopoDS::Edge(anIter.Value()); |
1027 | |
1028 | RemoveCommonPart(anEdge1, theE2, theMapSubst); |
1029 | } |
1030 | |
1031 | return; |
1032 | } |
1033 | |
1034 | if (theMapSubst.IsBound(theE2)) { |
1035 | const TopTools_ListOfShape &aLOfE2 = theMapSubst.Find(theE2); |
1036 | TopTools_ListIteratorOfListOfShape anIter(aLOfE2); |
1037 | |
1038 | // For each split in the list aLOfE2 recursively call this function. |
1039 | for (; anIter.More(); anIter.Next()) { |
1040 | TopoDS_Edge anEdge2 = TopoDS::Edge(anIter.Value()); |
1041 | |
1042 | RemoveCommonPart(theE1, anEdge2, theMapSubst); |
1043 | } |
1044 | |
1045 | return; |
1046 | } |
1047 | |
1048 | TopTools_IndexedMapOfShape aMapVtx; |
1049 | TopTools_IndexedMapOfShape aMapCommonVtx; |
1050 | |
1051 | // Searching for common vertices: |
1052 | TopExp::MapShapes(theE1, aMapVtx); |
1053 | TopoDS_Iterator anIter(theE2, Standard_False); |
1054 | |
1055 | for (; anIter.More(); anIter.Next()) { |
1056 | TopoDS_Shape aVtx = anIter.Value(); |
1057 | |
1058 | if (aMapVtx.Contains(aVtx)) { |
1059 | aMapCommonVtx.Add(aVtx); |
1060 | } |
1061 | } |
1062 | |
1063 | // If there are at least two common vertices we can check overlapping: |
1064 | if (aMapCommonVtx.Extent() <= 1) |
1065 | return; |
1066 | |
1067 | TopTools_ListOfShape aSplits; |
1068 | |
1069 | SplitEdge(theE2, aMapCommonVtx, aSplits); |
1070 | |
1071 | TopTools_ListIteratorOfListOfShape aSplitIter(aSplits); |
1072 | Standard_Boolean isModified = Standard_False; |
1073 | |
1074 | for (; aSplitIter.More();) { |
1075 | TopoDS_Edge aSplit = TopoDS::Edge(aSplitIter.Value()); |
1076 | |
1077 | if (IsOverlapped(theE1, aSplit)) { |
1078 | // Removal of overlapping split from the list of splits |
1079 | aSplits.Remove(aSplitIter); |
1080 | isModified = Standard_True; |
1081 | } else { |
1082 | aSplitIter.Next(); |
1083 | } |
1084 | } |
1085 | |
1086 | // If we deleted some splits, we should save the splits |
1087 | // of theE2 in order to use them in further overlapping checks. |
1088 | if (isModified) |
1089 | theMapSubst.Bind(theE2, aSplits); |
1090 | } |
1091 | |
1092 | //======================================================================= |
1093 | //function : GetSplits |
1094 | //purpose : This function removes returns the splits build from theEdge. |
1095 | // If there are no ones the edge itself will be added to theSplits. |
1096 | //======================================================================= |
1097 | |
1098 | static void GetSplits(const TopoDS_Shape &theEdge, |
1099 | const TopTools_DataMapOfShapeListOfShape &theMapSubst, |
1100 | TopTools_ListOfShape &theSplits) |
1101 | { |
1102 | if (theMapSubst.IsBound(theEdge)) { |
1103 | const TopTools_ListOfShape &theList = |
1104 | theMapSubst.Find(theEdge); |
1105 | TopTools_ListIteratorOfListOfShape anEdgeIter(theList); |
1106 | |
1107 | for (; anEdgeIter.More(); anEdgeIter.Next()) { |
1108 | const TopoDS_Shape &anEdge = anEdgeIter.Value(); |
1109 | |
1110 | GetSplits(anEdge, theMapSubst, theSplits); |
1111 | } |
1112 | } else { |
1113 | theSplits.Append(theEdge); |
1114 | } |
1115 | } |
1116 | |
1117 | //======================================================================= |
1118 | //function : isWireModified |
1119 | //purpose : Checks if the given wire was modified. |
1120 | //======================================================================= |
1121 | |
1122 | static Standard_Boolean isWireModified |
1123 | (const TopoDS_Shape &theWire, |
1124 | const TopTools_DataMapOfShapeListOfShape &theMapSubst) |
1125 | { |
1126 | TopExp_Explorer anExp(theWire, TopAbs_EDGE); |
1127 | |
1128 | for(; anExp.More(); anExp.Next()) { |
1129 | const TopoDS_Shape &anEdge = anExp.Current(); |
1130 | |
1131 | if (theMapSubst.IsBound(anEdge)) |
1132 | return Standard_True; |
1133 | } |
1134 | |
1135 | return Standard_False; |
1136 | } |
1137 | |
1138 | //======================================================================= |
1139 | //function : RemoveOverlappedEdges |
1140 | //purpose : This function removes doubled common parts of edges from theS2. |
1141 | //======================================================================= |
1142 | |
1143 | static TopoDS_Shape RemoveOverlappedEdges |
1144 | (const TopoDS_Shape &theS1, |
1145 | const TopoDS_Shape &theS2, |
1146 | TopTools_DataMapOfShapeListOfShape &theMapModif) |
1147 | { |
1148 | TopExp_Explorer anExp1(theS1, TopAbs_EDGE); |
1149 | TopTools_DataMapOfShapeListOfShape aMapModif; |
1150 | |
1151 | // For each couple of edges we remove a common part if any. |
1152 | for(; anExp1.More(); anExp1.Next()) { |
1153 | TopoDS_Edge anEdge1 = TopoDS::Edge(anExp1.Current()); |
1154 | TopExp_Explorer anExp2(theS2, TopAbs_EDGE); |
1155 | |
1156 | for(; anExp2.More(); anExp2.Next()) { |
1157 | TopoDS_Edge anEdge2 = TopoDS::Edge(anExp2.Current()); |
1158 | |
1159 | RemoveCommonPart(anEdge1, anEdge2, aMapModif); |
1160 | } |
1161 | } |
1162 | |
1163 | // Searching for built splits for every edge. |
1164 | TopoDS_Shape aNewS; |
1165 | TopoDS_Shape aNewS2; |
1166 | BRep_Builder aBuilder; |
1167 | |
1168 | aBuilder.MakeCompound(TopoDS::Compound(aNewS)); |
1169 | aBuilder.MakeCompound(TopoDS::Compound(aNewS2)); |
1170 | aBuilder.Add(aNewS, theS1); |
1171 | |
1172 | TopExp_Explorer anExpWire(theS2, TopAbs_WIRE); |
1173 | |
1174 | for(; anExpWire.More(); anExpWire.Next()) { |
1175 | const TopoDS_Shape &aWire = anExpWire.Current(); |
1176 | |
1177 | if (isWireModified(aWire, aMapModif)) { |
1178 | TopExp_Explorer anExpEdge(aWire, TopAbs_EDGE); |
1179 | TopoDS_Shape aNewComp; |
1180 | |
1181 | aBuilder.MakeCompound(TopoDS::Compound(aNewComp)); |
1182 | |
1183 | for(; anExpEdge.More(); anExpEdge.Next()) { |
1184 | const TopoDS_Shape &anEdge = anExpEdge.Current(); |
1185 | TopTools_ListOfShape aSplits; |
1186 | |
1187 | GetSplits(anEdge, aMapModif, aSplits); |
1188 | |
1189 | if (!aSplits.IsEmpty() && !anEdge.IsSame(aSplits.First())) { |
1190 | if (!theMapModif.IsBound(anEdge)) |
1191 | theMapModif.Bind(anEdge, aSplits); |
1192 | } else if (aSplits.IsEmpty()) { |
1193 | theMapModif.Bind(anEdge, aSplits); |
1194 | } |
1195 | |
1196 | TopTools_ListIteratorOfListOfShape aSplitIter(aSplits); |
1197 | |
1198 | for (; aSplitIter.More(); aSplitIter.Next()) { |
1199 | const TopoDS_Shape &aSplit = aSplitIter.Value(); |
1200 | |
1201 | aBuilder.Add(aNewComp, aSplit); |
1202 | } |
1203 | } |
1204 | |
1205 | // Addition of new compound if it is not empty |
1206 | TopoDS_Iterator aSubShIter(aNewComp); |
1207 | |
1208 | if (aSubShIter.More()) |
1209 | aBuilder.Add(aNewS2, aNewComp); |
1210 | } else { |
1211 | aBuilder.Add(aNewS2, aWire); |
1212 | } |
1213 | } |
1214 | |
1215 | // Addition of new shape if it is not empty |
1216 | TopoDS_Iterator aSubShIter(aNewS2); |
1217 | |
1218 | if (aSubShIter.More()) |
1219 | aBuilder.Add(aNewS, aNewS2); |
1220 | |
1221 | return aNewS; |
1222 | } |
1223 | |
1224 | //======================================================================= |
1225 | //function : FillMapModif |
1226 | //purpose : This function fills the map of modified sub-shapes of theShape |
1227 | //======================================================================= |
1228 | |
1229 | static void FillMapModif(const BRepTools_Substitution &theSubst, |
1230 | const TopoDS_Shape &theShape, |
1231 | TopTools_DataMapOfShapeListOfShape &theMapModif) |
1232 | { |
1233 | TopAbs_ShapeEnum aType = theShape.ShapeType(); |
1234 | |
1235 | if (aType == TopAbs_EDGE || aType == TopAbs_VERTEX) { |
1236 | if (theSubst.IsCopied(theShape)) { |
1237 | const TopTools_ListOfShape &aModifShapes = theSubst.Copy(theShape); |
1238 | |
1239 | if (!theMapModif.IsBound(theShape)) |
1240 | theMapModif.Bind(theShape, aModifShapes); |
1241 | } |
1242 | } |
1243 | |
1244 | TopoDS_Iterator anIter(theShape, Standard_False); |
1245 | TopTools_MapOfShape aUsedShapes; |
1246 | |
1247 | for (; anIter.More(); anIter.Next()) { |
1248 | const TopoDS_Shape &aSubShape = anIter.Value(); |
1249 | |
1250 | if (!aUsedShapes.Add(aSubShape)) |
1251 | continue; |
1252 | |
1253 | FillMapModif(theSubst, aSubShape, theMapModif); |
1254 | } |
1255 | } |
1256 | |
1257 | //======================================================================= |
1258 | //function : PerformWires |
1259 | //purpose : gluing two wires |
1260 | //======================================================================= |
1261 | |
1262 | void |
1263 | QANewModTopOpe_Glue::PerformWires() |
1264 | { |
1265 | Standard_Boolean S1IsEdge = Standard_False, S2IsEdge = Standard_False; |
1266 | if(myS1.ShapeType() == TopAbs_EDGE) { |
1267 | myS1 = BRepBuilderAPI_MakeWire(TopoDS::Edge(myS1)); |
1268 | S1IsEdge = Standard_True; |
1269 | } |
1270 | if(myS2.ShapeType() == TopAbs_EDGE) { |
1271 | myS2 = BRepBuilderAPI_MakeWire(TopoDS::Edge(myS2)); |
1272 | S2IsEdge = Standard_True; |
1273 | } |
1274 | |
1275 | TopoDS_Shape aS1F = myS1.Oriented(TopAbs_FORWARD); |
1276 | TopoDS_Shape aS2F = myS2.Oriented(TopAbs_FORWARD); |
1277 | BRepExtrema_DistShapeShape aExtrema (aS1F, aS2F); |
1278 | if (!aExtrema.IsDone()) |
1279 | return; |
1280 | |
1281 | // process extrema points |
1282 | |
1283 | TColStd_SequenceOfInteger VVInt; |
1284 | TColStd_SequenceOfInteger VEInt; |
1285 | TColStd_SequenceOfInteger EEInt; |
1286 | |
1287 | |
1288 | Standard_Boolean anIsCoincided = Standard_False; |
1289 | Standard_Boolean S1IsVert = Standard_True; |
1290 | Standard_Boolean S2IsVert = Standard_True; |
1291 | Standard_Real aTol1, aTol2; |
1292 | Standard_Integer nbSol = aExtrema.NbSolution(), i, j, k; |
1293 | Standard_Real aDist = aExtrema.Value(); |
1294 | for (i=1; i <= nbSol; i++) { |
1295 | TopoDS_Shape aS1 = aExtrema.SupportOnShape1(i); |
1296 | TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i); |
1297 | S1IsVert = Standard_True; |
1298 | S2IsVert = Standard_True; |
1299 | // check distance against tolerances |
1300 | if (aS1.ShapeType() == TopAbs_VERTEX) |
1301 | aTol1 = BRep_Tool::Tolerance (TopoDS::Vertex(aS1)); |
1302 | else { |
1303 | aTol1 = BRep_Tool::Tolerance (TopoDS::Edge(aS1)); |
1304 | S1IsVert = Standard_False; |
1305 | } |
1306 | |
1307 | if (aS2.ShapeType() == TopAbs_VERTEX) |
1308 | aTol2 = BRep_Tool::Tolerance (TopoDS::Vertex(aS2)); |
1309 | else { |
1310 | aTol2 = BRep_Tool::Tolerance (TopoDS::Edge(aS2)); |
1311 | S2IsVert = Standard_False; |
1312 | } |
1313 | |
1314 | if (aDist > aTol1 + aTol2) continue; |
1315 | |
1316 | anIsCoincided = Standard_True; |
1317 | |
1318 | if(S1IsVert && S2IsVert) { |
1319 | if(!aS1.IsSame(aS2)) VVInt.Append(i); |
1320 | } |
1321 | else if(S1IsVert || S2IsVert) |
1322 | VEInt.Append(i); |
1323 | else |
1324 | EEInt.Append(i); |
1325 | } |
1326 | |
1327 | if(!anIsCoincided) return; |
1328 | |
1329 | BRep_Builder aBld; |
1330 | TColgp_SequenceOfPnt aPoints1; |
1331 | TColgp_SequenceOfPnt aPoints2; |
1332 | TopTools_DataMapOfShapeListOfShape aMapSubst; |
1333 | |
1334 | for(k = 1; k <= VVInt.Length(); k++) { |
1335 | // avoid to process the same points twice |
1336 | i = VVInt(k); |
1337 | gp_Pnt aPnt1 = aExtrema.PointOnShape1(i); |
1338 | gp_Pnt aPnt2 = aExtrema.PointOnShape2(i); |
1339 | for (j=1; j<=aPoints1.Length(); j++) { |
1340 | if (aPnt1.IsEqual(aPoints1(j),Precision::Confusion()) && |
1341 | aPnt2.IsEqual(aPoints2(j),Precision::Confusion())) { |
1342 | break; |
1343 | } |
1344 | } |
1345 | if (j <= aPoints1.Length()) continue; |
1346 | aPoints1.Append (aPnt1); |
1347 | aPoints2.Append (aPnt2); |
1348 | |
1349 | const TopoDS_Vertex& aVer1 = TopoDS::Vertex(aExtrema.SupportOnShape1(i)); |
1350 | const TopoDS_Vertex& aVer2 = TopoDS::Vertex(aExtrema.SupportOnShape2(i)); |
1351 | aTol1 = BRep_Tool::Tolerance(aVer1); |
1352 | aTol2 = BRep_Tool::Tolerance(aVer2); |
1353 | aTol1 = Max(aTol1, aTol2 + aDist); |
1354 | gp_Pnt aP = BRep_Tool::Pnt(aVer1); |
1355 | aBld.UpdateVertex (aVer1, aP, aTol1); |
1356 | TopTools_ListOfShape aList; |
1357 | aList.Append (aVer1); |
1358 | aMapSubst.Bind (aVer2, aList); |
1359 | |
1360 | } |
1361 | |
1362 | for(k = 1; k <= VEInt.Length(); k++) { |
1363 | // avoid to process the same points twice |
1364 | i = VEInt(k); |
1365 | gp_Pnt aPnt1 = aExtrema.PointOnShape1(i); |
1366 | gp_Pnt aPnt2 = aExtrema.PointOnShape2(i); |
1367 | for (j=1; j<=aPoints1.Length(); j++) { |
1368 | if (aPnt1.IsEqual(aPoints1(j),Precision::Confusion()) && |
1369 | aPnt2.IsEqual(aPoints2(j),Precision::Confusion())) { |
1370 | break; |
1371 | } |
1372 | } |
1373 | if (j <= aPoints1.Length()) continue; |
1374 | aPoints1.Append (aPnt1); |
1375 | aPoints2.Append (aPnt2); |
1376 | |
1377 | TopoDS_Shape aS1 = aExtrema.SupportOnShape1(i); |
1378 | TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i); |
1379 | |
1380 | if(aS1.ShapeType() == TopAbs_VERTEX) { |
1381 | TopoDS_Vertex& aVer1 = TopoDS::Vertex(aS1); |
1382 | const TopoDS_Edge& aE2 = TopoDS::Edge(aS2); |
1383 | aTol1 = BRep_Tool::Tolerance(aVer1); |
1384 | aTol2 = BRep_Tool::Tolerance(aE2); |
1385 | aTol1 = Max(aTol1, aTol2 + aDist); |
1386 | gp_Pnt aP = BRep_Tool::Pnt(aVer1); |
1387 | aBld.UpdateVertex (aVer1, aP, aTol1); |
1388 | Standard_Real aPar; |
1389 | aExtrema.ParOnEdgeS2(i, aPar); |
1390 | if (!aMapSubst.IsBound(aE2)) { |
1391 | // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aE2, TopTools_ListOfShape()); |
1392 | TopTools_ListOfShape aListOfShape1; |
1393 | aMapSubst.Bind (aE2, aListOfShape1); |
1394 | } |
1395 | TopTools_ListOfShape& aListSubst = aMapSubst(aE2); |
1396 | TopoDS_Edge aEdge; |
1397 | if (aListSubst.IsEmpty()) { |
1398 | aEdge = aE2; |
1399 | } |
1400 | else { |
1401 | aEdge = TopoDS::Edge(aListSubst.First()); |
1402 | aListSubst.Clear(); |
1403 | } |
1404 | |
1405 | TopoDS_Edge aNewEdge; |
1406 | QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVer1, aPar, aNewEdge); |
1407 | aListSubst.Append (aNewEdge); |
1408 | } |
1409 | else { |
1410 | TopoDS_Vertex& aVer1 = TopoDS::Vertex(aS2); |
1411 | const TopoDS_Edge& aE2 = TopoDS::Edge(aS1); |
1412 | aTol1 = BRep_Tool::Tolerance(aVer1); |
1413 | aTol2 = BRep_Tool::Tolerance(aE2); |
1414 | aTol1 = Max(aTol1, aTol2 + aDist); |
1415 | gp_Pnt aP = BRep_Tool::Pnt(aVer1); |
1416 | aBld.UpdateVertex (aVer1, aP, aTol1); |
1417 | Standard_Real aPar; |
1418 | aExtrema.ParOnEdgeS1(i, aPar); |
1419 | if (!aMapSubst.IsBound(aE2)) { |
1420 | // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aE2, TopTools_ListOfShape()); |
1421 | TopTools_ListOfShape aListOfShape2; |
1422 | aMapSubst.Bind (aE2, aListOfShape2); |
1423 | } |
1424 | TopTools_ListOfShape& aListSubst = aMapSubst(aE2); |
1425 | TopoDS_Edge aEdge; |
1426 | if (aListSubst.IsEmpty()) { |
1427 | aEdge = aE2; |
1428 | } |
1429 | else { |
1430 | aEdge = TopoDS::Edge(aListSubst.First()); |
1431 | aListSubst.Clear(); |
1432 | } |
1433 | |
1434 | TopoDS_Edge aNewEdge; |
1435 | QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVer1, aPar, aNewEdge); |
1436 | aListSubst.Append (aNewEdge); |
1437 | } |
1438 | } |
1439 | |
1440 | for(k = 1; k <= EEInt.Length(); k++) { |
1441 | // avoid to process the same points twice |
1442 | i = EEInt(k); |
1443 | gp_Pnt aPnt1 = aExtrema.PointOnShape1(i); |
1444 | gp_Pnt aPnt2 = aExtrema.PointOnShape2(i); |
1445 | for (j=1; j<=aPoints1.Length(); j++) { |
1446 | if (aPnt1.IsEqual(aPoints1(j),Precision::Confusion()) && |
1447 | aPnt2.IsEqual(aPoints2(j),Precision::Confusion())) { |
1448 | break; |
1449 | } |
1450 | } |
1451 | if (j <= aPoints1.Length()) continue; |
1452 | aPoints1.Append (aPnt1); |
1453 | aPoints2.Append (aPnt2); |
1454 | |
1455 | const TopoDS_Edge& aE1 = TopoDS::Edge(aExtrema.SupportOnShape1(i)); |
1456 | const TopoDS_Edge& aE2 = TopoDS::Edge(aExtrema.SupportOnShape2(i)); |
1457 | |
1458 | aTol1 = BRep_Tool::Tolerance(aE1); |
1459 | aTol2 = BRep_Tool::Tolerance(aE2); |
1460 | gp_Pnt aP((aPnt1.X() + aPnt2.X())*.5, (aPnt1.Y() + aPnt2.Y())*.5, (aPnt1.Z() + aPnt2.Z())*.5); |
1461 | aTol1 = Max(aTol1+.5*aDist, aTol2+.5*aDist); |
1462 | aTol1 = Max(aTol1, Precision::Confusion()); |
1463 | |
1464 | TopoDS_Vertex aVer; |
1465 | aBld.MakeVertex(aVer, aP, aTol1); |
1466 | |
1467 | Standard_Real aPar; |
1468 | aExtrema.ParOnEdgeS1(i, aPar); |
1469 | if (!aMapSubst.IsBound(aE1)) { |
1470 | // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aE1, TopTools_ListOfShape()); |
1471 | TopTools_ListOfShape aListOfShape3; |
1472 | aMapSubst.Bind (aE1, aListOfShape3); |
1473 | } |
1474 | TopTools_ListOfShape& aListSubst1 = aMapSubst(aE1); |
1475 | TopoDS_Edge aEdge; |
1476 | if (aListSubst1.IsEmpty()) { |
1477 | aEdge = aE1; |
1478 | } |
1479 | else { |
1480 | aEdge = TopoDS::Edge(aListSubst1.First()); |
1481 | aListSubst1.Clear(); |
1482 | } |
1483 | |
1484 | TopoDS_Edge aNewEdge; |
1485 | QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVer, aPar, aNewEdge); |
1486 | aListSubst1.Append (aNewEdge); |
1487 | |
1488 | if(!myMapGener.IsBound(aE1)) { |
1489 | // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aE1, TopTools_ListOfShape()); |
1490 | TopTools_ListOfShape aListOfShape4; |
1491 | myMapGener.Bind(aE1, aListOfShape4); |
1492 | } |
1493 | myMapGener(aE1).Append(aVer); |
1494 | |
1495 | aExtrema.ParOnEdgeS2(i, aPar); |
1496 | if (!aMapSubst.IsBound(aE2)) { |
1497 | // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aE2, TopTools_ListOfShape()); |
1498 | TopTools_ListOfShape aListOfShape5; |
1499 | aMapSubst.Bind (aE2, aListOfShape5); |
1500 | } |
1501 | TopTools_ListOfShape& aListSubst2 = aMapSubst(aE2); |
1502 | if (aListSubst2.IsEmpty()) { |
1503 | aEdge = aE2; |
1504 | } |
1505 | else { |
1506 | aEdge = TopoDS::Edge(aListSubst2.First()); |
1507 | aListSubst2.Clear(); |
1508 | } |
1509 | |
1510 | QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVer, aPar, aNewEdge); |
1511 | aListSubst2.Append (aNewEdge); |
1512 | |
1513 | if(!myMapGener.IsBound(aE2)) { |
1514 | // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aE2, TopTools_ListOfShape()); |
1515 | TopTools_ListOfShape aListOfShape6; |
1516 | myMapGener.Bind(aE2, aListOfShape6); |
1517 | } |
1518 | myMapGener(aE2).Append(aVer); |
1519 | |
1520 | } |
1521 | |
1522 | aBld.MakeCompound (TopoDS::Compound(myShape)); |
1523 | aBld.Add(myShape, myS1); |
1524 | aBld.Add(myShape, myS2); |
1525 | |
1526 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aIterM(aMapSubst); |
1527 | for (; aIterM.More(); aIterM.Next()) { |
1528 | TopAbs_Orientation aOri = TopAbs_FORWARD; |
1529 | TopTools_ListIteratorOfListOfShape aIt (aIterM.Value()); |
1530 | for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri); |
1531 | if(aIterM.Key().ShapeType() == TopAbs_EDGE) { |
1532 | TopoDS_Edge aEdge = TopoDS::Edge(aIterM.Value().First()); |
1533 | TopTools_ListOfShape& aListSubst = aMapSubst(aIterM.Key()); |
1534 | aListSubst.Clear(); |
1535 | if(!TopOpeBRepTool_TOOL::SplitE(aEdge, aListSubst)) { |
1536 | aListSubst.Append(aEdge); |
1537 | } |
1538 | } |
1539 | mySubst.Substitute (aIterM.Key(), aIterM.Value()); |
1540 | // aOri = aIterM.Key().Orientation(); |
1541 | // aIt.Initialize (aIterM.Value()); |
1542 | // for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri); |
1543 | // myMapModif.Bind (aIterM.Key(), aIterM.Value()); |
1544 | } |
1545 | |
1546 | mySubst.Build(myShape); |
1547 | |
1548 | FillMapModif(mySubst, myS1, myMapModif); |
1549 | FillMapModif(mySubst, myS2, myMapModif); |
1550 | |
1551 | if (mySubst.IsCopied(myS1) || mySubst.IsCopied(myS2)) { |
1552 | TopoDS_Shape aNewS1; |
1553 | TopoDS_Shape aNewS2; |
1554 | |
1555 | if (mySubst.IsCopied(myS1)) |
1556 | aNewS1 = mySubst.Copy(myS1).First(); |
1557 | else |
1558 | aNewS1 = myS1; |
1559 | |
1560 | if(S1IsEdge) { |
1561 | TopoDS_Iterator aTDIt(aNewS1); |
1562 | TopoDS_Shape aE = aTDIt.Value(); |
1563 | aTDIt.Next(); |
1564 | if(!aTDIt.More()) aNewS1 = aE; |
1565 | } |
1566 | |
1567 | if (mySubst.IsCopied(myS2)) |
1568 | aNewS2 = mySubst.Copy(myS2).First(); |
1569 | else |
1570 | aNewS2 = myS2; |
1571 | |
1572 | if(S2IsEdge) { |
1573 | TopoDS_Iterator aTDIt(aNewS2); |
1574 | TopoDS_Shape aE = aTDIt.Value(); |
1575 | aTDIt.Next(); |
1576 | if(!aTDIt.More()) aNewS2 = aE; |
1577 | } |
1578 | |
1579 | myShape = RemoveOverlappedEdges(aNewS1, aNewS2, myMapModif); |
1580 | } |
1581 | |
1582 | Done(); |
1583 | } |