0025748: Parallel version of progress indicator
[occt.git] / src / BRepTools / BRepTools_Modifier.cxx
1 // Created on: 1994-08-25
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 // IFV 04.06.99 - PRO18974 - processing of INTERNAL shapes.
18
19 #include <BRepTools_Modification.hxx>
20 #include <BRepTools_Modifier.hxx>
21 #include <Standard_NoSuchObject.hxx>
22 #include <Standard_NullObject.hxx>
23 #include <TColStd_ListIteratorOfListOfTransient.hxx>
24 #include <TColStd_ListOfTransient.hxx>
25 #include <TopExp_Explorer.hxx>
26 #include <TopoDS_Edge.hxx>
27 #include <TopoDS_Face.hxx>
28 #include <TopoDS_Iterator.hxx>
29 #include <TopoDS_Shape.hxx>
30 #include <TopoDS_Vertex.hxx>
31 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
32 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
33 #include <TopTools_ListIteratorOfListOfShape.hxx>
34 #include <TopTools_ListOfShape.hxx>
35
36 #if 0
37 #include <Poly_Triangulation.hxx>
38 #include <Poly_Polygon3D.hxx>
39 #include <BRepMesh_IncrementalMesh.hxx>
40 #endif
41
42 #include <Geom2d_Line.hxx>
43 #include <BRep_Builder.hxx>
44 #include <BRep_Tool.hxx>
45 #include <TopoDS.hxx>
46 #include <BRepTools.hxx>
47 #include <TopAbs.hxx>
48 #include <TopExp.hxx>
49 #include <gp_Pnt.hxx>
50
51 #include <gp.hxx>
52
53 #include <Standard_NullObject.hxx>
54 #include <gp_Trsf.hxx>
55 #include <BRepTools_TrsfModification.hxx>
56 #include <Message_ProgressScope.hxx>
57 #include <Geom_Surface.hxx>
58
59 static void SetShapeFlags(const TopoDS_Shape& theInSh, TopoDS_Shape& theOutSh);
60
61 //=======================================================================
62 //function : BRepTools_Modifier
63 //purpose  : 
64 //=======================================================================
65
66 BRepTools_Modifier::BRepTools_Modifier (Standard_Boolean theMutableInput):
67 myDone(Standard_False), myMutableInput (theMutableInput)
68 {}
69
70 //=======================================================================
71 //function : BRepTools_Modifier
72 //purpose  : 
73 //=======================================================================
74
75 BRepTools_Modifier::BRepTools_Modifier (const TopoDS_Shape& S) :
76 myShape(S),myDone(Standard_False), myMutableInput (Standard_False)
77 {
78   Put(S);
79 }
80
81 //=======================================================================
82 //function : BRepTools_Modifier
83 //purpose  : 
84 //=======================================================================
85
86 BRepTools_Modifier::BRepTools_Modifier
87   (const TopoDS_Shape& S,
88    const Handle(BRepTools_Modification)& M)
89    : myShape(S), myDone(Standard_False), 
90      myMutableInput (Standard_False)
91 {
92   Put(S);
93   Perform(M);
94 }
95
96
97 //=======================================================================
98 //function : Init
99 //purpose  : 
100 //=======================================================================
101
102 void BRepTools_Modifier::Init(const TopoDS_Shape& S)
103 {
104   myShape = S;
105   myDone = Standard_False;
106   Put(S);
107 }
108
109
110 //=======================================================================
111 //function : Perform
112 //purpose  : 
113 //=======================================================================
114 #ifdef DEBUG_Modifier
115 static TopTools_IndexedMapOfShape MapE, MapF;
116 #endif
117
118 void BRepTools_Modifier::Perform(const Handle(BRepTools_Modification)& M,
119                                  const Message_ProgressRange& theProgress)
120 {
121   if (myShape.IsNull()) {
122     throw Standard_NullObject();
123   }
124 #ifdef DEBUG_Modifier
125   MapE.Clear(); MapF.Clear();
126   TopExp::MapShapes(myShape, TopAbs_EDGE, MapE);
127   TopExp::MapShapes(myShape, TopAbs_FACE, MapF);
128 #endif
129   TopTools_DataMapIteratorOfDataMapOfShapeShape theIter(myMap);
130
131   Message_ProgressScope aPS(theProgress, "Converting Shape", 2);
132
133   TopTools_IndexedDataMapOfShapeListOfShape aMVE, aMEF;
134   TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
135   TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, aMEF);
136
137   CreateNewVertices(aMVE, M);
138
139   FillNewCurveInfo(aMEF, M);
140
141   FillNewSurfaceInfo(M);
142
143   if (!myMutableInput)
144     CreateOtherVertices(aMVE, aMEF, M);
145
146   Standard_Boolean aNewGeom;
147   Rebuild(myShape, M, aNewGeom, aPS.Next());
148
149   if (!aPS.More())
150   {
151     // The processing was broken
152     return;
153   }
154
155   if (myShape.ShapeType() == TopAbs_FACE) {
156     if (myShape.Orientation() == TopAbs_REVERSED) {
157       myMap(myShape).Reverse();
158     }
159     else{
160       myMap(myShape).Orientation(myShape.Orientation());
161     } 
162   }
163   else {
164     myMap(myShape).Orientation(myShape.Orientation());
165   }
166
167   // Update the continuities
168
169
170   BRep_Builder aBB;
171
172 /*
173   Standard_Boolean RecomputeTriangles = Standard_False;
174   Standard_Real MaxDeflection = RealFirst();
175   Handle(Poly_Triangulation) Tr;
176   Handle(Poly_Polygon3D) Po;
177   TopLoc_Location Loc;
178 */
179
180   for (int ii = 1; ii <= aMEF.Extent(); ii++)
181   {
182     const TopoDS_Edge& CurE = TopoDS::Edge(aMEF.FindKey(ii));
183     const TopoDS_Edge& NewE = TopoDS::Edge(myMap(CurE));
184     if (!CurE.IsSame(NewE)) {
185       TopTools_ListIteratorOfListOfShape it;
186       it.Initialize(aMEF.FindFromKey(CurE));
187       TopoDS_Face F1,F2;
188       while (it.More() && F2.IsNull()) {
189         if (F1.IsNull()) {
190           F1 = TopoDS::Face(it.Value());
191         }
192         else {
193           F2 = TopoDS::Face(it.Value());
194         }
195         it.Next();
196       }
197       if (!F2.IsNull()) {
198         const TopoDS_Face& newf1  = TopoDS::Face(myMap(F1));
199         const TopoDS_Face& newf2  = TopoDS::Face(myMap(F2));
200         GeomAbs_Shape Newcont = M->Continuity(CurE,F1,F2,NewE,newf1,newf2);
201         if (Newcont > GeomAbs_C0) {
202           aBB.Continuity(NewE,newf1,newf2,Newcont);
203         }
204       }
205     }
206     theIter.Next();
207   }
208 /*
209   if (RecomputeTriangles) {
210     BRepMesh_IncrementalMesh(myMap(myShape),MaxDeflection);
211   }
212 */
213
214   myDone = Standard_True;
215
216 }
217
218 //=======================================================================
219 //function : Put
220 //purpose  : 
221 //=======================================================================
222
223 void BRepTools_Modifier::Put(const TopoDS_Shape& S)
224 {
225   if (!myMap.IsBound(S)) {
226     myMap.Bind(S,TopoDS_Shape());
227     for(TopoDS_Iterator theIterator(S,Standard_False);theIterator.More();theIterator.Next()) {
228
229       Put(theIterator.Value());
230     }
231   }
232 }
233
234 //=======================================================================
235 //function : Rebuild
236 //purpose  : 
237 //=======================================================================
238
239 Standard_Boolean BRepTools_Modifier::Rebuild
240   (const TopoDS_Shape& S,
241    const Handle(BRepTools_Modification)& M,
242    Standard_Boolean& theNewGeom,
243    const Message_ProgressRange& theProgress)
244 {
245 #ifdef DEBUG_Modifier
246   int iF = MapF.Contains(S) ? MapF.FindIndex(S) : 0;
247   int iE = MapE.Contains(S) ? MapE.FindIndex(S) : 0;
248 #endif
249   TopAbs_ShapeEnum ts = S.ShapeType();
250   TopoDS_Shape& result = myMap(S);
251   if (!result.IsNull())
252   {
253     theNewGeom = myHasNewGeom.Contains(S);
254     return !S.IsSame(result);
255   }
256   Standard_Boolean rebuild = Standard_False, RevWires = Standard_False;
257   TopAbs_Orientation ResOr = TopAbs_FORWARD;
258   BRep_Builder B;
259   Standard_Real tol;
260   Standard_Boolean No3DCurve = Standard_False; // en fait, si on n`a pas de 
261   //modif geometry 3d , it is necessary to test the existence of a curve 3d.
262
263   // new geometry ?
264
265   switch (ts) {
266   case TopAbs_FACE:
267     {
268       rebuild = myNSInfo.IsBound(TopoDS::Face(S));
269       if (rebuild) 
270       {
271         const NewSurfaceInfo& aNSinfo = myNSInfo(TopoDS::Face(S));
272         RevWires = aNSinfo.myRevWires;
273         B.MakeFace(TopoDS::Face(result),aNSinfo.mySurface,
274           aNSinfo.myLoc.Predivided(S.Location()),aNSinfo.myToler);
275         result.Location(S.Location());
276         if (aNSinfo.myRevFace) 
277           ResOr = TopAbs_REVERSED;
278         // set specifics flags of a Face
279         B.NaturalRestriction(TopoDS::Face(result), BRep_Tool::NaturalRestriction(TopoDS::Face(S)));
280       }
281
282       // update triangulation on the copied face
283       Handle(Poly_Triangulation) aTriangulation;
284       if (M->NewTriangulation(TopoDS::Face(S), aTriangulation))
285       {
286         if (rebuild) // the copied face already exists => update it
287           B.UpdateFace(TopoDS::Face(result), aTriangulation);
288         else
289         { // create new face with bare triangulation
290           B.MakeFace(TopoDS::Face(result), aTriangulation);
291           result.Location(S.Location());
292         }
293         rebuild = Standard_True;
294       }
295     }
296     break;
297
298   case TopAbs_EDGE:
299     {
300       rebuild = myNCInfo.IsBound(TopoDS::Edge(S));
301       if (rebuild) 
302       {
303         const NewCurveInfo& aNCinfo = myNCInfo(TopoDS::Edge(S));
304         if (aNCinfo.myCurve.IsNull()) {
305           B.MakeEdge(TopoDS::Edge(result));
306           B.Degenerated(TopoDS::Edge(result),
307                         BRep_Tool::Degenerated(TopoDS::Edge(S)));
308           B.UpdateEdge(TopoDS::Edge(result),aNCinfo.myToler);  //OCC217
309           No3DCurve = Standard_True;
310         }
311         else {
312           B.MakeEdge(TopoDS::Edge(result),aNCinfo.myCurve,
313             aNCinfo.myLoc.Predivided(S.Location()),aNCinfo.myToler);
314           No3DCurve = Standard_False;
315         }
316         result.Location(S.Location());
317 //      result.Orientation(S.Orientation());
318
319         // set specifics flags of an Edge
320         B.SameParameter(TopoDS::Edge(result),
321                         BRep_Tool::SameParameter(TopoDS::Edge(S)));
322         B.SameRange(TopoDS::Edge(result),
323                     BRep_Tool::SameRange(TopoDS::Edge(S)));
324       }
325
326       // update polygonal structure on the edge
327       Handle(Poly_Polygon3D) aPolygon;
328       if (M->NewPolygon(TopoDS::Edge(S), aPolygon))
329       {
330         if (rebuild) // the copied edge already exists => update it
331           B.UpdateEdge(TopoDS::Edge(result), aPolygon, S.Location());
332         else
333         { // create new edge with bare polygon
334           B.MakeEdge(TopoDS::Edge(result), aPolygon);
335           result.Location(S.Location());
336         }
337         rebuild = Standard_True;
338       }
339     }
340     break;
341   default:
342     ;
343   }
344
345   // rebuild sub-shapes and test new sub-shape ?
346
347   Standard_Boolean newgeom = rebuild;
348   theNewGeom = rebuild;
349
350   TopoDS_Iterator it;
351
352   {
353     Standard_Integer aShapeCount = 0;
354     {
355       for (it.Initialize(S, Standard_False); it.More(); it.Next()) ++aShapeCount;
356     }
357     
358     Message_ProgressScope aPS(theProgress, "Converting SubShapes", aShapeCount);
359     //
360     for (it.Initialize(S, Standard_False); it.More() && aPS.More(); it.Next()) {
361       // always call Rebuild
362       Standard_Boolean isSubNewGeom = Standard_False;
363       Standard_Boolean subrebuilt = Rebuild(it.Value(), M, isSubNewGeom, aPS.Next());
364       rebuild =  subrebuilt || rebuild ;
365       theNewGeom = theNewGeom || isSubNewGeom;
366     }
367     if (!aPS.More())
368     {
369       // The processing was broken
370       return Standard_False;
371     }
372   }
373   if (theNewGeom)
374     myHasNewGeom.Add(S);
375
376   // make an empty copy
377   if (rebuild && !newgeom) {
378     result = S.EmptyCopied();
379     result.Orientation(TopAbs_FORWARD);
380   }
381
382   // copy the sub-elements 
383   
384   if (rebuild) {
385     TopAbs_Orientation orient;
386     for (it.Initialize(S,Standard_False); it.More(); it.Next()) {
387       orient = it.Value().Orientation();
388       if (RevWires || myMap(it.Value()).Orientation() == TopAbs_REVERSED) {
389         orient = TopAbs::Reverse(orient);
390       }
391       B.Add(result,myMap(it.Value()).Oriented(orient));
392     }
393
394
395     if (ts == TopAbs_FACE) {
396       // pcurves
397       Handle(Geom2d_Curve) curve2d; //,curve2d1;
398       TopoDS_Face face = TopoDS::Face(S);
399       TopAbs_Orientation fcor = face.Orientation();
400       if(fcor != TopAbs_REVERSED) fcor = TopAbs_FORWARD;
401
402       TopExp_Explorer ex(face.Oriented(fcor),TopAbs_EDGE);
403       for (;ex.More(); ex.Next()) 
404       {
405         const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
406
407 #ifdef DEBUG_Modifier
408         iE = MapE.Contains(edge) ? MapE.FindIndex(edge) : 0;
409 #endif
410         if (theNewGeom && M->NewCurve2d
411             (edge, face, TopoDS::Edge(myMap(ex.Current())), TopoDS::Face(result), curve2d, tol))
412         {
413           // rem dub 16/09/97 : Make constant topology or not make at all.
414           // Do not make if CopySurface = 1
415           // Atention, TRUE sewing edges (RealyClosed)  
416           // stay even if  CopySurface is true.
417     
418           // check that edge contains two pcurves on this surface:
419           // either it is true seam on the current face, or belongs to two faces
420           // built on that same surface (see OCC21772)
421           // Note: this check could be made separate method in BRepTools
422           Standard_Boolean isClosed = Standard_False;
423           if(BRep_Tool::IsClosed(edge,face))
424           {
425             isClosed = ( ! newgeom || BRepTools::IsReallyClosed(edge,face) );
426             if ( ! isClosed )
427             {
428               TopLoc_Location aLoc;
429               TopoDS_Shape resface = (myMap.IsBound(face) ? myMap(face) : face);
430               if(resface.IsNull())
431                 resface = face;
432               Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(resface), aLoc);
433               // check other faces sharing the same surface
434               TopExp_Explorer aExpF(myShape,TopAbs_FACE);
435               for( ; aExpF.More() && !isClosed; aExpF.Next())
436               {
437                 TopoDS_Face anOther = TopoDS::Face(aExpF.Current());
438                 if(anOther.IsSame(face))
439                   continue;
440                 TopoDS_Shape resface2 = (myMap.IsBound(anOther) ? myMap(anOther) : anOther);
441                 if(resface2.IsNull())
442                   resface2 = anOther;
443                 TopLoc_Location anOtherLoc;
444                 Handle(Geom_Surface) anOtherSurf = 
445                   BRep_Tool::Surface(TopoDS::Face(resface2), anOtherLoc);
446                 if ( aSurf == anOtherSurf && aLoc.IsEqual (anOtherLoc) )
447                 {
448                   TopExp_Explorer aExpE(anOther,TopAbs_EDGE);
449                   for( ; aExpE.More() && !isClosed ; aExpE.Next())
450                     isClosed = edge.IsSame(aExpE.Current());
451                 }
452               }
453             }
454           }
455           if (isClosed) 
456           {
457             TopoDS_Edge CurE = TopoDS::Edge(myMap(edge));
458             TopoDS_Shape aLocalResult = result;
459             aLocalResult.Orientation(TopAbs_FORWARD);
460             TopoDS_Face CurF = TopoDS::Face(aLocalResult);
461             Handle(Geom2d_Curve) curve2d1, currcurv;
462             Standard_Real f,l;
463             if ((!RevWires && fcor != edge.Orientation()) ||
464               ( RevWires && fcor == edge.Orientation())) {
465                 CurE.Orientation(TopAbs_FORWARD);
466                 curve2d1 = BRep_Tool::CurveOnSurface(CurE,CurF,f,l);
467                 if (curve2d1.IsNull()) curve2d1 = new Geom2d_Line(gp::OX2d());
468                 B.UpdateEdge (CurE, curve2d1, curve2d, CurF, 0.);
469             }
470             else {
471               CurE.Orientation(TopAbs_REVERSED);
472               curve2d1 = BRep_Tool::CurveOnSurface(CurE,CurF,f,l);
473               if (curve2d1.IsNull()) curve2d1 = new Geom2d_Line(gp::OX2d());
474               B.UpdateEdge (CurE, curve2d, curve2d1, CurF, 0.);
475             }
476             currcurv = BRep_Tool::CurveOnSurface(CurE,CurF,f,l);
477             B.Range(CurE,f,l);
478           }
479           else {
480             B.UpdateEdge(TopoDS::Edge(myMap(ex.Current())),
481               curve2d,
482               TopoDS::Face(result), 0.);
483           }
484
485           TopLoc_Location theLoc;
486           Standard_Real theF,theL;
487           Handle(Geom_Curve) C3D = BRep_Tool::Curve(TopoDS::Edge(myMap(ex.Current())), theLoc, theF, theL);
488           if (C3D.IsNull()) { // Update vertices
489             Standard_Real param;
490             TopExp_Explorer ex2(edge,TopAbs_VERTEX);
491             while (ex2.More()) {
492               const TopoDS_Vertex& vertex = TopoDS::Vertex(ex2.Current());
493               if (!M->NewParameter(vertex, edge, param, tol)) {
494                 tol = BRep_Tool::Tolerance(vertex);
495                 param = BRep_Tool::Parameter(vertex,edge);
496               }
497
498               TopAbs_Orientation vtxrelat = vertex.Orientation();
499               if (edge.Orientation() == TopAbs_REVERSED) {
500                 // Update considere l'edge FORWARD, et le vertex en relatif
501                 vtxrelat= TopAbs::Reverse(vtxrelat);
502               }
503               //if (myMap(edge).Orientation() == TopAbs_REVERSED) {
504               //  vtxrelat= TopAbs::Reverse(vtxrelat);
505               //}
506
507               TopoDS_Vertex aLocalVertex = TopoDS::Vertex(myMap(vertex));
508               aLocalVertex.Orientation(vtxrelat);
509               //B.UpdateVertex(TopoDS::Vertex
510               //(myMap(vertex).Oriented(vtxrelat)),
511               B.UpdateVertex(aLocalVertex, param, TopoDS::Edge(myMap(edge)), tol);
512               ex2.Next();
513             }
514           }
515         }
516
517         // Copy polygon on triangulation
518         Handle(Poly_PolygonOnTriangulation) aPolyOnTria_1, aPolyOnTria_2;
519         Standard_Boolean aNewPonT = M->NewPolygonOnTriangulation(edge, face, aPolyOnTria_1);
520         if (BRepTools::IsReallyClosed(edge, face))
521         {
522           // Obtain triangulation on reversed edge
523           TopoDS_Edge anEdgeRev = edge;
524           anEdgeRev.Reverse();
525           aNewPonT = M->NewPolygonOnTriangulation(anEdgeRev, face, aPolyOnTria_2) || aNewPonT;
526           // It there is only one polygon on triangulation, store it to aPolyOnTria_1
527           if (aPolyOnTria_1.IsNull() && !aPolyOnTria_2.IsNull())
528           {
529             aPolyOnTria_1 = aPolyOnTria_2;
530             aPolyOnTria_2 = Handle(Poly_PolygonOnTriangulation)();
531           }
532         }
533         if (aNewPonT)
534         {
535           TopLoc_Location aLocation;
536           Handle(Poly_Triangulation) aNewFaceTria =
537               BRep_Tool::Triangulation(TopoDS::Face(myMap(face)), aLocation);
538           TopoDS_Edge aNewEdge = TopoDS::Edge(myMap(edge));
539           if (aPolyOnTria_2.IsNull())
540             B.UpdateEdge(aNewEdge, aPolyOnTria_1, aNewFaceTria, aLocation);
541           else
542           {
543             if (edge.Orientation() == TopAbs_FORWARD)
544               B.UpdateEdge(aNewEdge, aPolyOnTria_1, aPolyOnTria_2, aNewFaceTria, aLocation);
545             else
546               B.UpdateEdge(aNewEdge, aPolyOnTria_2, aPolyOnTria_1, aNewFaceTria, aLocation);
547           }
548         }
549       }
550
551     }
552
553 //    else if (ts == TopAbs_EDGE) {
554     else if (ts == TopAbs_EDGE && !No3DCurve) {
555       // Vertices
556       Standard_Real param;
557       const TopoDS_Edge& edge = TopoDS::Edge(S);
558       TopAbs_Orientation edor = edge.Orientation();
559       if(edor != TopAbs_REVERSED) edor = TopAbs_FORWARD;
560       TopExp_Explorer ex(edge.Oriented(edor), TopAbs_VERTEX);
561       while (ex.More()) {
562         const TopoDS_Vertex& vertex = TopoDS::Vertex(ex.Current());
563
564         if (!M->NewParameter(vertex, edge, param, tol)) {
565           tol = BRep_Tool::Tolerance(vertex);
566           param = BRep_Tool::Parameter(vertex,edge);
567         }
568
569         TopAbs_Orientation vtxrelat = vertex.Orientation();
570         if (edor == TopAbs_REVERSED) {
571           // Update considere l'edge FORWARD, et le vertex en relatif
572           vtxrelat= TopAbs::Reverse(vtxrelat);
573         }
574
575         //if (result.Orientation() == TopAbs_REVERSED) {
576         //  vtxrelat= TopAbs::Reverse(vtxrelat);
577         //}
578         TopoDS_Vertex aLocalVertex = TopoDS::Vertex(myMap(vertex));
579         aLocalVertex.Orientation(vtxrelat);
580         //B.UpdateVertex(TopoDS::Vertex(myMap(vertex).Oriented(vtxrelat)),
581         if (myMutableInput || !aLocalVertex.IsSame(vertex))
582           B.UpdateVertex(aLocalVertex, param, TopoDS::Edge(result), tol);
583         ex.Next();
584       }
585
586     }
587
588     // update flags
589
590     result.Orientable(S.Orientable());
591     result.Closed(S.Closed());
592     result.Infinite(S.Infinite());
593   }
594   else
595     result = S;
596
597   // Set flag of the shape.
598   result.Orientation(ResOr);
599
600   SetShapeFlags(S, result);
601
602   return rebuild;
603 }
604
605 void BRepTools_Modifier::CreateNewVertices( const TopTools_IndexedDataMapOfShapeListOfShape& theMVE, const Handle(BRepTools_Modification)& M)
606 {
607   double aToler;
608   BRep_Builder aBB;
609   gp_Pnt aPnt;  
610   for (int i = 1; i <= theMVE.Extent(); i++ )
611   {
612     //fill MyMap only with vertices with NewPoint == true
613     const TopoDS_Vertex& aV = TopoDS::Vertex(theMVE.FindKey(i));
614     Standard_Boolean IsNewP = M->NewPoint(aV, aPnt, aToler);
615     if (IsNewP)
616     {
617       TopoDS_Vertex aNewV;
618       aBB.MakeVertex(aNewV, aPnt, aToler);
619       SetShapeFlags(aV, aNewV);
620       myMap(aV) = aNewV;
621       myHasNewGeom.Add(aV);
622     }
623     else if (myMutableInput)
624       myMap(aV) = aV.Oriented(TopAbs_FORWARD);
625   }
626 }
627
628 void BRepTools_Modifier::FillNewCurveInfo(const TopTools_IndexedDataMapOfShapeListOfShape& theMEF, const Handle(BRepTools_Modification)& M)
629 {
630   Handle(Geom_Curve) aCurve;
631   TopLoc_Location aLocation;
632   BRepTools_Modifier::NewCurveInfo aNCinfo;
633   double aToler;
634   for (int i = 1; i <= theMEF.Extent(); i++ )
635   {
636     const TopoDS_Edge& anE = TopoDS::Edge(theMEF.FindKey(i));
637     Standard_Boolean IsNewCur = M->NewCurve(anE, aCurve, aLocation, aToler);
638     if (IsNewCur)
639     {
640       aNCinfo.myCurve = aCurve;
641       aNCinfo.myLoc = aLocation;
642       aNCinfo.myToler = aToler;
643       myNCInfo.Bind(anE, aNCinfo);
644       myHasNewGeom.Add(anE);
645     }
646   }
647 }
648
649 void BRepTools_Modifier::FillNewSurfaceInfo(const Handle(BRepTools_Modification)& M)
650 {
651   TopTools_IndexedMapOfShape aMF;  
652   TopExp::MapShapes(myShape, TopAbs_FACE, aMF);
653   BRepTools_Modifier::NewSurfaceInfo aNSinfo;
654   for (int i = 1; i <= aMF.Extent(); i++ )
655   {
656     const TopoDS_Face& aF = TopoDS::Face(aMF(i));
657     Standard_Boolean RevFace;
658     Standard_Boolean RevWires;
659     Handle(Geom_Surface) aSurface;
660     TopLoc_Location aLocation;
661     double aToler1;
662     Standard_Boolean IsNewSur = M->NewSurface(aF, aSurface, aLocation, aToler1, RevWires,RevFace);
663     if (IsNewSur)
664     {
665       aNSinfo.mySurface = aSurface;
666       aNSinfo.myLoc = aLocation;
667       aNSinfo.myToler = aToler1;
668       aNSinfo.myRevWires = RevWires;
669       aNSinfo.myRevFace = RevFace;
670       myNSInfo.Bind(aF, aNSinfo);
671       myHasNewGeom.Add(aF);
672     }
673     else
674     {
675       //check if subshapes will be modified 
676       Standard_Boolean notRebuilded = Standard_True;
677       TopExp_Explorer exE(aF, TopAbs_EDGE);
678       while (exE.More() && notRebuilded) 
679       {
680         const TopoDS_Edge& anEE = TopoDS::Edge(exE.Current());
681         if (myNCInfo.IsBound(anEE))
682         {
683           notRebuilded = Standard_False;
684           break;
685         }
686         TopExp_Explorer exV(anEE, TopAbs_VERTEX);
687         while (exV.More() && notRebuilded) 
688         {
689           const TopoDS_Vertex& aVV = TopoDS::Vertex(exV.Current());
690           if (!myMap(aVV).IsNull())
691           {
692             notRebuilded = Standard_False;
693             break;
694           }
695           exV.Next();
696         }
697         exE.Next();
698       }
699       if (notRebuilded)
700       {
701         //subshapes is not going to be modified
702         myNonUpdFace.Add(aF); 
703       }
704     }
705   }
706
707 }
708
709 void BRepTools_Modifier::CreateOtherVertices(const TopTools_IndexedDataMapOfShapeListOfShape& theMVE, 
710                                              const TopTools_IndexedDataMapOfShapeListOfShape& theMEF, 
711                                              const Handle(BRepTools_Modification)& M)
712 {
713   double aToler;
714   //The following logic in some ways repeats the logic from the Rebuild() method.
715   //If the face with its subshapes is not going to be modified 
716   //(i.e. NewSurface() for this face and NewCurve(), NewPoint() for its edges/vertices returns false)
717   //then the calling of NewCurve2d() for this face with its edges is not performed. 
718   //Therefore, the updating of vertices will not present in such cases and 
719   //the EmptyCopied() operation for vertices from this face is not needed. 
720
721   for (int i = 1; i <= theMVE.Extent(); i++ )
722   {
723     const TopoDS_Vertex& aV = TopoDS::Vertex(theMVE.FindKey(i));
724     TopoDS_Vertex aNewV = TopoDS::Vertex(myMap(aV));
725     if ( aNewV.IsNull()) 
726     {
727        const TopTools_ListOfShape& aLEdges = theMVE(i);
728        Standard_Boolean toReplace = Standard_False;
729        TopTools_ListIteratorOfListOfShape it(aLEdges);
730        for (; it.More() && !toReplace; it.Next()) 
731        {
732          const TopoDS_Edge& anE = TopoDS::Edge(it.Value());
733          if (myNCInfo.IsBound(anE) && !myNCInfo(anE).myCurve.IsNull())
734             toReplace = Standard_True;
735
736          if (!toReplace)
737          {
738            const TopTools_ListOfShape& aLFaces = theMEF.FindFromKey(anE);
739            TopTools_ListIteratorOfListOfShape it2(aLFaces);
740            for (; it2.More(); it2.Next()) 
741            {
742              const TopoDS_Face& aF = TopoDS::Face(it2.Value());
743              if (!myNonUpdFace.Contains(aF))
744              {
745                Handle(Geom2d_Curve) aCurve2d;
746                //some NewCurve2d()s may use NewE arg internally, so the 
747                //null TShape as an arg may lead to the exceptions 
748                TopoDS_Edge aDummyE = TopoDS::Edge(anE.EmptyCopied());
749                if (M->NewCurve2d(anE, aF, aDummyE, TopoDS_Face(), aCurve2d, aToler))
750                {
751                  toReplace = true;
752                  break;
753                }
754              }
755            }
756          }
757        }
758        if (toReplace)
759          aNewV = TopoDS::Vertex(aV.EmptyCopied());
760        else
761          aNewV = aV;
762        aNewV.Orientation(TopAbs_FORWARD);
763        myMap(aV) = aNewV;
764     }
765   }
766 }
767
768
769 static void SetShapeFlags(const TopoDS_Shape& theInSh, TopoDS_Shape& theOutSh)
770 {
771   theOutSh.Modified  (theInSh.Modified());
772   theOutSh.Checked   (theInSh.Checked());
773   theOutSh.Orientable(theInSh.Orientable());
774   theOutSh.Closed    (theInSh.Closed());
775   theOutSh.Infinite  (theInSh.Infinite());
776   theOutSh.Convex    (theInSh.Convex());
777 }
778
779
780 Standard_Boolean BRepTools_Modifier::IsMutableInput() const
781 {
782   return myMutableInput;
783 }
784
785 void BRepTools_Modifier::SetMutableInput(Standard_Boolean theMutableInput)
786 {
787   myMutableInput = theMutableInput;
788 }
789