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