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