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