973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
b311480e |
13 | |
7fd59977 |
14 | // abv 28.04.99 S4137: ading method Apply for work on all types of shapes |
15 | // sln 29.11.01 Bug24: correction iteration through map in method 'Status' |
16 | // sln 29.11.01 Bug22: correction of methods Replace and Value for case when mode myConsiderLocation is on |
17 | |
7fd59977 |
18 | #include <BRep_Builder.hxx> |
42cf5bc1 |
19 | #include <BRep_GCurve.hxx> |
7fd59977 |
20 | #include <BRep_TEdge.hxx> |
42cf5bc1 |
21 | #include <BRep_Tool.hxx> |
22 | #include <BRepTools_ReShape.hxx> |
7fd59977 |
23 | #include <Geom_Surface.hxx> |
98ffe9df |
24 | #include <NCollection_IndexedMap.hxx> |
42cf5bc1 |
25 | #include <Standard_Type.hxx> |
7fd59977 |
26 | #include <TopLoc_Location.hxx> |
42cf5bc1 |
27 | #include <TopoDS.hxx> |
42cf5bc1 |
28 | #include <TopoDS_Face.hxx> |
29 | #include <TopoDS_Iterator.hxx> |
30 | #include <TopoDS_Shape.hxx> |
7fd59977 |
31 | |
25e59720 |
32 | IMPLEMENT_STANDARD_RTTIEXT(BRepTools_ReShape,Standard_Transient) |
92efcf78 |
33 | |
98ffe9df |
34 | namespace |
35 | { |
36 | |
37 | //! Adds the shape to the map. |
38 | //! If the shape is a wire, shell or solid then |
39 | //! adds the sub-shapes of the shape instead. |
40 | //! Returns 'true' if the sub-shapes were added. |
41 | template<typename TMap> |
42 | void Add(TMap& theMap, const TopoDS_Shape& theShape) |
43 | { |
44 | const TopAbs_ShapeEnum aType = theShape.ShapeType(); |
45 | if (aType != TopAbs_WIRE && aType != TopAbs_SHELL && |
46 | aType != TopAbs_COMPSOLID) |
47 | { |
48 | theMap.Add(theShape); |
49 | return; |
50 | } |
51 | |
52 | for (TopoDS_Iterator aIt(theShape); aIt.More(); aIt.Next()) |
53 | { |
54 | theMap.Add(aIt.Value()); |
55 | } |
56 | } |
57 | |
58 | } |
59 | |
42cf5bc1 |
60 | //include <ShapeExtend.hxx> |
61 | //#include <BRepTools_Edge.hxx> |
b7c077b9 |
62 | static void CopyRanges (const TopoDS_Shape& toedge, const TopoDS_Shape& fromedge, |
63 | const Standard_Real alpha, const Standard_Real beta) |
7fd59977 |
64 | { |
b7c077b9 |
65 | Handle(BRep_TEdge) aTEdgeFrom = Handle(BRep_TEdge)::DownCast(fromedge.TShape()); |
66 | Handle(BRep_TEdge) aTEdgeTo = Handle(BRep_TEdge)::DownCast(toedge.TShape()); |
67 | BRep_ListOfCurveRepresentation& tolist = aTEdgeTo->ChangeCurves(); |
68 | BRep_ListIteratorOfListOfCurveRepresentation fromitcr (aTEdgeFrom->ChangeCurves()); |
69 | for (; fromitcr.More(); fromitcr.Next()) { |
7fd59977 |
70 | Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value()); |
71 | if ( fromGC.IsNull() ) continue; |
72 | Standard_Boolean isC3d = fromGC->IsCurve3D(); |
73 | if(isC3d) { |
74 | if(fromGC->Curve3D().IsNull()) continue; } |
75 | else { |
76 | if(fromGC->PCurve().IsNull()) continue; } |
77 | |
78 | if ( ! isC3d && ! fromGC->IsCurveOnSurface()) continue; // only 3d curves and pcurves are treated |
79 | |
80 | Handle(Geom_Surface) surface; |
81 | TopLoc_Location L; |
82 | if ( ! isC3d ) { |
83 | surface = fromGC->Surface(); |
84 | L = fromGC->Location(); |
85 | } |
86 | |
7fd59977 |
87 | Handle(BRep_GCurve) toGC; |
88 | for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More(); toitcr.Next()) { |
89 | toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value()); |
90 | if ( toGC.IsNull() ) continue; |
91 | if ( isC3d ) { |
92 | if ( ! toGC->IsCurve3D() ) continue; |
93 | } |
94 | else if ( ! toGC->IsCurveOnSurface() || |
95 | surface != toGC->Surface() || L != toGC->Location() ) continue; |
96 | Standard_Real first = fromGC->First(); |
97 | Standard_Real last = fromGC->Last(); |
98 | Standard_Real len = last - first; |
99 | toGC->SetRange ( first+alpha*len, first+beta*len ); |
100 | break; |
101 | } |
102 | } |
103 | } |
104 | |
105 | |
106 | //======================================================================= |
107 | //function : BRepTools_ReShape |
108 | //purpose : |
109 | //======================================================================= |
110 | |
111 | BRepTools_ReShape::BRepTools_ReShape() |
d533dafb |
112 | : myStatus(-1) |
7fd59977 |
113 | { |
114 | myConsiderLocation = Standard_False; |
7fd59977 |
115 | } |
116 | |
117 | |
118 | //======================================================================= |
119 | //function : Clear |
120 | //purpose : |
121 | //======================================================================= |
122 | |
123 | void BRepTools_ReShape::Clear() |
124 | { |
98ffe9df |
125 | myShapeToReplacement.Clear(); |
b60e8432 |
126 | myNewShapes.Clear(); |
7fd59977 |
127 | } |
128 | |
129 | |
130 | //======================================================================= |
131 | //function : Remove |
132 | //purpose : |
133 | //======================================================================= |
134 | |
669cd76e |
135 | void BRepTools_ReShape::Remove (const TopoDS_Shape& shape) |
7fd59977 |
136 | { |
137 | TopoDS_Shape nulshape; |
98ffe9df |
138 | replace(shape, nulshape, TReplacementKind_Remove); |
7fd59977 |
139 | } |
140 | |
141 | //======================================================================= |
669cd76e |
142 | //function : replace |
7fd59977 |
143 | //purpose : |
144 | //======================================================================= |
145 | |
669cd76e |
146 | void BRepTools_ReShape::replace (const TopoDS_Shape& ashape, |
98ffe9df |
147 | const TopoDS_Shape& anewshape, |
148 | const TReplacementKind theKind) |
7fd59977 |
149 | { |
150 | TopoDS_Shape shape = ashape; |
151 | TopoDS_Shape newshape = anewshape; |
152 | if ( shape.IsNull() || shape == newshape ) return; |
669cd76e |
153 | |
154 | if (shape.Orientation() == TopAbs_REVERSED) |
155 | { |
156 | shape.Reverse(); |
157 | newshape.Reverse(); |
158 | } |
159 | // protect against INTERNAL or EXTERNAL shape |
160 | else if (shape.Orientation() == TopAbs_INTERNAL |
161 | || shape.Orientation() == TopAbs_EXTERNAL) |
162 | { |
163 | newshape.Orientation((newshape.Orientation() == shape.Orientation()) ? |
164 | TopAbs_FORWARD : TopAbs_REVERSED); |
165 | shape.Orientation(TopAbs_FORWARD); |
166 | } |
167 | |
7fd59977 |
168 | if (myConsiderLocation) { |
169 | //sln 29.11.01 Bug22: Change location of 'newshape' in accordance with location of 'shape' |
9592ae24 |
170 | newshape.Location(newshape.Location().Multiplied(shape.Location().Inverted()), Standard_False); |
7fd59977 |
171 | TopLoc_Location nullLoc; |
172 | shape.Location ( nullLoc ); |
173 | } |
174 | |
0797d9d3 |
175 | #ifdef OCCT_DEBUG |
7fd59977 |
176 | if ( IsRecorded ( shape ) && ((myConsiderLocation && ! Value ( shape ).IsPartner ( newshape )) || |
177 | (!myConsiderLocation && ! Value ( shape ).IsSame ( newshape )))) |
04232180 |
178 | std::cout << "Warning: BRepTools_ReShape::Replace: shape already recorded" << std::endl; |
7fd59977 |
179 | #endif |
669cd76e |
180 | |
98ffe9df |
181 | myShapeToReplacement.Bind(shape, TReplacement(newshape, theKind)); |
669cd76e |
182 | myNewShapes.Add (newshape); |
7fd59977 |
183 | } |
184 | |
7fd59977 |
185 | //======================================================================= |
186 | //function : IsRecorded |
187 | //purpose : |
188 | //======================================================================= |
189 | |
190 | Standard_Boolean BRepTools_ReShape::IsRecorded (const TopoDS_Shape& ashape) const |
191 | { |
192 | TopoDS_Shape shape = ashape; |
193 | if (myConsiderLocation) { |
194 | TopLoc_Location nullLoc; |
195 | shape.Location ( nullLoc ); |
196 | } |
197 | if (shape.IsNull()) return Standard_False; |
98ffe9df |
198 | return myShapeToReplacement.IsBound (shape); |
7fd59977 |
199 | } |
200 | |
201 | |
202 | //======================================================================= |
203 | //function : Value |
204 | //purpose : |
205 | //======================================================================= |
206 | |
207 | TopoDS_Shape BRepTools_ReShape::Value (const TopoDS_Shape& ashape) const |
208 | { |
209 | TopoDS_Shape res; |
210 | if (ashape.IsNull()) return res; |
211 | TopoDS_Shape shape = ashape; |
212 | if (myConsiderLocation) { |
213 | TopLoc_Location nullLoc; |
214 | shape.Location ( nullLoc ); |
215 | } |
216 | |
217 | Standard_Boolean fromMap = Standard_False; |
98ffe9df |
218 | if (!myShapeToReplacement.IsBound(shape)) |
219 | { |
220 | res = shape; |
7fd59977 |
221 | } |
98ffe9df |
222 | else |
223 | { |
224 | res = myShapeToReplacement(shape).Result(); |
225 | if (shape.Orientation() == TopAbs_REVERSED) |
226 | { |
227 | res.Reverse(); |
7fd59977 |
228 | } |
98ffe9df |
229 | fromMap = Standard_True; |
7fd59977 |
230 | } |
231 | // for INTERNAL/EXTERNAL, since they are not fully supported, keep orientation |
232 | if ( shape.Orientation() == TopAbs_INTERNAL || |
233 | shape.Orientation() == TopAbs_EXTERNAL ) |
234 | res.Orientation ( shape.Orientation() ); |
235 | |
236 | if (myConsiderLocation) { |
237 | //sln 29.11.01 Bug22: Recalculate location of resulting shape in accordance with |
238 | //whether result is from map or not |
9592ae24 |
239 | if(fromMap) res.Location(ashape.Location()*res.Location(), Standard_False); |
240 | else res.Location(ashape.Location(), Standard_False); |
7fd59977 |
241 | } |
242 | |
243 | return res; |
244 | } |
245 | |
246 | |
247 | //======================================================================= |
248 | //function : Status |
249 | //purpose : |
250 | //======================================================================= |
251 | |
252 | Standard_Integer BRepTools_ReShape::Status(const TopoDS_Shape& ashape, |
253 | TopoDS_Shape& newsh, |
254 | const Standard_Boolean last) |
255 | { |
256 | Standard_Integer res = 0; |
257 | if (ashape.IsNull()) { newsh.Nullify(); return res; } |
258 | |
259 | TopoDS_Shape shape = ashape; |
260 | TopLoc_Location aLocSh = shape.Location(); |
261 | if (myConsiderLocation) { |
262 | TopLoc_Location nullLoc; |
263 | shape.Location ( nullLoc ); |
264 | } |
265 | |
98ffe9df |
266 | if (!myShapeToReplacement.IsBound(shape)) |
267 | { |
268 | newsh = shape; |
269 | res = 0; |
270 | } |
271 | else |
272 | { |
273 | newsh = myShapeToReplacement(shape).Result(); |
274 | res = 1; |
275 | } |
7fd59977 |
276 | if (res > 0) { |
277 | if (newsh.IsNull()) res = -1; |
278 | else if (newsh.IsEqual (shape)) res = 0; |
279 | else if ( last && ((myConsiderLocation && ! newsh.IsPartner (shape)) || |
280 | (!myConsiderLocation && ! newsh.IsSame (shape)))) { |
281 | //TopoDS_Shape newnewsh; |
282 | //Standard_Integer newres = Status (newsh, newnewsh, last); |
283 | //newsh = newnewsh; |
284 | //if (newres) res = newres; |
285 | // sln 29.11.01 Bug24: Correction iteration through maps. Way of iteration used early does not |
286 | // correspond to way of storing information in the maps. |
287 | newsh = Apply(shape, TopAbs_SHAPE); |
288 | if (newsh.IsNull()) res = -1; |
289 | if (newsh.IsEqual (shape)) res = 0; |
290 | } |
291 | } |
292 | if(myConsiderLocation && !newsh.IsNull()) |
293 | { |
294 | TopLoc_Location aResLoc = (res >0 && !newsh.Location().IsIdentity() ? |
295 | aLocSh * newsh.Location() : aLocSh); |
9592ae24 |
296 | newsh.Location(aResLoc, Standard_False); |
7fd59977 |
297 | } |
298 | return res; |
299 | } |
300 | |
7fd59977 |
301 | //======================================================================= |
302 | //function : EncodeStatus |
303 | //purpose : static |
304 | //======================================================================= |
305 | static Standard_Integer EncodeStatus (const Standard_Integer status) |
306 | { |
307 | switch ( status ) { |
308 | case 0 : return 0x0000; //ShapeExtend_OK |
309 | case 1: return 0x0001; //ShapeExtend_DONE1 |
310 | case 2: return 0x0002; //.... |
311 | case 3: return 0x0004; |
312 | case 4: return 0x0008; |
313 | case 5: return 0x0010; |
314 | case 6: return 0x0020; |
315 | case 7: return 0x0040; |
316 | case 8: return 0x0080; //.... |
317 | case 9 : return 0x00ff; //ShapeExtend_DONE |
318 | case 10: return 0x0100; //ShapeExtend_FAIL1 |
319 | case 11: return 0x0200; //... |
320 | case 12: return 0x0400; |
321 | case 13: return 0x0800; |
322 | case 14: return 0x1000; |
323 | case 15: return 0x2000; |
324 | case 16: return 0x4000; |
325 | case 17: return 0x8000; //.... |
326 | case 18 : return 0xff00; //ShapeExtend_FAIL |
327 | } |
328 | return 0; |
329 | } |
330 | |
331 | |
332 | //======================================================================= |
333 | //function : Apply |
334 | //purpose : |
335 | //======================================================================= |
336 | |
337 | TopoDS_Shape BRepTools_ReShape::Apply (const TopoDS_Shape& shape, |
338 | const TopAbs_ShapeEnum until) |
339 | { |
340 | myStatus = EncodeStatus(0); //ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
341 | if ( shape.IsNull() ) return shape; |
342 | |
343 | // apply direct replacement |
344 | TopoDS_Shape newsh = Value ( shape ); |
345 | |
346 | // if shape removed, return NULL |
347 | if ( newsh.IsNull() ) { |
348 | myStatus = EncodeStatus (2); //ShapeExtend_DONE2 |
349 | return newsh; |
350 | } |
351 | |
352 | // if shape replaced, apply modifications to the result recursively |
353 | if ( (myConsiderLocation && ! newsh.IsPartner (shape)) || |
354 | (!myConsiderLocation &&! newsh.IsSame ( shape )) ) { |
355 | TopoDS_Shape res = Apply ( newsh, until ); |
356 | myStatus |= EncodeStatus(1); //ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); |
357 | return res; |
358 | } |
359 | |
e837b3a2 |
360 | TopAbs_ShapeEnum st = shape.ShapeType(); |
361 | if (st > until || (st == until && until > TopAbs_COMPOUND)) return newsh; // stopping criteria |
7fd59977 |
362 | if(st == TopAbs_VERTEX || st == TopAbs_SHAPE) |
363 | return shape; |
364 | // define allowed types of components |
365 | //fix for SAMTECH bug OCC322 about abcense internal vertices after sewing. |
366 | /* |
367 | switch ( st ) { |
368 | case TopAbs_COMPOUND: subt = TopAbs_SHAPE; break; |
369 | case TopAbs_COMPSOLID: subt = TopAbs_SOLID; break; |
370 | case TopAbs_SOLID: subt = TopAbs_SHELL; break; |
371 | case TopAbs_SHELL: subt = TopAbs_FACE; break; |
372 | case TopAbs_FACE: subt = TopAbs_WIRE; break; |
373 | case TopAbs_WIRE: subt = TopAbs_EDGE; break; |
374 | case TopAbs_EDGE: subt = TopAbs_VERTEX; break; |
375 | case TopAbs_VERTEX: |
376 | case TopAbs_SHAPE: |
377 | default: return shape; |
378 | } |
379 | */ |
380 | BRep_Builder B; |
381 | |
382 | TopoDS_Shape result = shape.EmptyCopied(); |
383 | TopAbs_Orientation orien = shape.Orientation(); |
384 | result.Orientation(TopAbs_FORWARD); // protect against INTERNAL or EXTERNAL shapes |
385 | Standard_Boolean modif = Standard_False; |
386 | Standard_Integer locStatus = myStatus; |
387 | |
388 | // apply recorded modifications to subshapes |
3e6a4cd0 |
389 | Standard_Boolean isEmpty = Standard_True; |
7fd59977 |
390 | for ( TopoDS_Iterator it(shape,Standard_False); it.More(); it.Next() ) { |
b2fedee6 |
391 | const TopoDS_Shape& sh = it.Value(); |
7fd59977 |
392 | newsh = Apply ( sh, until ); |
393 | if ( newsh != sh ) { |
394 | if ( myStatus & EncodeStatus(4)) //ShapeExtend::DecodeStatus ( myStatus, ShapeExtend_DONE4 ) ) |
3e6a4cd0 |
395 | locStatus |= EncodeStatus(4); //|= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 ); |
7fd59977 |
396 | modif = 1; |
397 | } |
398 | if ( newsh.IsNull() ) { |
399 | locStatus |= EncodeStatus(4); //ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 ); |
400 | continue; |
401 | } |
3e6a4cd0 |
402 | if ( isEmpty ) |
403 | isEmpty = Standard_False; |
7fd59977 |
404 | locStatus |= EncodeStatus(3);//ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 ); |
405 | if ( st == TopAbs_COMPOUND || newsh.ShapeType() == sh.ShapeType()) { //fix for SAMTECH bug OCC322 about abcense internal vertices after sewing. |
406 | B.Add ( result, newsh ); |
407 | continue; |
408 | } |
409 | Standard_Integer nitems = 0; |
410 | for ( TopoDS_Iterator subit(newsh); subit.More(); subit.Next(), nitems++ ) { |
b2fedee6 |
411 | const TopoDS_Shape& subsh = subit.Value(); |
7fd59977 |
412 | if ( subsh.ShapeType() == sh.ShapeType() ) B.Add ( result, subsh );//fix for SAMTECH bug OCC322 about abcense internal vertices after sewing. |
413 | else locStatus |= EncodeStatus(10);//ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 ); |
414 | } |
415 | if ( ! nitems ) locStatus |= EncodeStatus(10);//ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 ); |
416 | } |
417 | if ( ! modif ) return shape; |
418 | |
3e6a4cd0 |
419 | // For empty topological containers (any kind of shape except vertex, edge |
420 | // and face) we have to produce an empty result |
421 | if ( isEmpty && st != TopAbs_VERTEX && st != TopAbs_EDGE && st != TopAbs_FACE ) |
422 | { |
423 | result = TopoDS_Shape(); |
7fd59977 |
424 | } |
3e6a4cd0 |
425 | else |
426 | { |
427 | // restore Range on edge broken by EmptyCopied() |
428 | if ( st == TopAbs_EDGE ) { |
429 | CopyRanges (result, shape, 0, 1); |
430 | } |
431 | else if (st == TopAbs_FACE) { |
432 | TopoDS_Face face = TopoDS::Face ( shape ); |
433 | if( BRep_Tool::NaturalRestriction( face ) ) { |
434 | BRep_Builder aB; |
435 | aB.NaturalRestriction( TopoDS::Face ( result ), Standard_True ); |
436 | } |
7fd59977 |
437 | } |
3e6a4cd0 |
438 | else if (st == TopAbs_WIRE || st == TopAbs_SHELL) |
439 | result.Closed (BRep_Tool::IsClosed (result)); |
440 | |
441 | result.Orientation(orien); |
7fd59977 |
442 | } |
443 | |
98ffe9df |
444 | replace(shape, result, |
445 | result.IsNull() ? TReplacementKind_Remove : TReplacementKind_Modify); |
3e6a4cd0 |
446 | myStatus = locStatus; |
ab860031 |
447 | |
7fd59977 |
448 | return result; |
449 | } |
450 | |
451 | |
452 | //======================================================================= |
453 | //function : Status |
454 | //purpose : |
455 | //======================================================================= |
456 | |
457 | /*Standard_Boolean BRepTools_ReShape::Status (const ShapeExtend_Status status) const |
458 | { |
459 | return ShapeExtend::DecodeStatus ( myStatus, status ); |
460 | }*/ |
461 | |
ed5ca017 |
462 | //======================================================================= |
463 | //function : CopyVertex |
464 | //purpose : |
465 | //======================================================================= |
466 | |
467 | TopoDS_Vertex BRepTools_ReShape::CopyVertex(const TopoDS_Vertex& theV, |
468 | const Standard_Real theTol) |
469 | { |
470 | return CopyVertex(theV, BRep_Tool::Pnt(theV), theTol); |
471 | } |
472 | |
473 | //======================================================================= |
474 | //function : CopyVertex |
475 | //purpose : |
476 | //======================================================================= |
477 | |
478 | TopoDS_Vertex BRepTools_ReShape::CopyVertex(const TopoDS_Vertex& theV, |
479 | const gp_Pnt& theNewPos, |
480 | const Standard_Real theTol) |
481 | { |
482 | TopoDS_Vertex aVertexCopy; |
483 | Standard_Boolean isRecorded = IsRecorded(theV); |
484 | aVertexCopy = isRecorded ? TopoDS::Vertex(Apply(theV)) : TopoDS::Vertex(theV.EmptyCopied()); |
485 | |
486 | BRep_Builder B; |
487 | Standard_Real aNewTol = theTol > 0.0 ? theTol : BRep_Tool::Tolerance(theV); |
488 | B.UpdateVertex(aVertexCopy, theNewPos, aNewTol); |
489 | |
490 | if (!isRecorded) |
491 | Replace(theV, aVertexCopy); |
492 | |
493 | return aVertexCopy; |
494 | } |
b60e8432 |
495 | |
496 | Standard_Boolean BRepTools_ReShape::IsNewShape(const TopoDS_Shape& theShape) const |
497 | { |
498 | return myNewShapes.Contains(theShape); |
499 | } |
98ffe9df |
500 | |
501 | //======================================================================= |
502 | //function : History |
503 | //purpose : |
504 | //======================================================================= |
505 | |
506 | Handle(BRepTools_History) BRepTools_ReShape::History() const |
507 | { |
508 | Handle(BRepTools_History) aHistory = new BRepTools_History; |
509 | |
510 | // Fill the history. |
511 | for (TShapeToReplacement::Iterator aRIt(myShapeToReplacement); |
512 | aRIt.More(); aRIt.Next()) |
513 | { |
514 | const TopoDS_Shape& aShape = aRIt.Key(); |
515 | if (!BRepTools_History::IsSupportedType(aShape) || |
516 | myNewShapes.Contains(aShape)) |
517 | { |
518 | continue; |
519 | } |
520 | |
521 | NCollection_IndexedMap<TopoDS_Shape> aIntermediates; |
522 | NCollection_Map<TopoDS_Shape> aModified; |
523 | aIntermediates.Add(aShape); |
524 | for (Standard_Integer aI = 1; aI <= aIntermediates.Size(); ++aI) |
525 | { |
526 | const TopoDS_Shape& aIntermediate = aIntermediates(aI); |
527 | const TReplacement* aReplacement = |
528 | myShapeToReplacement.Seek(aIntermediate); |
529 | if (aReplacement == NULL) |
530 | { |
531 | Add(aModified, aIntermediate); |
532 | } |
533 | else if (aReplacement->RelationKind() != |
534 | BRepTools_History::TRelationType_Removed) |
535 | { |
536 | const TopoDS_Shape aResult = aReplacement->RelationResult(); |
537 | if (!aResult.IsNull()) |
538 | { |
539 | Add(aIntermediates, aResult); |
540 | } |
541 | } |
542 | } |
543 | |
544 | if (aModified.IsEmpty()) |
545 | { |
546 | aHistory->Remove(aShape); |
547 | } |
548 | else |
549 | { |
550 | for (NCollection_Map<TopoDS_Shape>::Iterator aIt(aModified); |
551 | aIt.More(); aIt.Next()) |
552 | { |
553 | aHistory->AddModified(aShape, aIt.Value()); |
554 | } |
555 | } |
556 | } |
557 | |
558 | return aHistory; |
559 | } |