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 <Geom2d_Curve.hxx> |
23 | #include <Geom_Surface.hxx> |
24 | #include <GeomAPI_ProjectPointOnSurf.hxx> |
25 | #include <TopoDS.hxx> |
26 | #include <TopoDS_Iterator.hxx> |
27 | #include <BRep_Tool.hxx> |
28 | #include <BRepTools.hxx> |
29 | #include <BRepClass_FaceClassifier.hxx> |
30 | #include <BRepFeat_SplitShape.hxx> |
31 | #include <BRepLib.hxx> |
32 | #include <TopExp.hxx> |
33 | #include <TopExp_Explorer.hxx> |
34 | #include <TopTools_DataMapOfShapeInteger.hxx> |
35 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
36 | #include <TopTools_MapIteratorOfMapOfShape.hxx> |
37 | #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx> |
38 | #include <BRepAlgo_EdgeConnector.hxx> |
39 | #include <TopTools_MapOfShape.hxx> |
40 | #include <BRep_Builder.hxx> |
41 | #include <QANewModTopOpe_Tools.hxx> |
42 | #include <TopTools_IndexedMapOfShape.hxx> |
43 | |
44 | //======================================================================= |
45 | //function : SplitEdgeComplete |
46 | //purpose : static |
47 | //======================================================================= |
48 | |
49 | static void |
50 | SplitEdgeComplete (const TopoDS_Edge& theEdge, |
51 | TopTools_ListOfShape& theListSplits) |
52 | { |
53 | struct ParVer { |
54 | Standard_Real myParF, myParL; |
55 | TopoDS_Vertex myVerF, myVerL; |
56 | }; |
57 | ParVer *aParVer = new ParVer[theListSplits.Extent()+1]; |
58 | TopTools_DataMapOfShapeInteger aMapEdgeIPV; |
59 | TopTools_ListOfShape aListTodo; |
60 | aListTodo = theListSplits; |
61 | |
62 | // prepare structures aMapEdgeIPV and aParVer |
63 | |
64 | aListTodo.Prepend(theEdge); |
65 | TopTools_ListIteratorOfListOfShape aIter(aListTodo); |
66 | Standard_Integer iPV; |
67 | for (iPV=0; aIter.More(); aIter.Next(), iPV++) { |
68 | const TopoDS_Edge& aEdge = TopoDS::Edge(aIter.Value()); |
69 | TopoDS_Vertex aVer1, aVer2; |
70 | Standard_Real aPar1, aPar2; |
71 | |
72 | // compute parameters of first and last vertices of aEdge on theEdge |
73 | |
74 | TopExp::Vertices(aEdge, aVer1, aVer2); |
75 | |
76 | if(aVer1.IsNull() || aVer2.IsNull()) { |
77 | aListTodo.Remove(aIter); |
78 | TopTools_ListIteratorOfListOfShape aIter1(theListSplits); |
79 | for (; aIter1.More(); aIter1.Next()) { |
80 | if(aEdge.IsSame(aIter1.Value())) { |
81 | theListSplits.Remove(aIter1); |
82 | break; |
83 | } |
84 | } |
85 | if(aIter.More()) continue; |
86 | break; |
87 | } |
88 | |
89 | if (iPV == 0) { |
90 | // the vertices of theEdge |
91 | aPar1 = BRep_Tool::Parameter(aVer1, theEdge); |
92 | aPar2 = BRep_Tool::Parameter(aVer2, theEdge); |
93 | } |
94 | else { |
95 | Standard_Real aDist; |
96 | // the vertices of an edge from the source list |
97 | if (!QANewModTopOpe_Glue::ProjPointOnEdge (BRep_Tool::Pnt(aVer1), |
98 | theEdge, aPar1, aDist)) { |
99 | // the vertex is out of theEdge => take one from theEdge |
100 | Standard_Real aPar; |
101 | if (QANewModTopOpe_Glue::ProjPointOnEdge (BRep_Tool::Pnt(aParVer[0].myVerF), |
102 | aEdge, aPar, aDist)) { |
103 | aVer1 = aParVer[0].myVerF; |
104 | aPar1 = aParVer[0].myParF; |
105 | } |
106 | else { |
107 | aVer1 = aParVer[0].myVerL; |
108 | aPar1 = aParVer[0].myParL; |
109 | } |
110 | } |
111 | if (!QANewModTopOpe_Glue::ProjPointOnEdge (BRep_Tool::Pnt(aVer2), |
112 | theEdge, aPar2, aDist)) { |
113 | // the vertex is out of theEdge => take one from theEdge |
114 | Standard_Real aPar; |
115 | if (QANewModTopOpe_Glue::ProjPointOnEdge (BRep_Tool::Pnt(aParVer[0].myVerL), |
116 | aEdge, aPar, aDist)) { |
117 | aVer2 = aParVer[0].myVerL; |
118 | aPar2 = aParVer[0].myParL; |
119 | } |
120 | else { |
121 | aVer2 = aParVer[0].myVerF; |
122 | aPar2 = aParVer[0].myParF; |
123 | } |
124 | } |
125 | } |
126 | if (aPar1 < aPar2) { |
127 | aParVer[iPV].myParF = aPar1; aParVer[iPV].myVerF = aVer1; |
128 | aParVer[iPV].myParL = aPar2; aParVer[iPV].myVerL = aVer2; |
129 | } |
130 | else { |
131 | aParVer[iPV].myParF = aPar2; aParVer[iPV].myVerF = aVer2; |
132 | aParVer[iPV].myParL = aPar1; aParVer[iPV].myVerL = aVer1; |
133 | if(iPV != 0) { |
134 | TopTools_ListIteratorOfListOfShape aIterSplits(theListSplits); |
135 | for(; aIterSplits.More(); aIterSplits.Next()) { |
136 | if(aEdge.IsSame(aIterSplits.Value())) { |
137 | aIterSplits.Value().Reverse(); |
138 | } |
139 | } |
140 | } |
141 | } |
142 | aMapEdgeIPV.Bind(aEdge,iPV); |
143 | } |
144 | aListTodo.RemoveFirst(); |
145 | |
146 | // find holes and make new edges |
147 | |
148 | BRep_Builder aBld; |
149 | Standard_Integer iPVLast = 0; |
150 | iPV = -1; |
151 | while (iPV != 0) { |
152 | |
153 | // find the most left edge |
154 | iPV = 0; |
155 | TopTools_ListIteratorOfListOfShape aIterFound; |
156 | Standard_Real aParF = aParVer[0].myParL; |
157 | TopoDS_Vertex aVerF = aParVer[0].myVerL; |
158 | for (aIter.Initialize(aListTodo); aIter.More(); aIter.Next()) { |
159 | const TopoDS_Edge& aEdge = TopoDS::Edge(aIter.Value()); |
160 | Standard_Integer i = aMapEdgeIPV(aEdge); |
161 | if (aParVer[i].myParF < aParF) { |
162 | aParF = aParVer[i].myParF; |
163 | aVerF = aParVer[i].myVerF; |
164 | iPV = i; |
165 | aIterFound = aIter; |
166 | } |
167 | } |
168 | |
169 | // get previous last parameter |
170 | Standard_Real aParPrevL; |
171 | TopoDS_Vertex aVerPrevL; |
172 | if (iPVLast == 0) { |
173 | aParPrevL = aParVer[0].myParF; |
174 | aVerPrevL = aParVer[0].myVerF; |
175 | } |
176 | else { |
177 | aParPrevL = aParVer[iPVLast].myParL; |
178 | aVerPrevL = aParVer[iPVLast].myVerL; |
179 | } |
180 | |
181 | if (aParF > aParPrevL && !BRepTools::Compare(aVerF, aVerPrevL)) { |
182 | // make new edge to close the hole |
183 | TopoDS_Edge aNewEdge = theEdge; |
184 | aNewEdge.EmptyCopy(); |
185 | aNewEdge.Orientation(TopAbs_FORWARD); |
186 | TopoDS_Vertex aV1 = aVerPrevL; |
187 | TopoDS_Vertex aV2 = aVerF; |
188 | aV1.Orientation(TopAbs_FORWARD); |
189 | aV2.Orientation(TopAbs_REVERSED); |
190 | aBld.Add(aNewEdge, aV1); |
191 | aBld.Add(aNewEdge, aV2); |
192 | aBld.UpdateVertex(aV1, aParPrevL, aNewEdge, BRep_Tool::Tolerance(aV1)); |
193 | aBld.UpdateVertex(aV2, aParF, aNewEdge, BRep_Tool::Tolerance(aV2)); |
194 | theListSplits.Append(aNewEdge); |
195 | } |
196 | |
197 | iPVLast = iPV; |
198 | if (aIterFound.More()) aListTodo.Remove(aIterFound); |
199 | } |
200 | |
201 | delete [] aParVer; |
202 | } |
203 | |
204 | //======================================================================= |
205 | //function : SplitEdge |
206 | //purpose : static |
207 | //======================================================================= |
208 | |
209 | static void |
210 | SplitEdge (const TopoDS_Edge &theEdge, |
4e57c75e |
211 | const BOPAlgo_PPaveFiller &thePDSFiller, |
7fd59977 |
212 | const TopTools_MapOfShape &theEdgesValid, |
213 | const Standard_Boolean useMap, |
214 | TopTools_ListOfShape &theListSplits) |
215 | { |
216 | const TopAbs_State aStates[3] = {TopAbs_ON, TopAbs_IN, TopAbs_OUT}; |
217 | |
218 | for (Standard_Integer i=0; i < 3; i++) { // for each state {ON, IN, OUT} |
219 | if (QANewModTopOpe_Tools::IsSplit(thePDSFiller, theEdge, aStates[i])) { |
220 | // get splits according to this state |
221 | // and append them to the substitution list |
222 | TopTools_ListOfShape aListSplits; |
223 | |
224 | QANewModTopOpe_Tools::Splits(thePDSFiller, theEdge, aStates[i], aListSplits); |
225 | TopTools_ListIteratorOfListOfShape aIterSplits(aListSplits); |
226 | for(; aIterSplits.More(); aIterSplits.Next()) { |
227 | const TopoDS_Shape& aEdge = aIterSplits.Value(); |
228 | if (!useMap || theEdgesValid.Contains (aEdge)) |
229 | theListSplits.Append(aEdge.Oriented(TopAbs_FORWARD)); |
230 | } |
231 | } |
232 | } |
233 | |
234 | if (!theListSplits.IsEmpty()) { |
235 | SplitEdgeComplete (theEdge, theListSplits); |
236 | } |
237 | } |
238 | |
239 | //======================================================================= |
240 | //function : IsEdgeOut |
241 | //purpose : static |
242 | //remark : the edge is expected to have a pcurve on this face |
243 | //======================================================================= |
244 | |
245 | static Standard_Boolean |
246 | IsEdgeOut (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace) |
247 | { |
248 | Standard_Real aParF, aParL, aParM; |
249 | Handle(Geom2d_Curve) aCrv = BRep_Tool::CurveOnSurface(theEdge, theFace, aParF, aParL); |
250 | if (aCrv.IsNull()) return Standard_True; |
251 | |
252 | Standard_Real aPrec = Precision::PConfusion(); |
253 | BRepClass_FaceClassifier aClf; |
254 | gp_Pnt2d aPnt; |
255 | |
256 | if (!Precision::IsNegativeInfinite(aParF)) { |
257 | //check first point |
258 | aPnt = aCrv->Value(aParF); |
259 | aClf.Perform(theFace, aPnt, aPrec); |
260 | if(aClf.State() == TopAbs_OUT) return Standard_True; |
261 | } |
262 | |
263 | if (!Precision::IsPositiveInfinite(aParL)) { |
264 | //check last point |
265 | aPnt = aCrv->Value(aParL); |
266 | aClf.Perform(theFace, aPnt, aPrec); |
267 | if(aClf.State() == TopAbs_OUT) return Standard_True; |
268 | } |
269 | |
270 | //check middle point |
271 | if (!Precision::IsNegativeInfinite(aParF) && |
272 | !Precision::IsPositiveInfinite(aParL)) { |
273 | aParM = aParF + 0.618 * (aParL - aParF); |
274 | } |
275 | else { |
276 | if (Precision::IsNegativeInfinite(aParF) && |
277 | Precision::IsPositiveInfinite(aParL)) |
278 | aParM = 0.; |
279 | else if (Precision::IsNegativeInfinite(aParF)) |
280 | aParM = aParL - 1.; |
281 | else |
282 | aParM = aParF + 1.; |
283 | } |
284 | aPnt = aCrv->Value(aParM); |
285 | aClf.Perform(theFace, aPnt, aPrec); |
286 | if(aClf.State() == TopAbs_OUT) return Standard_True; |
287 | |
288 | return Standard_False; |
289 | } |
290 | |
291 | //======================================================================= |
292 | //function : CorrectAncestorsList |
293 | //purpose : static |
294 | //======================================================================= |
295 | |
296 | static void |
297 | CorrectAncestorsList (const TopoDS_Edge& theEdge, TopTools_ListOfShape& aListF) |
298 | { |
299 | // remove duplicates from list, |
300 | // remove faces for which theEdge has the state "OUT" |
301 | |
302 | // get a middle point on edge |
303 | TopTools_MapOfShape aMapF; |
304 | TopTools_ListIteratorOfListOfShape aIter(aListF); |
305 | while (aIter.More()) { |
306 | const TopoDS_Face& aFace = TopoDS::Face(aIter.Value()); |
307 | if (!aMapF.Add(aFace)) { |
308 | // duplicate -> remove |
309 | aListF.Remove(aIter); |
310 | continue; |
311 | } |
312 | if (IsEdgeOut(theEdge, aFace)) { |
313 | // this face is not an ancestor -> remove |
314 | aListF.Remove(aIter); |
315 | continue; |
316 | } |
317 | aIter.Next(); |
318 | } |
319 | } |
320 | |
321 | //======================================================================= |
322 | //function : PerformShell |
323 | //purpose : |
324 | //======================================================================= |
325 | |
326 | void |
327 | QANewModTopOpe_Glue::PerformShell() |
328 | { |
329 | // Standard_Boolean isSolidShell = (myS1.ShapeType() == TopAbs_SOLID); |
330 | Standard_Boolean isSolidShell = Standard_False; |
331 | Standard_Integer i; |
332 | |
333 | TopTools_MapOfShape anEdges, aCommonEdges, anOldVertices, aGenEdges; |
334 | TopExp_Explorer anExp; |
335 | |
336 | anExp.Init(myS1, TopAbs_EDGE); |
337 | for(; anExp.More(); anExp.Next()) anEdges.Add(anExp.Current()); |
338 | |
339 | anExp.Init(myS2, TopAbs_EDGE); |
340 | for(; anExp.More(); anExp.Next()) { |
341 | if(anEdges.Contains(anExp.Current())) aCommonEdges.Add(anExp.Current()); |
342 | } |
343 | |
344 | anExp.ReInit(); |
345 | for(; anExp.More(); anExp.Next()) anEdges.Add(anExp.Current()); |
346 | |
347 | anExp.Init(myS1, TopAbs_VERTEX); |
348 | for(; anExp.More(); anExp.Next()) anOldVertices.Add(anExp.Current()); |
349 | |
350 | anExp.Init(myS2, TopAbs_VERTEX); |
351 | for(; anExp.More(); anExp.Next()) anOldVertices.Add(anExp.Current()); |
352 | |
353 | |
354 | // initialization |
355 | TopoDS_Shape aS1, aS2; |
356 | Standard_Boolean aWire1 = Standard_False, aWire2 = Standard_False; |
357 | anExp.Init(myS1, TopAbs_WIRE, TopAbs_FACE); |
358 | if(anExp.More()) { |
359 | aS1 = myS1; |
360 | aWire1 = Standard_True; |
361 | } |
362 | else { |
363 | anExp.Init(myS1, TopAbs_EDGE, TopAbs_WIRE); |
364 | if(anExp.More()) { |
365 | aS1 = myS1; |
366 | aWire1 = Standard_True; |
367 | } |
368 | } |
369 | |
370 | anExp.Init(myS2, TopAbs_WIRE, TopAbs_FACE); |
371 | if(anExp.More()) { |
372 | aS2 = myS2; |
373 | aWire2 = Standard_True; |
374 | } |
375 | else { |
376 | anExp.Init(myS2, TopAbs_EDGE, TopAbs_WIRE); |
377 | if(anExp.More()) { |
378 | aS2 = myS2; |
379 | aWire2 = Standard_True; |
380 | } |
381 | } |
382 | |
383 | if(aWire1) { |
384 | BRep_Builder aBld; |
385 | myS1.Nullify(); |
386 | aBld.MakeCompound(TopoDS::Compound(myS1)); |
387 | anExp.Init(aS1, TopAbs_COMPSOLID); |
388 | for(; anExp.More(); anExp.Next()) { |
389 | aBld.Add(myS1, anExp.Current()); |
390 | } |
391 | |
392 | anExp.Init(aS1, TopAbs_SOLID, TopAbs_COMPSOLID); |
393 | for(; anExp.More(); anExp.Next()) { |
394 | aBld.Add(myS1, anExp.Current()); |
395 | } |
396 | |
397 | anExp.Init(aS1, TopAbs_SHELL, TopAbs_SOLID); |
398 | for(; anExp.More(); anExp.Next()) { |
399 | aBld.Add(myS1, anExp.Current()); |
400 | } |
401 | |
402 | anExp.Init(aS1, TopAbs_FACE, TopAbs_SHELL); |
403 | for(; anExp.More(); anExp.Next()) { |
404 | aBld.Add(myS1, anExp.Current()); |
405 | } |
406 | |
407 | } |
408 | |
409 | if(aWire2) { |
410 | BRep_Builder aBld; |
411 | myS2.Nullify(); |
412 | aBld.MakeCompound(TopoDS::Compound(myS2)); |
413 | anExp.Init(aS2, TopAbs_COMPSOLID); |
414 | for(; anExp.More(); anExp.Next()) { |
415 | aBld.Add(myS2, anExp.Current()); |
416 | } |
417 | |
418 | anExp.Init(aS2, TopAbs_SOLID, TopAbs_COMPSOLID); |
419 | for(; anExp.More(); anExp.Next()) { |
420 | aBld.Add(myS2, anExp.Current()); |
421 | } |
422 | |
423 | anExp.Init(aS2, TopAbs_SHELL, TopAbs_SOLID); |
424 | for(; anExp.More(); anExp.Next()) { |
425 | aBld.Add(myS2, anExp.Current()); |
426 | } |
427 | |
428 | anExp.Init(aS2, TopAbs_FACE, TopAbs_SHELL); |
429 | for(; anExp.More(); anExp.Next()) { |
430 | aBld.Add(myS2, anExp.Current()); |
431 | } |
432 | |
433 | } |
434 | |
435 | Standard_Boolean hasSolid1 = Standard_False; |
436 | Standard_Boolean hasSolid2 = Standard_False; |
437 | |
438 | anExp.Init(myS1, TopAbs_SOLID); |
439 | |
440 | if (anExp.More()) |
441 | hasSolid1 = Standard_True; |
442 | |
443 | anExp.Init(myS2, TopAbs_SOLID); |
444 | |
445 | if (anExp.More()) |
446 | hasSolid2 = Standard_True; |
447 | |
448 | if (hasSolid1 && hasSolid2) |
4e57c75e |
449 | myOperation = BOPAlgo_FUSE; |
7fd59977 |
450 | else if (hasSolid1) |
4e57c75e |
451 | myOperation = BOPAlgo_CUT21; |
7fd59977 |
452 | else if (hasSolid2) |
4e57c75e |
453 | myOperation = BOPAlgo_CUT; |
7fd59977 |
454 | else |
4e57c75e |
455 | myOperation = BOPAlgo_SECTION; |
7fd59977 |
456 | |
457 | BRepAlgoAPI_BooleanOperation::Build(); |
458 | if (!BuilderCanWork()) |
459 | return; |
460 | |
461 | if(aWire1) myS1 = aS1; |
462 | if(aWire2) myS2 = aS2; |
463 | |
464 | TopTools_DataMapOfShapeListOfShape* aMapSEdgeFaces[2] = |
465 | {&myMapSEdgeFaces1, &myMapSEdgeFaces2}; |
466 | TopTools_DataMapOfShapeShape* aMapSEdgeCrossFace[2] = |
467 | {&myMapSEdgeCrossFace1, &myMapSEdgeCrossFace2}; |
468 | TopTools_MapOfShape aSetFaces[2]; |
469 | TopTools_MapOfShape aSetEdges[2]; |
470 | |
471 | // fill myMapGener for new vertices |
472 | TopTools_MapIteratorOfMapOfShape aMapIter(anEdges); |
473 | const TopAbs_State aStates[3] = {TopAbs_ON, TopAbs_IN, TopAbs_OUT}; |
474 | for(; aMapIter.More(); aMapIter.Next()) { |
475 | const TopoDS_Shape& aEdge = aMapIter.Key(); |
476 | |
477 | if(aCommonEdges.Contains(aEdge)) continue; |
478 | |
479 | for (i=0; i < 3; i++) { // for each state {ON, IN, OUT} |
480 | if (QANewModTopOpe_Tools::IsSplit(myDSFiller, aEdge, aStates[i])) { |
481 | TopTools_ListOfShape aListSplits; |
482 | |
483 | QANewModTopOpe_Tools::Splits(myDSFiller, aEdge, aStates[i], aListSplits); |
484 | |
485 | TopTools_ListIteratorOfListOfShape aIterSplits(aListSplits); |
486 | for(; aIterSplits.More(); aIterSplits.Next()) { |
487 | const TopoDS_Shape& aE = aIterSplits.Value(); |
488 | TopoDS_Iterator aTDSIter(aE); |
489 | for(; aTDSIter.More(); aTDSIter.Next()) { |
490 | const TopoDS_Shape& aV = aTDSIter.Value(); |
491 | |
492 | if(!anOldVertices.Add(aV)) continue; |
493 | |
494 | if(!myMapGener.IsBound(aEdge)) { |
495 | // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aEdge, TopTools_ListOfShape()); |
496 | TopTools_ListOfShape aListOfShape1; |
497 | myMapGener.Bind(aEdge, aListOfShape1); |
498 | } |
499 | |
500 | myMapGener(aEdge).Append(aV); |
501 | } |
502 | } |
503 | } |
504 | } |
505 | } |
506 | |
507 | |
508 | // get list of section edges |
509 | const TopTools_ListOfShape& aListSE = SectionEdges(); |
510 | |
511 | // for each section edge remember the face crossed by the edge |
512 | // and the faces for which the edge coincides with a face's bound |
513 | TopTools_ListIteratorOfListOfShape aIterSE(aListSE); |
514 | Standard_Integer aNbUsedSecEdges = 0; |
515 | for(; aIterSE.More(); aIterSE.Next()) { |
516 | const TopoDS_Edge& aSecEdge = TopoDS::Edge(aIterSE.Value()); |
517 | |
518 | if(!aCommonEdges.Contains(aSecEdge)) { |
519 | |
520 | aNbUsedSecEdges++; |
521 | |
522 | TopoDS_Face aFaces[2]; |
523 | QANewModTopOpe_Tools::EdgeCurveAncestors(myDSFiller, aSecEdge, aFaces[0], |
524 | aFaces[1]); |
525 | |
526 | TopTools_ListOfShape aListF[2], aListE[2]; |
527 | QANewModTopOpe_Tools::EdgeSectionAncestors(myDSFiller, aSecEdge, aListF[0], |
528 | aListF[1], aListE[0], aListE[1]); |
529 | CorrectAncestorsList (aSecEdge, aListF[0]); |
530 | CorrectAncestorsList (aSecEdge, aListF[1]); |
531 | |
532 | Standard_Integer nbCurveAncestors = 0; |
533 | for (i = 0; i < 2; i++) { |
534 | if (!aListF[i].IsEmpty()) { |
535 | aMapSEdgeFaces[i]->Bind(aSecEdge, aListF[i]); |
536 | if (aListE[i].IsEmpty()) |
537 | aMapSEdgeCrossFace[i]->Bind(aSecEdge, aListF[i].First()); |
538 | TopTools_ListIteratorOfListOfShape aIter (aListF[i]); |
539 | for (; aIter.More(); aIter.Next()) |
540 | aSetFaces[i].Add(aIter.Value()); |
541 | } |
542 | else if (!aFaces[i].IsNull()) { |
543 | TopTools_ListOfShape aList; |
544 | aList.Append(aFaces[i]); |
545 | aMapSEdgeFaces[i]->Bind(aSecEdge, aList); |
546 | aMapSEdgeCrossFace[i]->Bind(aSecEdge, aFaces[i]); |
547 | aSetFaces[i].Add(aFaces[i]); |
548 | nbCurveAncestors++; |
549 | } |
550 | else if (!aListE[i].IsEmpty()) { |
551 | myEdgesToLeave.Add (aSecEdge); |
552 | TopTools_ListIteratorOfListOfShape aIter (aListE[i]); |
553 | for (; aIter.More(); aIter.Next()) |
554 | aSetEdges[i].Add(aIter.Value()); |
555 | } |
556 | } |
557 | if (nbCurveAncestors == 2) { |
558 | // the edge was computed by intersection of 2 surfaces |
559 | aGenEdges.Add(aSecEdge); |
560 | if (isSolidShell && !myAllowCutting) { |
561 | // Shell goes inside Solid while it is forbidden |
562 | return; |
563 | } |
564 | else { |
565 | // force same parameter |
566 | const Standard_Real aTol = 1.e-5; |
567 | BRep_Builder aBld; |
568 | aBld.SameRange (aSecEdge, Standard_False); |
569 | aBld.SameParameter (aSecEdge, Standard_False); |
570 | BRepLib::SameParameter (aSecEdge, aTol); |
571 | } |
572 | } |
573 | } |
574 | } |
575 | |
576 | //-------------------------------------------------- |
577 | if(aNbUsedSecEdges == 0 && aListSE.Extent() != 0) { |
578 | // all section edges are common edges - make compound |
579 | BRep_Builder aBld; |
580 | aBld.MakeCompound (TopoDS::Compound(myShape)); |
581 | aBld.Add(myShape, myS1); |
582 | aBld.Add(myShape, myS2); |
583 | Done(); |
584 | return; |
585 | } |
586 | //-------------------------------------------------- |
587 | |
588 | // cut faces of shell if another shape is solid |
589 | if (isSolidShell) { |
590 | // split edges of shape by section edges which are got |
591 | // due to coinciding of edges rather than intersecting of faces |
592 | TopTools_MapIteratorOfMapOfShape aIter(aSetEdges[1]); |
593 | for(; aIter.More(); aIter.Next()) { |
594 | const TopoDS_Edge aEdge = TopoDS::Edge (aIter.Key()); |
595 | TopTools_ListOfShape aListSplitE; |
596 | SplitEdge (aEdge, myDSFiller, myEdgesToLeave, Standard_False, aListSplitE); |
597 | if (!aListSplitE.IsEmpty()) { |
598 | mySubst.Substitute (aEdge, aListSplitE); |
599 | if (mySubst.IsCopied (aEdge)) { |
600 | // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind(aEdge, TopTools_ListOfShape()); |
601 | TopTools_ListOfShape aListOfShape2; |
602 | myMapModif.Bind(aEdge, aListOfShape2); |
603 | myMapModif(aEdge).Append (aListSplitE); |
604 | } |
605 | } |
606 | } |
607 | |
608 | for(aIter.Initialize (aSetFaces[1]); aIter.More(); aIter.Next()) { |
609 | const TopoDS_Face aFace = TopoDS::Face (aIter.Key()); |
610 | TopTools_ListOfShape aListSEOnFace; |
611 | |
612 | // select section edges on this face |
613 | for (aIterSE.Initialize(aListSE); aIterSE.More(); aIterSE.Next()) { |
614 | const TopoDS_Edge& aSecEdge = TopoDS::Edge(aIterSE.Value()); |
615 | // check if aFace is an ancestor of aSecEdge |
616 | if (aMapSEdgeFaces[1]->IsBound(aSecEdge)) { |
617 | TopTools_ListIteratorOfListOfShape |
618 | aIterF (aMapSEdgeFaces[1]->Find(aSecEdge)); |
619 | for (; aIterF.More(); aIterF.Next()) |
620 | if (aIterF.Value().IsSame(aFace)) { |
621 | aListSEOnFace.Append(aSecEdge); |
622 | break; |
623 | } |
624 | } |
625 | } |
626 | if (!aListSEOnFace.IsEmpty()) { |
627 | Standard_Boolean isCut = CutFace (aFace, aListSEOnFace); |
628 | if (isCut && !myAllowCutting) { |
629 | // Shell goes inside Solid while it is forbidden |
630 | return; |
631 | } |
632 | } |
633 | } |
634 | |
635 | // remove from maps all the section edges which are not marked to leave |
636 | for (aIterSE.Initialize (aListSE); aIterSE.More(); aIterSE.Next()) { |
637 | const TopoDS_Shape& aSecEdge = aIterSE.Value(); |
638 | if (!myEdgesToLeave.Contains (aSecEdge)) { |
639 | myMapSEdgeFaces1.UnBind (aSecEdge); |
640 | myMapSEdgeFaces2.UnBind (aSecEdge); |
641 | myMapSEdgeCrossFace1.UnBind (aSecEdge); |
642 | myMapSEdgeCrossFace2.UnBind (aSecEdge); |
643 | } |
644 | } |
645 | } |
646 | else { // not the case Solid-Shell |
647 | for (aIterSE.Initialize (aListSE); aIterSE.More(); aIterSE.Next()) |
648 | myEdgesToLeave.Add (aIterSE.Value()); |
649 | } |
650 | |
651 | // process intersected faces |
652 | for (i = 0; i < 2; i++) { |
653 | if (i == 1 && isSolidShell) continue; |
654 | |
655 | // split edges of shape by section edges which are got |
656 | // due to coinciding of edges rather than intersecting of faces |
657 | TopTools_MapIteratorOfMapOfShape aIter(aSetEdges[i]); |
658 | for(; aIter.More(); aIter.Next()) { |
659 | const TopoDS_Edge aEdge = TopoDS::Edge (aIter.Key()); |
660 | TopTools_ListOfShape aListSplitE; |
661 | SplitEdge (aEdge, myDSFiller, myEdgesToLeave, Standard_True, aListSplitE); |
662 | if (!aListSplitE.IsEmpty()) { |
663 | mySubst.Substitute (aEdge, aListSplitE); |
664 | //Substitution of vertices at the ends of aEdge. |
665 | TopoDS_Vertex aV1, aV2; |
666 | TopExp::Vertices(aEdge, aV1, aV2); |
667 | TopTools_ListIteratorOfListOfShape anIter(aListSplitE); |
668 | for(; anIter.More(); anIter.Next()) { |
669 | const TopoDS_Edge& aSpE = TopoDS::Edge(anIter.Value()); |
670 | TopoDS_Vertex aSpV1, aSpV2; |
671 | TopExp::Vertices(aSpE, aSpV1, aSpV2); |
672 | aSpV1.Orientation(TopAbs_FORWARD); |
673 | aSpV2.Orientation(TopAbs_FORWARD); |
674 | TopTools_ListOfShape aL; |
675 | if(BRepTools::Compare(aV1, aSpV1) && (!aV1.IsSame(aSpV1))) { |
676 | aL.Clear(); |
677 | aL.Append(aSpV1); |
678 | if(!mySubst.IsCopied (aV1)) { |
679 | mySubst.Substitute(aV1, aL); |
680 | // if (mySubst.IsCopied (aV1)) { |
681 | // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind(aV1, TopTools_ListOfShape()); |
682 | TopTools_ListOfShape aListOfShape3; |
683 | myMapModif.Bind(aV1, aListOfShape3); |
684 | myMapModif(aV1).Append (aL); |
685 | // } |
686 | } |
687 | } |
688 | if(BRepTools::Compare(aV1, aSpV2) && (!aV1.IsSame(aSpV2))) { |
689 | aL.Clear(); |
690 | aL.Append(aSpV2); |
691 | if(!mySubst.IsCopied (aV1)) { |
692 | mySubst.Substitute(aV1, aL); |
693 | // if (mySubst.IsCopied (aV1)) { |
694 | // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind(aV1, TopTools_ListOfShape()); |
695 | TopTools_ListOfShape aListOfShape4; |
696 | myMapModif.Bind(aV1, aListOfShape4); |
697 | myMapModif(aV1).Append (aL); |
698 | // } |
699 | } |
700 | } |
701 | if(BRepTools::Compare(aV2, aSpV1) && (!aV2.IsSame(aSpV1))) { |
702 | aL.Clear(); |
703 | aL.Append(aSpV1); |
704 | if (!mySubst.IsCopied (aV2)) { |
705 | mySubst.Substitute(aV2, aL); |
706 | // if (mySubst.IsCopied (aV2)) { |
707 | // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind(aV2, TopTools_ListOfShape()); |
708 | TopTools_ListOfShape aListOfShape5; |
709 | myMapModif.Bind(aV2, aListOfShape5); |
710 | myMapModif(aV2).Append (aL); |
711 | // } |
712 | } |
713 | } |
714 | if(BRepTools::Compare(aV2, aSpV2) && (!aV2.IsSame(aSpV2))) { |
715 | aL.Clear(); |
716 | aL.Append(aSpV2); |
717 | if (!mySubst.IsCopied (aV2)) { |
718 | mySubst.Substitute(aV2, aL); |
719 | // if (mySubst.IsCopied (aV2)) { |
720 | // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind(aV2, TopTools_ListOfShape()); |
721 | TopTools_ListOfShape aListOfShape6; |
722 | myMapModif.Bind(aV2, aListOfShape6); |
723 | myMapModif(aV2).Append (aL); |
724 | // } |
725 | } |
726 | } |
727 | } |
728 | |
729 | if (mySubst.IsCopied (aEdge)) { |
730 | // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind(aEdge, TopTools_ListOfShape()); |
731 | TopTools_ListOfShape aListOfShape7; |
732 | myMapModif.Bind(aEdge, aListOfShape7); |
733 | myMapModif(aEdge).Append (aListSplitE); |
734 | } |
735 | } |
736 | } |
737 | |
738 | for(aIter.Initialize (aSetFaces[i]); aIter.More(); aIter.Next()) { |
739 | const TopoDS_Face aFace = TopoDS::Face (aIter.Key()); |
740 | TopTools_ListOfShape aListSEOnFace; |
741 | |
742 | // select section edges on this face |
743 | for (aIterSE.Initialize(aListSE); aIterSE.More(); aIterSE.Next()) { |
744 | const TopoDS_Edge& aSecEdge = TopoDS::Edge(aIterSE.Value()); |
745 | // check if aFace is an ancestor of aSecEdge |
746 | if (aMapSEdgeFaces[i]->IsBound(aSecEdge)) { |
747 | TopTools_ListIteratorOfListOfShape |
748 | aIterF (aMapSEdgeFaces[i]->Find(aSecEdge)); |
749 | for (; aIterF.More(); aIterF.Next()) |
750 | if (aIterF.Value().IsSame(aFace)) { |
751 | aListSEOnFace.Append(aSecEdge); |
752 | break; |
753 | } |
754 | } |
755 | } |
756 | if (!aListSEOnFace.IsEmpty()) |
757 | SectionInsideFace (aFace, aListSEOnFace, i, aGenEdges); |
758 | } |
759 | } |
760 | |
761 | // construct new shapes from myS1 and myS2 |
762 | // and result compound |
763 | TopoDS_Shape aNewS[2]; |
764 | Standard_Integer nbModified = 0; |
765 | Standard_Integer nbDeleted = 0; |
766 | Standard_Integer iShape; |
767 | |
768 | for (i = 0; i < 2; i++) { |
769 | const TopoDS_Shape& aOldS = (i==0 ? myS1 : myS2); |
770 | mySubst.Build(aOldS); |
771 | if (mySubst.IsCopied(aOldS)) { |
772 | if (!mySubst.Copy(aOldS).IsEmpty()) { |
773 | aNewS[i] = mySubst.Copy(aOldS).First(); |
774 | aNewS[i].Orientation(aOldS.Orientation()); |
775 | nbModified++; |
776 | iShape = i; |
777 | } |
778 | else if (!myAllowCutting) { |
779 | // all Shell is inside Solid while it is forbidden |
780 | return; |
781 | } |
782 | else |
783 | nbDeleted++; |
784 | } |
785 | else { |
786 | aNewS[i] = aOldS; |
787 | iShape = i; |
788 | } |
789 | |
790 | TopExp_Explorer aExp (aOldS, TopAbs_FACE); |
791 | for (; aExp.More(); aExp.Next()) { |
792 | const TopoDS_Shape& aFace = aExp.Current(); |
793 | if(myMapModif.IsBound(aFace)) continue; |
794 | if (mySubst.IsCopied(aFace)) { |
795 | if (!mySubst.Copy(aFace).IsEmpty()) { |
796 | myMapModif.Bind(aFace,mySubst.Copy(aFace)); |
797 | } |
798 | } |
799 | } |
800 | |
801 | } |
802 | |
803 | if (nbModified > 0 && nbDeleted == 0) { |
804 | // the usual case |
805 | isSolidShell = Standard_True; |
806 | BRep_Builder aBld; |
807 | if(isSolidShell) { |
808 | aBld.MakeCompound (TopoDS::Compound(myShape)); |
809 | aBld.Add(myShape, aNewS[0]); |
810 | aBld.Add(myShape, aNewS[1]); |
811 | } |
812 | else { |
813 | aBld.MakeShell (TopoDS::Shell(myShape)); |
814 | for(anExp.Init(aNewS[0], TopAbs_FACE); anExp.More(); anExp.Next()) { |
815 | aBld.Add(myShape, anExp.Current()); |
816 | } |
817 | for(anExp.Init(aNewS[1], TopAbs_FACE); anExp.More(); anExp.Next()) { |
818 | aBld.Add(myShape, anExp.Current()); |
819 | } |
820 | } |
821 | Done(); |
822 | } |
823 | else if (nbDeleted == 1) { |
824 | // all Shell is inside Solid while it is permitted |
825 | myShape = aNewS[iShape]; |
826 | Done(); |
827 | } else if (nbModified == 0) { |
828 | // The case if nothing is changed. |
829 | BRep_Builder aBld; |
830 | |
831 | aBld.MakeCompound (TopoDS::Compound(myShape)); |
832 | aBld.Add(myShape, aNewS[0]); |
833 | aBld.Add(myShape, aNewS[1]); |
834 | Done(); |
835 | } |
836 | |
837 | mySubst.Clear(); |
838 | TopExp_Explorer aExp (myShape, TopAbs_EDGE); |
839 | Standard_Boolean IsSplit = Standard_False; |
840 | for (; aExp.More(); aExp.Next()) { |
841 | TopoDS_Edge aE = TopoDS::Edge(aExp.Current()); |
842 | if(mySubst.IsCopied(aE)) continue; |
843 | aE.Orientation(TopAbs_FORWARD); |
844 | TopTools_ListOfShape aListSplits; |
845 | if(QANewModTopOpe_Tools::SplitE(aE, aListSplits)) { |
846 | if(!IsSplit) IsSplit = Standard_True; |
847 | |
848 | BRep_Builder aBld; |
849 | Standard_Real aTol = Precision::Confusion(); |
850 | TopTools_ListIteratorOfListOfShape anISpl(aListSplits); |
851 | for(; anISpl.More(); anISpl.Next()) { |
852 | const TopoDS_Shape& aSpE = anISpl.Value(); |
853 | Standard_Real tol = BRep_Tool::Tolerance(TopoDS::Edge(aSpE)); |
854 | if(tol > aTol) { |
855 | aBld.UpdateEdge(TopoDS::Edge(aSpE), 1.05*tol); |
856 | } |
857 | } |
858 | |
859 | mySubst.Substitute(aE, aListSplits); |
860 | myMapModif.Bind(aE, aListSplits); |
861 | } |
862 | } |
863 | |
864 | if(IsSplit) { |
865 | mySubst.Build(myShape); |
866 | if(mySubst.IsCopied(myShape)) { |
867 | aExp.Init(myShape, TopAbs_FACE); |
868 | for(; aExp.More(); aExp.Next()) { |
869 | const TopoDS_Shape& aF = aExp.Current(); |
870 | if(mySubst.IsCopied(aF)) { |
871 | myMapModif.Bind(aF, mySubst.Copy(aF)); |
872 | } |
873 | } |
874 | myShape = mySubst.Copy(myShape).First(); |
875 | } |
876 | } |
877 | |
878 | } |
879 | |
880 | //======================================================================= |
881 | //function : SplitFaceBoundary |
882 | //purpose : static |
883 | //======================================================================= |
884 | |
885 | static TopoDS_Face |
886 | SplitFaceBoundary (const TopoDS_Face& theFace, |
887 | BRepTools_Substitution& theSubst, |
4e57c75e |
888 | const BOPAlgo_PPaveFiller &thePDSFiller, |
7fd59977 |
889 | const TopTools_MapOfShape& theEdgesValid, |
890 | const Standard_Boolean useMap, |
891 | TopTools_DataMapOfShapeListOfShape& theMapModif) |
892 | { |
893 | // split the face's edges by section edges lying on boundary |
894 | BRepTools_Substitution aLocalSubst; |
895 | TopExp_Explorer aExp (theFace, TopAbs_EDGE); |
896 | for (; aExp.More(); aExp.Next()) { |
897 | const TopoDS_Edge& aEdge = TopoDS::Edge (aExp.Current()); |
898 | if (theSubst.IsCopied (aEdge)) continue; |
899 | |
900 | TopTools_ListOfShape aListSplitE; |
901 | SplitEdge (aEdge, thePDSFiller, theEdgesValid, useMap, aListSplitE); |
902 | if (aListSplitE.IsEmpty()) continue; |
903 | |
904 | theSubst.Substitute (aEdge, aListSplitE); |
905 | aLocalSubst.Substitute (aEdge, aListSplitE); |
906 | //------------------------------------------------------------- |
907 | //Substitution of vertices at the ends of aEdge. |
908 | TopoDS_Vertex aV1, aV2; |
909 | TopExp::Vertices(aEdge, aV1, aV2); |
910 | TopTools_ListIteratorOfListOfShape anIter(aListSplitE); |
911 | for(; anIter.More(); anIter.Next()) { |
912 | const TopoDS_Edge& aSpE = TopoDS::Edge(anIter.Value()); |
913 | TopoDS_Vertex aSpV1, aSpV2; |
914 | TopExp::Vertices(aSpE, aSpV1, aSpV2); |
915 | aSpV1.Orientation(TopAbs_FORWARD); |
916 | aSpV2.Orientation(TopAbs_FORWARD); |
917 | TopTools_ListOfShape aL; |
918 | if(BRepTools::Compare(aV1, aSpV1) && (!aV1.IsSame(aSpV1))) { |
919 | aL.Clear(); |
920 | aL.Append(aSpV1); |
921 | aLocalSubst.Substitute(aV1, aL); |
922 | theSubst.Substitute(aV1, aL); |
923 | if (aLocalSubst.IsCopied (aV1)) { |
924 | // for Mandrake-10 - mkv,02.06.06 - theMapModif.Bind(aV1, TopTools_ListOfShape()); |
925 | TopTools_ListOfShape aListOfShape1; |
926 | theMapModif.Bind(aV1, aListOfShape1); |
927 | theMapModif(aV1).Append (aL); |
928 | } |
929 | } |
930 | if(BRepTools::Compare(aV1, aSpV2) && (!aV1.IsSame(aSpV2))) { |
931 | aL.Clear(); |
932 | aL.Append(aSpV2); |
933 | aLocalSubst.Substitute(aV1, aL); |
934 | theSubst.Substitute(aV1, aL); |
935 | if (aLocalSubst.IsCopied (aV1)) { |
936 | // for Mandrake-10 - mkv,02.06.06 - theMapModif.Bind(aV1, TopTools_ListOfShape()); |
937 | TopTools_ListOfShape aListOfShape2; |
938 | theMapModif.Bind(aV1, aListOfShape2); |
939 | theMapModif(aV1).Append (aL); |
940 | } |
941 | } |
942 | if(BRepTools::Compare(aV2, aSpV1) && (!aV2.IsSame(aSpV1))) { |
943 | aL.Clear(); |
944 | aL.Append(aSpV1); |
945 | aLocalSubst.Substitute(aV2, aL); |
946 | theSubst.Substitute(aV2, aL); |
947 | if (aLocalSubst.IsCopied (aV2)) { |
948 | // for Mandrake-10 - mkv,02.06.06 - theMapModif.Bind(aV2, TopTools_ListOfShape()); |
949 | TopTools_ListOfShape aListOfShape3; |
950 | theMapModif.Bind(aV2, aListOfShape3); |
951 | theMapModif(aV2).Append (aL); |
952 | } |
953 | } |
954 | if(BRepTools::Compare(aV2, aSpV2) && (!aV2.IsSame(aSpV2))) { |
955 | aL.Clear(); |
956 | aL.Append(aSpV2); |
957 | aLocalSubst.Substitute(aV2, aL); |
958 | theSubst.Substitute(aV2, aL); |
959 | if (aLocalSubst.IsCopied (aV2)) { |
960 | // for Mandrake-10 - mkv,02.06.06 - theMapModif.Bind(aV2, TopTools_ListOfShape()); |
961 | TopTools_ListOfShape aListOfShape4; |
962 | theMapModif.Bind(aV2, aListOfShape4); |
963 | theMapModif(aV2).Append (aL); |
964 | } |
965 | } |
966 | } |
967 | //------------------------------------------------------------- |
968 | if (aLocalSubst.IsCopied (aEdge)) { |
969 | // for Mandrake-10 - mkv,02.06.06 - theMapModif.Bind(aEdge, TopTools_ListOfShape()); |
970 | TopTools_ListOfShape aListOfShape5; |
971 | theMapModif.Bind(aEdge, aListOfShape5); |
972 | theMapModif(aEdge).Append (aListSplitE); |
973 | } |
974 | } |
975 | |
976 | aLocalSubst.Build (theFace); |
977 | if (aLocalSubst.IsCopied (theFace)) { |
978 | // TopoDS_Iterator aIterF (theFace); |
979 | // for (; aIterF.More(); aIterF.Next()) { |
980 | // const TopoDS_Shape& aWire = aIterF.Value(); |
981 | // if (aLocalSubst.IsCopied (aWire)) |
982 | // theSubst.Substitute (aWire, aLocalSubst.Copy(aWire)); |
983 | // } |
984 | aExp.Init(theFace, TopAbs_EDGE); |
985 | for(; aExp.More(); aExp.Next()) { |
986 | const TopoDS_Shape& anE = aExp.Current(); |
987 | |
988 | if (aLocalSubst.IsCopied (anE)) { |
989 | if(!theSubst.IsCopied (anE)) { |
990 | theSubst.Substitute (anE, aLocalSubst.Copy(anE)); |
991 | theMapModif.Bind(anE, aLocalSubst.Copy(anE)); |
992 | } |
993 | } |
994 | } |
995 | return TopoDS::Face (aLocalSubst.Copy(theFace).First()); |
996 | } |
997 | return theFace; |
998 | } |
999 | |
1000 | //======================================================================= |
1001 | //function : CutFace |
1002 | //purpose : |
1003 | //======================================================================= |
1004 | |
1005 | Standard_Boolean |
1006 | QANewModTopOpe_Glue::CutFace(const TopoDS_Face& theFace, |
1007 | const TopTools_ListOfShape& theListSE) |
1008 | { |
1009 | Standard_Boolean aRetValue = Standard_False; |
1010 | if (mySubst.IsCopied(theFace)) return aRetValue; |
1011 | |
1012 | // theFace may contain edges which need to be substituted |
1013 | mySubst.Build(theFace); |
1014 | TopoDS_Face aFace; |
1015 | if (mySubst.IsCopied(theFace)) { |
1016 | if (mySubst.Copy(theFace).IsEmpty()) return Standard_True; |
1017 | aFace = TopoDS::Face(mySubst.Copy(theFace).First()); |
1018 | } |
1019 | else |
1020 | aFace = theFace; |
1021 | |
1022 | // split the face's edges by section edges lying on boundary |
1023 | TopoDS_Face aFace1 = SplitFaceBoundary (aFace, mySubst, myDSFiller, |
1024 | myEdgesToLeave, Standard_False, myMapModif); |
1025 | |
1026 | // split face on subfaces by section edges lying inside the face |
1027 | BRepFeat_SplitShape aSpliter (aFace1); |
1028 | TopTools_ListIteratorOfListOfShape aIterSE (theListSE); |
1029 | for (; aIterSE.More(); aIterSE.Next()) { |
1030 | const TopoDS_Edge& aSEdge = TopoDS::Edge (aIterSE.Value()); |
1031 | if (myMapSEdgeCrossFace2.IsBound(aSEdge)) |
1032 | aSpliter.Add (aSEdge, aFace1); |
1033 | } |
1034 | aSpliter.Build(); |
1035 | const TopTools_ListOfShape& aListSplit = aSpliter.Modified(aFace1); |
1036 | |
1037 | // get OUT splits and append them to the substitution list |
1038 | TopTools_ListOfShape aListToSubst; |
1039 | TopTools_ListIteratorOfListOfShape aIter(aListSplit); |
1040 | for(; aIter.More(); aIter.Next()) { |
1041 | const TopoDS_Face& aFaceNew = TopoDS::Face (aIter.Value()); |
1042 | TopAbs_State aState = ClassifyFace (aFaceNew, theListSE); |
1043 | if (aState == TopAbs_OUT) { |
1044 | aListToSubst.Append(aFaceNew.Oriented(TopAbs_FORWARD)); |
1045 | // remember in the map the section edges to leave |
1046 | TopExp_Explorer aExp (aFaceNew, TopAbs_EDGE); |
1047 | for (; aExp.More(); aExp.Next()) { |
1048 | const TopoDS_Shape& aEdge = aExp.Current(); |
1049 | if (myMapSEdgeFaces2.IsBound (aEdge)) |
1050 | myEdgesToLeave.Add (aEdge); |
1051 | } |
1052 | } |
1053 | else { |
1054 | aRetValue = Standard_True; |
1055 | } |
1056 | } |
1057 | mySubst.Substitute(aFace, aListToSubst); |
1058 | |
1059 | // update history |
1060 | if (mySubst.IsCopied(aFace)) { |
1061 | // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind(theFace, TopTools_ListOfShape()); |
1062 | TopTools_ListOfShape aListOfShape; |
1063 | myMapModif.Bind(theFace, aListOfShape); |
1064 | myMapModif(theFace).Append (aListToSubst); |
1065 | } |
1066 | |
1067 | return aRetValue; |
1068 | } |
1069 | |
1070 | //======================================================================= |
1071 | //function : GetVecIntoFace |
1072 | //purpose : static |
1073 | //======================================================================= |
1074 | |
1075 | static Standard_Boolean |
1076 | GetVecIntoFace (const TopoDS_Face& theFace, |
1077 | const TopoDS_Edge& theEdge, |
1078 | gp_Pnt& thePntOnEdge, |
1079 | gp_Vec& theVecIntoFace) |
1080 | { |
1081 | TopoDS_Shape aDummy = theFace.Oriented(TopAbs_FORWARD); |
1082 | TopoDS_Face aFace = TopoDS::Face(aDummy); |
1083 | TopoDS_Edge aEdge; // theEdge extracted from theFace (with orientation) |
1084 | |
1085 | TopExp_Explorer aExp (aFace, TopAbs_EDGE); |
1086 | for (; aExp.More(); aExp.Next()) { |
1087 | aEdge = TopoDS::Edge (aExp.Current()); |
1088 | if (aEdge.IsSame(theEdge)) break; |
1089 | } |
1090 | if (!aExp.More()) return Standard_False; |
1091 | |
1092 | TopAbs_Orientation aOrient = aEdge.Orientation(); |
1093 | if (aOrient != TopAbs_FORWARD && aOrient != TopAbs_REVERSED) |
1094 | return Standard_False; |
1095 | |
1096 | Standard_Real aParF, aParL; |
1097 | Handle(Geom2d_Curve) aCrv = BRep_Tool::CurveOnSurface(aEdge, aFace, aParF, aParL); |
1098 | if (aCrv.IsNull()) return Standard_False; |
1099 | if (aCrv->Continuity() < GeomAbs_C1) return Standard_False; |
1100 | |
1101 | // get middle point on edge and normal |
1102 | Standard_Real aParM = aParF + (aParL - aParF) * 0.618; |
1103 | gp_Pnt2d aPntOnCrv; |
1104 | gp_Vec2d aDeriv; |
1105 | aCrv->D1(aParM, aPntOnCrv, aDeriv); |
1106 | gp_Vec2d aNormal(-aDeriv.Y(), aDeriv.X()); |
1107 | aNormal.Normalize(); |
1108 | if (aOrient == TopAbs_REVERSED) aNormal.Reverse(); |
1109 | |
1110 | // translate middle point along the normal |
1111 | Standard_Real uMin, uMax, vMin, vMax; |
1112 | BRepTools::UVBounds(aFace, uMin, uMax, vMin, vMax); |
1113 | Standard_Real duv = Min(uMax - uMin, vMax - vMin) * 0.1; |
1114 | Standard_Real dtol = BRep_Tool::Tolerance(aEdge) * 100.; |
1115 | Standard_Real d = Min(duv, dtol); |
1116 | gp_Pnt2d aPntOnSurf = aPntOnCrv.Translated(aNormal * d); |
1117 | |
1118 | // get 3d points |
1119 | Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); |
1120 | gp_Pnt aPntOnFace; |
1121 | aSurf->D0(aPntOnSurf.X(), aPntOnSurf.Y(), aPntOnFace); |
1122 | aSurf->D0(aPntOnCrv.X(), aPntOnCrv.Y(), thePntOnEdge); |
1123 | |
1124 | // compute theVecIntoFace |
1125 | theVecIntoFace = gp_Vec(thePntOnEdge, aPntOnFace); |
1126 | Standard_Real aNorm = theVecIntoFace.Magnitude(); |
1127 | if (aNorm < Precision::Confusion()) |
1128 | return Standard_False; |
1129 | theVecIntoFace.Divide(aNorm); |
1130 | |
1131 | return Standard_True; |
1132 | } |
1133 | |
1134 | //======================================================================= |
1135 | //function : ClassifyFace |
1136 | //purpose : |
1137 | //======================================================================= |
1138 | |
1139 | TopAbs_State |
1140 | QANewModTopOpe_Glue::ClassifyFace(const TopoDS_Face& theFace, |
1141 | const TopTools_ListOfShape& theListSE) const |
1142 | { |
1143 | TopAbs_State aState = TopAbs_UNKNOWN; |
1144 | |
1145 | TopTools_ListIteratorOfListOfShape aIterSE (theListSE); |
1146 | for (; aIterSE.More(); aIterSE.Next()) { |
1147 | const TopoDS_Edge& aEdge = TopoDS::Edge (aIterSE.Value()); |
1148 | |
1149 | // get a point on edge and a vector directed to inside face |
1150 | // relatively that point |
1151 | gp_Pnt aPntOnEdge; |
1152 | gp_Vec aVecIntoFace; |
1153 | if (BRep_Tool::Degenerated(aEdge) || |
1154 | !GetVecIntoFace (theFace, aEdge, aPntOnEdge, aVecIntoFace)) |
1155 | continue; |
1156 | |
1157 | // get faces from solid |
1158 | if (!myMapSEdgeFaces1.IsBound(aEdge)) continue; |
1159 | TopTools_ListIteratorOfListOfShape aIterF (myMapSEdgeFaces1(aEdge)); |
1160 | for (; aIterF.More(); aIterF.Next()) { |
1161 | const TopoDS_Face& aFaceSol = TopoDS::Face(aIterF.Value()); |
1162 | TopAbs_Orientation aOrient = aFaceSol.Orientation(); |
1163 | if (aOrient != TopAbs_FORWARD && aOrient != TopAbs_REVERSED) |
1164 | continue; |
1165 | |
1166 | // classify theFace relatively aFaceSol |
1167 | |
1168 | // get normal to the surface at the point aPntOnEdge |
1169 | Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFaceSol); |
1170 | GeomAPI_ProjectPointOnSurf aProjector(aPntOnEdge, aSurf); |
1171 | if (!aProjector.IsDone()) continue; |
1172 | Standard_Real u,v; |
1173 | aProjector.LowerDistanceParameters(u,v); |
1174 | gp_Vec d1u,d1v; |
1175 | gp_Pnt aPntProj; |
1176 | aSurf->D1(u, v, aPntProj, d1u, d1v); |
1177 | gp_Vec aNormal = d1u.Crossed(d1v); |
1178 | if (aOrient == TopAbs_REVERSED) aNormal.Reverse(); |
1179 | |
1180 | // compare normal and the vector "into face" |
1181 | Standard_Real aScalar = aVecIntoFace * aNormal; |
1182 | if (aScalar > Precision::Confusion()) { |
1183 | aState = TopAbs_OUT; |
1184 | break; |
1185 | } |
1186 | else if (aScalar < -Precision::Confusion()) |
1187 | aState = TopAbs_IN; |
1188 | else |
1189 | aState = TopAbs_ON; |
1190 | } |
1191 | if (aState == TopAbs_IN || aState == TopAbs_ON) |
1192 | break; |
1193 | } |
1194 | |
1195 | return aState; |
1196 | } |
1197 | |
1198 | //======================================================================= |
1199 | //function : IsVertexOnFaceBound |
1200 | //purpose : static |
1201 | //======================================================================= |
1202 | |
1203 | static Standard_Boolean |
1204 | IsVertexOnFaceBound (const TopoDS_Vertex& theVer, |
1205 | const TopoDS_Face& theFace, |
1206 | TopoDS_Edge& theEdgeContacted, |
1207 | TopoDS_Vertex& theVerContacted, |
1208 | Standard_Real& thePar, |
1209 | Standard_Real& theDist) |
1210 | { |
1211 | Standard_Real aDist, aPar, aTol2; |
1212 | theDist = RealLast(); |
1213 | gp_Pnt aPnt(BRep_Tool::Pnt(theVer)); |
1214 | Standard_Boolean isContactByVer = Standard_False; |
1215 | |
1216 | TopExp_Explorer aExp (theFace.Oriented(TopAbs_FORWARD), TopAbs_EDGE); |
1217 | for (; aExp.More() && theDist > Precision::Confusion(); aExp.Next()) { |
1218 | const TopoDS_Edge& aEdge = TopoDS::Edge (aExp.Current()); |
1219 | |
1220 | // first compare by vertices |
1221 | TopoDS_Iterator aIter (aEdge, Standard_False); |
1222 | for (; aIter.More(); aIter.Next()) { |
1223 | const TopoDS_Vertex& aVer = TopoDS::Vertex (aIter.Value()); |
1224 | if (aVer.IsSame(theVer)) { |
1225 | theEdgeContacted = aEdge; |
1226 | theVerContacted = aVer; |
1227 | return Standard_True; |
1228 | } |
1229 | if (QANewModTopOpe_Glue::CompareVertices (aVer, theVer, aDist)) { |
1230 | if (aDist < theDist) { |
1231 | theEdgeContacted = aEdge; |
1232 | theVerContacted = aVer; |
1233 | theDist = aDist; |
1234 | thePar = BRep_Tool::Parameter (aVer, aEdge); |
1235 | aTol2 = BRep_Tool::Tolerance (aVer); |
1236 | isContactByVer = Standard_True; |
1237 | } |
1238 | } |
1239 | } |
1240 | |
1241 | if (!isContactByVer) { |
1242 | // project on edge |
1243 | if (!BRep_Tool::Degenerated(aEdge)) { |
1244 | if (QANewModTopOpe_Glue::ProjPointOnEdge (aPnt, aEdge, aPar, aDist)) { |
1245 | if (aDist < theDist) { |
1246 | theEdgeContacted = aEdge; |
1247 | theVerContacted.Nullify(); |
1248 | theDist = aDist; |
1249 | thePar = aPar; |
1250 | aTol2 = BRep_Tool::Tolerance(aEdge); |
1251 | } |
1252 | } |
1253 | } |
1254 | } |
1255 | } |
1256 | |
1257 | if (theDist <= BRep_Tool::Tolerance(theVer) || theDist <= aTol2) |
1258 | return Standard_True; |
1259 | |
1260 | return Standard_False; |
1261 | } |
1262 | |
1263 | //======================================================================= |
1264 | //function : UpdateMapNewOld |
1265 | //purpose : static |
1266 | //======================================================================= |
1267 | |
1268 | static void |
1269 | UpdateMapNewOld (const TopoDS_Shape& theSh, const BRepTools_Substitution& theSubst, |
1270 | TopTools_DataMapOfShapeShape& theMapNewOld) |
1271 | { |
1272 | TopTools_IndexedMapOfShape aMapSh; |
1273 | TopExp::MapShapes (theSh, aMapSh); |
1274 | |
1275 | for (Standard_Integer i=1; i<=aMapSh.Extent(); i++) { |
1276 | const TopoDS_Shape& aSubSh = aMapSh(i); |
1277 | if (!aSubSh.IsSame(theSh) && theSubst.IsCopied (aSubSh)) { |
1278 | TopTools_ListIteratorOfListOfShape aIt (theSubst.Copy(aSubSh)); |
1279 | for (; aIt.More(); aIt.Next()) { |
1280 | const TopoDS_Shape& aNewSubSh = aIt.Value(); |
1281 | if (theMapNewOld.IsBound(aSubSh)) { |
1282 | TopoDS_Shape aOldSubSh = theMapNewOld(aSubSh); |
1283 | theMapNewOld.UnBind (aSubSh); |
1284 | theMapNewOld.Bind (aNewSubSh, aOldSubSh); |
1285 | } |
1286 | else { |
1287 | theMapNewOld.Bind (aNewSubSh, aSubSh); |
1288 | } |
1289 | } |
1290 | } |
1291 | } |
1292 | } |
1293 | |
1294 | //======================================================================= |
1295 | //function : DoLocalSubstitution |
1296 | //purpose : static |
1297 | //======================================================================= |
1298 | |
1299 | static void |
1300 | DoLocalSubstitution (TopoDS_Shape& theSh, const TopoDS_Shape& theSubSh, |
1301 | const TopoDS_Shape& theNewSubSh, |
1302 | TopTools_DataMapOfShapeShape& theMapNewOld) |
1303 | { |
1304 | BRepTools_Substitution aLocalSubst; |
1305 | TopTools_ListOfShape aList; |
1306 | aList.Append (theNewSubSh.Oriented(TopAbs_FORWARD)); |
1307 | aLocalSubst.Substitute (theSubSh, aList); |
1308 | aLocalSubst.Build(theSh); |
1309 | |
1310 | if (aLocalSubst.IsCopied(theSh)) { |
1311 | UpdateMapNewOld (theSh, aLocalSubst, theMapNewOld); |
1312 | theSh = aLocalSubst.Copy(theSh).First(); |
1313 | } |
1314 | } |
1315 | |
1316 | //======================================================================= |
1317 | //function : SectionInsideFace |
1318 | //purpose : |
1319 | //======================================================================= |
1320 | |
1321 | void |
1322 | QANewModTopOpe_Glue::SectionInsideFace(const TopoDS_Face& theFace, |
1323 | const TopTools_ListOfShape& theListSE, |
1324 | const Standard_Integer theShapeNum, |
1325 | const TopTools_MapOfShape& theGenEdges) |
1326 | { |
1327 | if (mySubst.IsCopied(theFace)) return; |
1328 | |
1329 | // theFace may contain edges which need to be substituted |
1330 | mySubst.Build(theFace); |
1331 | TopoDS_Face aFace; |
1332 | if (mySubst.IsCopied(theFace)) { |
1333 | if (mySubst.Copy(theFace).IsEmpty()) return; |
1334 | aFace = TopoDS::Face(mySubst.Copy(theFace).First()); |
1335 | } |
1336 | else |
1337 | aFace = theFace; |
1338 | |
1339 | // split the face's edges by section edges lying on boundary |
1340 | TopoDS_Face aFace1 = SplitFaceBoundary (aFace, mySubst, myDSFiller, |
1341 | myEdgesToLeave, Standard_True, myMapModif); |
1342 | TopTools_DataMapOfShapeShape aMapNewOrig; |
1343 | UpdateMapNewOld (theFace, mySubst, aMapNewOrig); |
1344 | |
1345 | // process section edges contacting the face boundary: |
1346 | // insert internal vertices in the boundary |
1347 | const TopTools_DataMapOfShapeShape& aMapEF = |
1348 | (theShapeNum==0 ? myMapSEdgeCrossFace1 : myMapSEdgeCrossFace2); |
1349 | BRep_Builder aBld; |
1350 | TopTools_DataMapOfShapeShape aMapNewOld; |
1351 | TopTools_ListIteratorOfListOfShape aIterSE (theListSE); |
1352 | |
1353 | TopTools_MapOfShape aVerGener; |
1354 | |
1355 | for (; aIterSE.More(); aIterSE.Next()) { |
1356 | const TopoDS_Edge& aSEdge = TopoDS::Edge (aIterSE.Value()); |
1357 | // skip edges lying on the boundary |
1358 | if (!aMapEF.IsBound (aSEdge)) continue; |
1359 | |
1360 | // check if vertices of aSEdge contacts edges of aFace |
1361 | TopoDS_Iterator aIter (aSEdge, Standard_False); |
1362 | for (; aIter.More(); aIter.Next()) { |
1363 | const TopoDS_Vertex& aSVer = TopoDS::Vertex (aIter.Value()); |
1364 | if (aSVer.Orientation() != TopAbs_FORWARD && |
1365 | aSVer.Orientation() != TopAbs_REVERSED) continue; |
1366 | |
1367 | TopoDS_Edge aEdge; |
1368 | TopoDS_Vertex aVer; |
1369 | Standard_Real aPar, aDist; |
1370 | if (IsVertexOnFaceBound (aSVer, aFace1, aEdge, aVer, aPar, aDist)) { |
1371 | // aSVer contacts aFace's boundary |
1372 | |
1373 | if (!aVer.IsNull()) { // vertex contacted |
1374 | if (!aVer.IsSame(aSVer)) { |
1375 | // the vertices are coincided but not the same |
1376 | // => substitute aVer with aSVer |
1377 | Standard_Real aTol = Max (BRep_Tool::Tolerance(aSVer), |
1378 | BRep_Tool::Tolerance(aVer) + aDist); |
1379 | TopAbs_Orientation aOri = aVer.Orientation(); |
1380 | if (aOri != TopAbs_FORWARD && aOri != TopAbs_REVERSED) { |
1381 | TopoDS_Shape aDummy = aSVer.Oriented(aOri); |
1382 | aBld.UpdateVertex (TopoDS::Vertex (aDummy), |
1383 | aPar, aEdge, aTol); |
1384 | } |
1385 | DoLocalSubstitution (aFace1, aVer, aSVer, aMapNewOld); |
1386 | // update history |
1387 | TopoDS_Shape aOrig = aMapNewOld(aSVer); |
1388 | if (aMapNewOrig.IsBound(aOrig)) aOrig = aMapNewOrig(aOrig); |
1389 | // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind(aOrig, TopTools_ListOfShape()); |
1390 | TopTools_ListOfShape aListOfShape1; |
1391 | myMapModif.Bind(aOrig, aListOfShape1); |
1392 | myMapModif(aOrig).Append (aSVer); |
1393 | aVerGener.Add(aSVer); |
1394 | continue; |
1395 | } |
1396 | } |
1397 | |
1398 | else { // contact inside edge |
1399 | // add the vertex as internal to the edge of the face |
1400 | TopoDS_Edge aNewEdge; |
1401 | InsertVertexInEdge (aEdge, aSVer, aPar, aNewEdge); |
1402 | // substitute edge |
1403 | DoLocalSubstitution (aFace1, aEdge, aNewEdge, aMapNewOld); |
1404 | // update history |
1405 | const TopoDS_Shape& aOld = aMapNewOld(aNewEdge); |
1406 | TopoDS_Shape aOrig; |
1407 | if (aMapNewOrig.IsBound(aOld)) { |
1408 | aOrig = aMapNewOrig(aOld); |
1409 | TopTools_ListOfShape& aListModif = myMapModif(aOrig); |
1410 | TopTools_ListIteratorOfListOfShape aIt (aListModif); |
1411 | for (; aIt.More(); aIt.Next()) |
1412 | if (aIt.Value().IsSame(aOld)) { |
1413 | aListModif.Remove (aIt); |
1414 | break; |
1415 | } |
1416 | aListModif.Append (aNewEdge); |
1417 | } |
1418 | else { |
1419 | aOrig = aOld; |
1420 | // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind(aOrig, TopTools_ListOfShape()); |
1421 | TopTools_ListOfShape aListOfShape2; |
1422 | myMapModif.Bind(aOrig, aListOfShape2); |
1423 | myMapModif(aOrig).Append (aNewEdge); |
1424 | } |
1425 | if (!myMapGener.IsBound (aOrig)) { |
1426 | // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aOrig, TopTools_ListOfShape()); |
1427 | TopTools_ListOfShape aListOfShape3; |
1428 | myMapGener.Bind(aOrig, aListOfShape3); |
1429 | } |
1430 | myMapGener(aOrig).Append (aSVer); |
1431 | aVerGener.Add(aSVer); |
1432 | } |
1433 | } |
1434 | } |
1435 | } |
1436 | |
1437 | // add the made replacements in the global substitution list |
1438 | TopTools_DataMapIteratorOfDataMapOfShapeShape aDIter (aMapNewOld); |
1439 | for (; aDIter.More(); aDIter.Next()) { |
1440 | TopTools_ListOfShape aList; |
1441 | const TopoDS_Shape& aOld = aDIter.Value(); |
1442 | const TopoDS_Shape& aNew = aDIter.Key(); |
1443 | aList.Append (aNew); |
1444 | mySubst.Substitute (aOld, aList); |
1445 | } |
1446 | |
1447 | // make wires from section edges |
1448 | Handle(BRepAlgo_EdgeConnector) aConnector = new BRepAlgo_EdgeConnector; |
1449 | TopTools_ListOfShape aListGener; |
1450 | TopoDS_Vertex aV1, aV2; |
1451 | for (aIterSE.Initialize (theListSE); aIterSE.More(); aIterSE.Next()) { |
1452 | const TopoDS_Edge& aSEdge = TopoDS::Edge (aIterSE.Value()); |
1453 | if (aMapEF.IsBound (aSEdge)) { |
1454 | aConnector->Add (aSEdge); |
1455 | aConnector->AddStart (aSEdge); |
1456 | if(theGenEdges.Contains(aSEdge)) { |
1457 | aListGener.Append (aSEdge); |
1458 | TopExp::Vertices(aSEdge, aV1, aV2); |
1459 | if(aVerGener.Add(aV1)) aListGener.Append (aV1); |
1460 | if(aVerGener.Add(aV2)) aListGener.Append (aV2); |
1461 | } |
1462 | } |
1463 | } |
1464 | const TopTools_ListOfShape& aListW = aConnector->MakeBlock(); |
1465 | if (aConnector->IsDone()) { |
1466 | // add new wires to face |
1467 | TopoDS_Face aNewFace = aFace1; |
1468 | aNewFace.EmptyCopy(); |
1469 | aNewFace.Orientation(TopAbs_FORWARD); |
1470 | aBld.NaturalRestriction (aNewFace, BRep_Tool::NaturalRestriction(aFace1)); |
1471 | // add old subshapes |
1472 | TopoDS_Iterator aIterF (aFace1, Standard_False); |
1473 | for (; aIterF.More(); aIterF.Next()) { |
1474 | aBld.Add (aNewFace, aIterF.Value()); |
1475 | } |
1476 | // add new wires as internal |
1477 | TopTools_ListIteratorOfListOfShape aIterL (aListW); |
1478 | for (; aIterL.More(); aIterL.Next()) { |
1479 | TopoDS_Shape aWire = aIterL.Value(); |
1480 | // check if there is a wire containing the same set of edges; |
1481 | // in this case use the old wire |
1482 | aWire = FindWireOrUpdateMap (aWire, myMapEdgeWires); |
1483 | aBld.Add (aNewFace, aWire.Oriented(TopAbs_INTERNAL)); |
1484 | } |
1485 | // substitute face |
1486 | TopTools_ListOfShape aList; |
1487 | aList.Append(aNewFace); |
1488 | mySubst.Substitute(aFace, aList); |
1489 | // update history |
1490 | // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind(theFace, TopTools_ListOfShape()); |
1491 | TopTools_ListOfShape aListOfShape4; |
1492 | myMapModif.Bind(theFace, aListOfShape4); |
1493 | myMapModif(theFace).Append (aList); |
1494 | if(!aListGener.IsEmpty()) { |
1495 | // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(theFace, TopTools_ListOfShape()); |
1496 | TopTools_ListOfShape aListOfShape5; |
1497 | myMapGener.Bind(theFace, aListOfShape5); |
1498 | myMapGener(theFace).Append (aListGener); |
1499 | } |
1500 | } |
1501 | #ifdef DEB |
1502 | else if (!aListW.IsEmpty()) { |
1503 | cout<<"QANewModTopOpe_Glue::SectionInsideFace : can't connect edges"<<endl; |
1504 | } |
1505 | #endif |
1506 | } |