0022312: Translation of french commentaries in OCCT files
[occt.git] / src / BRepTools / BRepTools_Modifier.cxx
1 // File:        BRepTools_Modifier.cxx
2 // Created:     Thu Aug 25 10:48:00 1994
3 // Author:      Jacques GOUSSARD
4 //              <jag@ecolox>
5
6 // IFV 04.06.99 - PRO18974 - processing of INTERNAL shapes.
7
8 #include <BRepTools_Modifier.ixx>
9
10 #include <TopoDS_Iterator.hxx>
11 #include <TopoDS_Vertex.hxx>
12 #include <TopoDS_Edge.hxx>
13 #include <TopoDS_Face.hxx>
14 #include <TopoDS_Shape.hxx>
15 #include <TopExp_Explorer.hxx>
16 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
17 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
18 #include <TopTools_ListOfShape.hxx>
19 #include <TopTools_ListIteratorOfListOfShape.hxx>
20 #include <TColStd_ListOfTransient.hxx>
21 #include <TColStd_ListIteratorOfListOfTransient.hxx>
22
23 #if 0
24 #include <Poly_Triangulation.hxx>
25 #include <Poly_Polygon3D.hxx>
26 #include <BRepMesh_IncrementalMesh.hxx>
27 #endif
28
29 #include <Geom2d_Line.hxx>
30 #include <BRep_Builder.hxx>
31 #include <BRep_Tool.hxx>
32 #include <TopoDS.hxx>
33 #include <BRepTools.hxx>
34 #include <TopAbs.hxx>
35 #include <TopExp.hxx>
36 #include <gp_Pnt.hxx>
37
38 #include <gp.hxx>
39
40 #include <Standard_NullObject.hxx>
41 #include <gp_Trsf.hxx>
42 #include <BRepTools_TrsfModification.hxx>
43
44
45
46 //=======================================================================
47 //function : BRepTools_Modifier
48 //purpose  : 
49 //=======================================================================
50
51 BRepTools_Modifier::BRepTools_Modifier ():myDone(Standard_False)
52 {}
53
54 //=======================================================================
55 //function : BRepTools_Modifier
56 //purpose  : 
57 //=======================================================================
58
59 BRepTools_Modifier::BRepTools_Modifier (const TopoDS_Shape& S) :
60   myShape(S),myDone(Standard_False)
61 {
62   myMap.Clear();
63   Put(S);
64 }
65
66 //=======================================================================
67 //function : BRepTools_Modifier
68 //purpose  : 
69 //=======================================================================
70
71 BRepTools_Modifier::BRepTools_Modifier
72   (const TopoDS_Shape& S,
73    const Handle(BRepTools_Modification)& M) : myShape(S),myDone(Standard_False)
74 {
75   myMap.Clear();
76   Put(S);
77   Perform(M);
78 }
79
80
81 //=======================================================================
82 //function : Init
83 //purpose  : 
84 //=======================================================================
85
86 void BRepTools_Modifier::Init(const TopoDS_Shape& S)
87 {
88   myShape = S;
89   myDone = Standard_False;
90   myMap.Clear();
91   Put(S);
92 }
93
94
95 //=======================================================================
96 //function : Perform
97 //purpose  : 
98 //=======================================================================
99
100 void BRepTools_Modifier::Perform(const Handle(BRepTools_Modification)& M)
101 {
102   if (myShape.IsNull()) {
103     Standard_NullObject::Raise();
104   }
105   TopTools_DataMapIteratorOfDataMapOfShapeShape theIter(myMap);
106
107   // Set to Null the value of shapes, in case when another modification is applied to the start shape.
108
109   if (!theIter.Value().IsNull()) {
110     while (theIter.More()) {
111       myMap(theIter.Value()).Nullify();
112       theIter.Next();
113     }
114     theIter.Reset();
115   }
116
117   /*
118   while (theIter.More()) {
119     Rebuild(theIter.Key(),M);
120     theIter.Next();
121   }
122   */
123
124   Rebuild(myShape,M);
125
126   if (myShape.ShapeType() == TopAbs_FACE) {
127     if (myShape.Orientation() == TopAbs_REVERSED) {
128       myMap(myShape).Reverse();
129     }
130     else{
131       myMap(myShape).Orientation(myShape.Orientation());
132     } 
133   }
134   else {
135     myMap(myShape).Orientation(myShape.Orientation());
136   }
137
138   // Update the continuities
139
140   TopTools_IndexedDataMapOfShapeListOfShape theEFMap;
141   TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,theEFMap);
142   BRep_Builder B;
143
144 /*
145   Standard_Boolean RecomputeTriangles = Standard_False;
146   Standard_Real MaxDeflection = RealFirst();
147   Handle(Poly_Triangulation) Tr;
148   Handle(Poly_Polygon3D) Po;
149   TopLoc_Location Loc;
150 */
151
152   while (theIter.More()) {
153     const TopoDS_Shape& S = theIter.Key();
154 /*
155     if (S.ShapeType() == TopAbs_FACE && !S.IsSame(theIter.Value())) {
156       Tr = BRep_Tool::Triangulation(TopoDS::Face(S),Loc);
157       if (!Tr.IsNull()) {
158         RecomputeTriangles = Standard_True;
159         MaxDeflection = Max(MaxDeflection,Tr->Deflection());
160       }
161     }
162     else */ if (S.ShapeType() == TopAbs_EDGE && !S.IsSame(theIter.Value())) {
163       const TopoDS_Edge& edg = TopoDS::Edge(S);
164 /*
165       Po = BRep_Tool::Polygon3D(edg,Loc);
166       if (!Po.IsNull()) {
167         RecomputeTriangles = Standard_True;
168         MaxDeflection = Max(MaxDeflection,Po->Deflection());
169       }
170 */
171       TopTools_ListIteratorOfListOfShape it;
172       it.Initialize(theEFMap.FindFromKey(edg));
173       TopoDS_Face F1,F2;
174       while (it.More() && F2.IsNull()) {
175         if (F1.IsNull()) {
176           F1 = TopoDS::Face(it.Value());
177         }
178         else {
179           F2 = TopoDS::Face(it.Value());
180         }
181         it.Next();
182       }
183       if (!F2.IsNull()) {
184         const TopoDS_Edge& newedg = TopoDS::Edge(myMap(edg));
185         const TopoDS_Face& newf1  = TopoDS::Face(myMap(F1));
186         const TopoDS_Face& newf2  = TopoDS::Face(myMap(F2));
187         GeomAbs_Shape Newcont = M->Continuity(edg,F1,F2,newedg,newf1,newf2);
188         if (Newcont > GeomAbs_C0) {
189           B.Continuity(newedg,newf1,newf2,Newcont);
190         }
191       }
192     }
193     theIter.Next();
194   }
195 /*
196   if (RecomputeTriangles) {
197     BRepMesh_IncrementalMesh(myMap(myShape),MaxDeflection);
198   }
199 */
200
201   myDone = Standard_True;
202
203 }
204
205 //=======================================================================
206 //function : Put
207 //purpose  : 
208 //=======================================================================
209
210 void BRepTools_Modifier::Put(const TopoDS_Shape& S)
211 {
212   if (!myMap.IsBound(S)) {
213     myMap.Bind(S,TopoDS_Shape());
214     for(TopoDS_Iterator theIterator(S,Standard_False);theIterator.More();theIterator.Next()) {
215
216       Put(theIterator.Value());
217     }
218   }
219 }
220
221 //=======================================================================
222 //function : Rebuild
223 //purpose  : 
224 //=======================================================================
225
226 Standard_Boolean BRepTools_Modifier::Rebuild
227   (const TopoDS_Shape& S,
228    const Handle(BRepTools_Modification)& M)
229 {
230   TopoDS_Shape& result = myMap(S);
231 //  if (!result.IsNull()) return ! S.IsEqual(result);
232   if (!result.IsNull()) return ! S.IsSame(result);
233   Standard_Boolean rebuild = Standard_False, RevWires = Standard_False;
234   TopAbs_Orientation ResOr = TopAbs_FORWARD;
235   BRep_Builder B;
236   Standard_Real tol;
237   Standard_Boolean No3DCurve = Standard_False; // en fait, si on n`a pas de 
238   //modif geometry 3d , it is necessary to test the existence of a curve 3d.
239
240   // new geometry ?
241
242   TopAbs_ShapeEnum ts = S.ShapeType();
243   switch (ts) {
244   case TopAbs_FACE:
245     {
246       Standard_Boolean RevFace;
247       Handle(Geom_Surface) surface;
248       TopLoc_Location location;
249       rebuild = M->NewSurface(TopoDS::Face(S),surface,location,tol,
250                               RevWires,RevFace);
251       if (rebuild) {
252         B.MakeFace(TopoDS::Face(result),surface,
253                    location.Predivided(S.Location()),tol);
254         result.Location(S.Location());
255 //      result.Orientation(S.Orientation());
256         if (RevFace) {
257           ResOr = TopAbs_REVERSED;
258         }
259         // set specifics flags of a Face
260         B.NaturalRestriction(TopoDS::Face(result),
261                              BRep_Tool::NaturalRestriction(TopoDS::Face(S)));
262       }
263     }
264     break;
265
266   case TopAbs_EDGE:
267     {
268       Handle(Geom_Curve) curve;
269       TopLoc_Location location;
270       rebuild = M->NewCurve(TopoDS::Edge(S),curve,location,tol);
271       if (rebuild) {
272         if (curve.IsNull()) {
273           B.MakeEdge(TopoDS::Edge(result));
274           B.Degenerated(TopoDS::Edge(result),
275                         BRep_Tool::Degenerated(TopoDS::Edge(S)));
276           B.UpdateEdge(TopoDS::Edge(result),tol);  //OCC217
277           No3DCurve = Standard_True;
278         }
279         else {
280           B.MakeEdge(TopoDS::Edge(result),curve,
281                      location.Predivided(S.Location()),tol);
282           No3DCurve = Standard_False;
283         }
284         result.Location(S.Location());
285 //      result.Orientation(S.Orientation());
286
287         // set specifics flags of an Edge
288         B.SameParameter(TopoDS::Edge(result),
289                         BRep_Tool::SameParameter(TopoDS::Edge(S)));
290         B.SameRange(TopoDS::Edge(result),
291                     BRep_Tool::SameRange(TopoDS::Edge(S)));
292       }
293     }
294     break;
295
296   case TopAbs_VERTEX:
297     {
298       gp_Pnt vtx;
299       rebuild = M->NewPoint(TopoDS::Vertex(S),vtx,tol);
300       if (rebuild) {
301         B.MakeVertex(TopoDS::Vertex(result),vtx,tol);
302       }
303     }
304     break;
305
306   default:
307     {
308     }
309   }
310
311   // rebuild sub-shapes and test new sub-shape ?
312
313   Standard_Boolean newgeom = rebuild;
314
315   TopoDS_Iterator it;
316
317   for (it.Initialize(S, Standard_False); it.More(); it.Next()) {
318     // always call Rebuild
319     Standard_Boolean subrebuilt = Rebuild(it.Value(),M);
320     rebuild =  subrebuilt || rebuild ;
321   }
322
323   // make an empty copy
324   if (rebuild && !newgeom) {
325     result = S.EmptyCopied();
326     result.Orientation(TopAbs_FORWARD);
327   }
328
329   // copy the sub-elements 
330   
331   if (rebuild) {
332     TopAbs_Orientation orient;
333     for (it.Initialize(S,Standard_False); it.More(); it.Next()) {
334       orient = it.Value().Orientation();
335       if (RevWires || myMap(it.Value()).Orientation() == TopAbs_REVERSED) {
336         orient = TopAbs::Reverse(orient);
337       }
338       B.Add(result,myMap(it.Value()).Oriented(orient));
339     }
340
341
342     if (ts == TopAbs_FACE) {
343       // pcurves
344       Handle(Geom2d_Curve) curve2d; //,curve2d1;
345       TopoDS_Face face = TopoDS::Face(S);
346       TopAbs_Orientation fcor = face.Orientation();
347       if(fcor != TopAbs_REVERSED) fcor = TopAbs_FORWARD;
348
349       TopExp_Explorer ex(face.Oriented(fcor),TopAbs_EDGE);
350       for (;ex.More(); ex.Next()) 
351       {
352         const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
353
354         if (M->NewCurve2d(edge, face,TopoDS::Edge(myMap(ex.Current())),
355                           TopoDS::Face(result),curve2d, tol)) 
356         {
357           // rem dub 16/09/97 : Make constant topology or not make at all.
358           // Do not make if CopySurface = 1
359           // Atention, TRUE sewing edges (RealyClosed)  
360           // stay even if  CopySurface is true.
361     
362           // check that edge contains two pcurves on this surface:
363           // either it is true seam on the current face, or belongs to two faces
364           // built on that same surface (see OCC21772)
365           // Note: this check could be made separate method in BRepTools
366           Standard_Boolean isClosed = Standard_False;
367           if(BRep_Tool::IsClosed(edge,face))
368           {
369             isClosed = ( ! newgeom || BRepTools::IsReallyClosed(edge,face) );
370             if ( ! isClosed )
371             {
372               TopLoc_Location aLoc;
373               TopoDS_Shape resface = (myMap.IsBound(face) ? myMap(face) : face);
374               if(resface.IsNull())
375                 resface = face;
376               Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(resface), aLoc);
377               // check other faces sharing the same surface
378               TopExp_Explorer aExpF(myShape,TopAbs_FACE);
379               for( ; aExpF.More() && !isClosed; aExpF.Next())
380               {
381                 TopoDS_Face anOther = TopoDS::Face(aExpF.Current());
382                 if(anOther.IsSame(face))
383                   continue;
384                 TopoDS_Shape resface2 = (myMap.IsBound(anOther) ? myMap(anOther) : anOther);
385                 if(resface2.IsNull())
386                   resface2 = anOther;
387                 TopLoc_Location anOtherLoc;
388                 Handle(Geom_Surface) anOtherSurf = 
389                   BRep_Tool::Surface(TopoDS::Face(resface2), anOtherLoc);
390                 if ( aSurf == anOtherSurf && aLoc.IsEqual (anOtherLoc) )
391                 {
392                   TopExp_Explorer aExpE(anOther,TopAbs_EDGE);
393                   for( ; aExpE.More() && !isClosed ; aExpE.Next())
394                     isClosed = edge.IsSame(aExpE.Current());
395                 }
396               }
397             }
398           }
399           if (isClosed) 
400           {
401             TopoDS_Edge CurE = TopoDS::Edge(myMap(edge));
402             TopoDS_Shape aLocalResult = result;
403             aLocalResult.Orientation(TopAbs_FORWARD);
404             TopoDS_Face CurF = TopoDS::Face(aLocalResult);
405             Handle(Geom2d_Curve) curve2d1, currcurv;
406             Standard_Real f,l;
407             if ((!RevWires && fcor != edge.Orientation()) ||
408                 ( RevWires && fcor == edge.Orientation())) {
409               CurE.Orientation(TopAbs_FORWARD);
410               curve2d1 = BRep_Tool::CurveOnSurface(CurE,CurF,f,l);
411               if (curve2d1.IsNull()) curve2d1 = new Geom2d_Line(gp::OX2d());
412               B.UpdateEdge (CurE, curve2d1, curve2d, CurF, 0.);
413             }
414             else {
415               CurE.Orientation(TopAbs_REVERSED);
416               curve2d1 = BRep_Tool::CurveOnSurface(CurE,CurF,f,l);
417               if (curve2d1.IsNull()) curve2d1 = new Geom2d_Line(gp::OX2d());
418               B.UpdateEdge (CurE, curve2d, curve2d1, CurF, 0.);
419             }
420             currcurv = BRep_Tool::CurveOnSurface(edge,face,f,l);
421             B.Range(edge,f,l);
422           }
423           else {
424             B.UpdateEdge(TopoDS::Edge(myMap(ex.Current())),
425                          curve2d,
426                          TopoDS::Face(result), 0.);
427           }
428
429           TopLoc_Location theLoc;
430           Standard_Real theF,theL;
431           Handle(Geom_Curve) C3D =
432             BRep_Tool::Curve(TopoDS::Edge(myMap(ex.Current())),
433                              theLoc,theF,theL);
434           if (C3D.IsNull()) { // Update vertices
435             Standard_Real param;
436             TopExp_Explorer ex2(edge,TopAbs_VERTEX);
437             while (ex2.More()) {
438               const TopoDS_Vertex& vertex = TopoDS::Vertex(ex2.Current());
439               if (!M->NewParameter(vertex, edge, param, tol)) {
440                 tol = BRep_Tool::Tolerance(vertex);
441                 param = BRep_Tool::Parameter(vertex,edge);
442               }
443
444               TopAbs_Orientation vtxrelat = vertex.Orientation();
445               if (edge.Orientation() == TopAbs_REVERSED) {
446                 // Update considere l'edge FORWARD, et le vertex en relatif
447                 vtxrelat= TopAbs::Reverse(vtxrelat);
448               }
449 //            if (myMap(edge).Orientation() == TopAbs_REVERSED) {
450 //              vtxrelat= TopAbs::Reverse(vtxrelat);
451 //            }
452               TopoDS_Vertex aLocalVertex = TopoDS::Vertex(myMap(vertex));
453               aLocalVertex.Orientation(vtxrelat);
454 //            B.UpdateVertex(TopoDS::Vertex
455 //                           (myMap(vertex).Oriented(vtxrelat)),
456               B.UpdateVertex(aLocalVertex,
457                              param,
458                              TopoDS::Edge(myMap(edge)),
459                              tol);
460               ex2.Next();
461             }
462           }
463
464         }
465       }
466
467     }
468
469 //    else if (ts == TopAbs_EDGE) {
470     else if (ts == TopAbs_EDGE && !No3DCurve) {
471       // Vertices
472       Standard_Real param;
473       const TopoDS_Edge& edge = TopoDS::Edge(S);
474       TopAbs_Orientation edor = edge.Orientation();
475       if(edor != TopAbs_REVERSED) edor = TopAbs_FORWARD;
476       TopExp_Explorer ex(edge.Oriented(edor), TopAbs_VERTEX);
477       while (ex.More()) {
478         const TopoDS_Vertex& vertex = TopoDS::Vertex(ex.Current());
479
480         if (!M->NewParameter(vertex, edge, param, tol)) {
481           tol = BRep_Tool::Tolerance(vertex);
482           param = BRep_Tool::Parameter(vertex,edge);
483         }
484
485
486         TopAbs_Orientation vtxrelat = vertex.Orientation();
487         if (edor == TopAbs_REVERSED) {
488           // Update considere l'edge FORWARD, et le vertex en relatif
489           vtxrelat= TopAbs::Reverse(vtxrelat);
490         }
491 //      if (result.Orientation() == TopAbs_REVERSED) {
492 //        vtxrelat= TopAbs::Reverse(vtxrelat);
493 //      }
494         TopoDS_Vertex aLocalVertex = TopoDS::Vertex(myMap(vertex));
495         aLocalVertex.Orientation(vtxrelat);
496 //      B.UpdateVertex(TopoDS::Vertex
497 //                     (myMap(vertex).Oriented(vtxrelat)),
498         B.UpdateVertex(aLocalVertex,
499                        param,
500                        TopoDS::Edge(result),
501                        tol);
502
503         ex.Next();
504       }
505
506     }
507
508     // update flags
509
510     result.Orientable(S.Orientable());
511     result.Closed(S.Closed());
512     result.Infinite(S.Infinite());
513   }
514   else
515     result = S;
516
517   // Set flag of the shape.
518   result.Orientation(ResOr);
519
520   result.Free      (S.Free());
521   result.Modified  (S.Modified());
522   result.Checked   (S.Checked());
523   result.Orientable(S.Orientable());
524   result.Closed    (S.Closed());
525   result.Infinite  (S.Infinite());
526   result.Convex    (S.Convex());
527
528   return rebuild;
529 }
530
531