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