0023024: Update headers of OCCT files
[occt.git] / src / BRepOffset / BRepOffset_MakeLoops.cxx
1 // Created on: 1996-09-05
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1996-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 #include <stdio.h>
23
24 #include <BRepOffset_MakeLoops.ixx>
25 #include <BRepAlgo_Loop.hxx>
26
27
28 #include <BRep_Builder.hxx>
29 #include <BRep_Tool.hxx>
30 #include <TopExp.hxx>
31 #include <TopExp_Explorer.hxx>
32 #include <TopTools_ListIteratorOfListOfShape.hxx>
33 #include <TopoDS.hxx>
34 #include <TopoDS_Face.hxx>
35 #include <TopoDS_Edge.hxx>
36 #include <TopoDS_Vertex.hxx>
37 #include <TopTools_MapOfShape.hxx>
38 #include <TopoDS_Iterator.hxx>
39 #include <BRep_TVertex.hxx>
40
41 #ifdef DRAW
42 #include <DBRep.hxx>
43 #endif
44 #ifdef DEB
45 Standard_Integer NbF = 1;
46 static Standard_Boolean Affich = Standard_False;
47 //POP pour NT
48 //char name[100];
49 #endif
50
51
52 BRepOffset_MakeLoops::BRepOffset_MakeLoops()
53 {
54 }
55
56 //=======================================================================
57 //function : Build
58 //purpose  : 
59 //=======================================================================
60
61 void BRepOffset_MakeLoops::Build(const TopTools_ListOfShape&   LF, 
62                                  const Handle(BRepAlgo_AsDes)& AsDes, 
63                                  BRepAlgo_Image&               Image)
64 {
65   TopTools_ListIteratorOfListOfShape    it(LF);
66   TopTools_ListIteratorOfListOfShape    itl,itLCE;
67   BRepAlgo_Loop                       Loops;
68   Loops.VerticesForSubstitute( myVerVerMap );
69
70   for (; it.More(); it.Next()) {
71     const TopoDS_Face& F = TopoDS::Face(it.Value());
72     //---------------------------
73     // Initialization of Loops.
74     //---------------------------
75     Loops.Init(F);
76     //-----------------------------
77     // return edges of F.
78     //-----------------------------
79     const TopTools_ListOfShape& LE = AsDes->Descendant(F);
80     TopTools_ListOfShape        AddedEdges;
81
82     for (itl.Initialize(LE); itl.More(); itl.Next()) {
83       TopoDS_Edge E = TopoDS::Edge(itl.Value());
84       if (Image.HasImage(E)) {
85         //-------------------------------------------
86         // E was already cut in another face.
87         // Return the cut edges reorientate them as E.
88         // See pb for the edges that have disappeared?
89         //-------------------------------------------
90         const TopTools_ListOfShape& LCE = Image.Image(E);
91         for (itLCE.Initialize(LCE); itLCE.More(); itLCE.Next()) {
92           TopoDS_Shape CE = itLCE.Value().Oriented(E.Orientation()); 
93           Loops.AddConstEdge(TopoDS::Edge(CE));
94         }
95       }
96       else {
97         Loops     .AddEdge(E, AsDes->Descendant(E));
98         AddedEdges.Append (E);
99       }
100     }
101     //------------------------
102     // Unwind.
103     //------------------------
104     Loops.Perform();
105     Loops.WiresToFaces();      
106     //------------------------
107     // MAJ SD.
108     //------------------------
109     const TopTools_ListOfShape&  NF = Loops.NewFaces();
110     //-----------------------
111     // F => New faces;
112     //-----------------------
113     Image.Bind(F,NF);
114
115     TopTools_ListIteratorOfListOfShape itAdded;
116     for (itAdded.Initialize(AddedEdges); itAdded.More(); itAdded.Next()) {
117       const TopoDS_Edge& E = TopoDS::Edge(itAdded.Value());
118       //-----------------------
119       //  E => New edges;
120       //-----------------------
121       const TopTools_ListOfShape& LoopNE = Loops.NewEdges(E);
122       if (Image.HasImage(E)) {
123         Image.Add(E,LoopNE);
124       }
125       else {
126         Image.Bind(E,LoopNE);
127       }
128     }
129   }
130   Loops.GetVerticesForSubstitute( myVerVerMap );
131   if (myVerVerMap.IsEmpty())
132     return;
133   BRep_Builder BB;
134   for (it.Initialize( LF ); it.More(); it.Next())
135     {
136       TopoDS_Shape F = it.Value();
137       TopTools_ListOfShape LIF;
138       Image.LastImage( F, LIF );
139       for (itl.Initialize(LIF); itl.More(); itl.Next())
140         {
141           const TopoDS_Shape& IF = itl.Value();
142           TopExp_Explorer EdExp( IF, TopAbs_EDGE );
143           for (; EdExp.More(); EdExp.Next())
144             {
145               TopoDS_Shape E = EdExp.Current();
146               TopTools_ListOfShape VList;
147               TopoDS_Iterator VerExp( E );
148               for (; VerExp.More(); VerExp.Next())
149                 VList.Append( VerExp.Value() );
150               TopTools_ListIteratorOfListOfShape itlv( VList );
151               for (; itlv.More(); itlv.Next())
152                 {
153                   const TopoDS_Shape& V = itlv.Value();
154                   if (myVerVerMap.IsBound( V ))
155                     {
156                       TopoDS_Shape NewV = myVerVerMap( V );
157                       E.Free( Standard_True );
158                       NewV.Orientation( V.Orientation() );
159                       Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
160                       Handle(BRep_TVertex)& NewTV = *((Handle(BRep_TVertex)*) &NewV.TShape());
161                       if (TV->Tolerance() > NewTV->Tolerance())
162                         NewTV->Tolerance( TV->Tolerance() );
163                       NewTV->ChangePoints().Append( TV->ChangePoints() );
164                       AsDes->Replace( V, NewV );
165                       BB.Remove( E, V );
166                       BB.Add( E, NewV );
167                     }
168                 }
169             }
170         }
171     }
172 }
173
174 //=======================================================================
175 //function : IsBetweenCorks
176 //purpose  : 
177 //=======================================================================
178
179 static Standard_Boolean IsBetweenCorks(const TopoDS_Shape& E,
180                                        const Handle(BRepAlgo_AsDes)& AsDes,
181                                        const TopTools_ListOfShape&   LContext) 
182 {
183   if (!AsDes->HasAscendant(E)) return 1;
184   const TopTools_ListOfShape& LF = AsDes->Ascendant(E);
185   TopTools_ListIteratorOfListOfShape it;
186   for (it.Initialize(LF); it.More(); it.Next()) {
187     const TopoDS_Shape& S = it.Value();
188     Standard_Boolean found = 0;
189     TopTools_ListIteratorOfListOfShape it2;
190     for (it2.Initialize(LContext); it2.More(); it2.Next()) {
191       if(S.IsSame(it2.Value())) {
192         found = 1;
193         break;
194       }
195     }
196     if (!found) return 0;
197   }
198   return 1;
199 }
200 //=======================================================================
201 //function : BuildOnContext
202 //purpose  : 
203 //=======================================================================
204
205 void BRepOffset_MakeLoops::BuildOnContext(const TopTools_ListOfShape&   LContext,  
206                                           const BRepOffset_Analyse&     Analyse, 
207                                           const Handle(BRepAlgo_AsDes)& AsDes, 
208                                           BRepAlgo_Image&               Image,
209                                           const Standard_Boolean        InSide)
210 {
211   //-----------------------------------------
212   // unwinding of caps.
213   //-----------------------------------------
214   TopTools_ListIteratorOfListOfShape  it(LContext);
215   TopTools_ListIteratorOfListOfShape  itl,itLCE;
216   BRepAlgo_Loop                     Loops;
217   Loops.VerticesForSubstitute( myVerVerMap );
218   TopExp_Explorer                     exp; 
219   TopTools_MapOfShape                 MapExtent;
220
221   for (; it.More(); it.Next()) {
222     const TopoDS_Face& F = TopoDS::Face(it.Value());
223     TopTools_MapOfShape                 MBound;
224     //-----------------------------------------------
225     // Initialisation of Loops.
226     // F is reversed it will be added in myOffC.
227     // and myOffC will be reversed in the final result.
228     //-----------------------------------------------
229     TopoDS_Shape aLocalShape = F.Reversed();
230     if (InSide) Loops.Init(TopoDS::Face(aLocalShape));
231 //    if (InSide) Loops.Init(TopoDS::Face(F.Reversed()));
232     else        Loops.Init(F);
233     //--------------------------------------------------------
234     // return edges of F not modified by definition.
235     //--------------------------------------------------------
236     for (exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
237          exp.More();
238          exp.Next()) {
239       TopoDS_Edge CE = TopoDS::Edge(exp.Current());
240       MBound.Add(CE);   
241       if (Analyse.HasAncestor(CE)) {
242         // the stop of cups except for the connectivity stops between caps.
243         //      if (!AsDes->HasAscendant(CE)) {
244         aLocalShape = CE.Reversed();
245         if (InSide) Loops.AddConstEdge(CE);
246         else        Loops.AddConstEdge(TopoDS::Edge(aLocalShape));
247 //      else        Loops.AddConstEdge(TopoDS::Edge(CE.Reversed()));
248       }
249     }
250     //------------------------------------------------------
251     // Trace of offsets + connectivity edge between caps.
252     //------------------------------------------------------    
253     const TopTools_ListOfShape& LE = AsDes->Descendant(F);
254     TopTools_ListOfShape        AddedEdges;
255     
256     for (itl.Initialize(LE); itl.More(); itl.Next()) {
257       TopoDS_Edge E = TopoDS::Edge(itl.Value());
258       if (Image.HasImage(E)) {
259         //-------------------------------------------
260         // E was already cut in another face.
261         // Return cut edges and orientate them as E.
262         // See pb for the edges that have disappeared?
263         //-------------------------------------------
264         const TopTools_ListOfShape& LCE = Image.Image(E);
265         for (itLCE.Initialize(LCE); itLCE.More(); itLCE.Next()) {
266           TopoDS_Shape CE = itLCE.Value().Oriented(E.Orientation());      
267           if (MapExtent.Contains(E)) {
268             Loops.AddConstEdge(TopoDS::Edge(CE));
269             continue;
270           }
271           if (!MBound.Contains(E)) CE.Reverse();
272           if (InSide) Loops.AddConstEdge(TopoDS::Edge(CE));
273           else
274             {
275               TopoDS_Shape aLocalShape = CE.Reversed();
276               Loops.AddConstEdge(TopoDS::Edge(aLocalShape));
277             }
278 //        else        Loops.AddConstEdge(TopoDS::Edge(CE.Reversed()));
279         }
280       }
281       else {
282         if (IsBetweenCorks(E,AsDes,LContext) && AsDes->HasDescendant(E)) {
283           //connection between 2 caps
284           MapExtent.Add(E);
285           TopTools_ListOfShape LV;
286           if (InSide) {
287             for (itLCE.Initialize(AsDes->Descendant(E)); itLCE.More(); itLCE.Next()) {
288               LV.Append(itLCE.Value().Reversed());
289             }
290             Loops.AddEdge(E,LV);
291           }
292           else {
293             Loops.AddEdge(E,AsDes->Descendant(E));
294           }
295           AddedEdges.Append (E);
296         }
297         else if (IsBetweenCorks(E,AsDes,LContext)) {
298         TopoDS_Shape aLocalShape = E.Reversed();
299           if (InSide) Loops.AddConstEdge(E);
300           else        Loops.AddConstEdge(TopoDS::Edge(aLocalShape));
301 //        if (InSide) Loops.AddConstEdge(TopoDS::Edge(E));
302 //        else        Loops.AddConstEdge(TopoDS::Edge(E.Reversed()));
303         }
304         else { 
305           TopoDS_Shape aLocalShape = E.Reversed();
306           if (InSide) Loops.AddConstEdge(TopoDS::Edge(aLocalShape));
307           else        Loops.AddConstEdge(E);
308 //        if (InSide) Loops.AddConstEdge(TopoDS::Edge(E.Reversed()));
309 //        else        Loops.AddConstEdge(TopoDS::Edge(E));
310         }
311       }
312     }
313     //------------------------
314     // Unwind.
315     //------------------------
316     Loops.Perform();
317     Loops.WiresToFaces();      
318     //------------------------
319     // MAJ SD.
320     //------------------------
321     const TopTools_ListOfShape&  NF = Loops.NewFaces();
322     //-----------------------
323     // F => New faces;
324     //-----------------------
325     Image.Bind(F,NF);   
326
327     TopTools_ListIteratorOfListOfShape itAdded;
328     for (itAdded.Initialize(AddedEdges); itAdded.More(); itAdded.Next()) {
329       const TopoDS_Edge& E = TopoDS::Edge(itAdded.Value());
330       //-----------------------
331       //  E => New edges;
332       //-----------------------
333       if (Image.HasImage(E)) {
334         Image.Add(E,Loops.NewEdges(E));
335       }
336       else {
337         Image.Bind(E,Loops.NewEdges(E));
338       }
339     }
340   }
341   Loops.GetVerticesForSubstitute( myVerVerMap );
342   if (myVerVerMap.IsEmpty())
343     return;
344   BRep_Builder BB;
345   for (it.Initialize( LContext ); it.More(); it.Next())
346     {
347       TopoDS_Shape F = it.Value();
348       TopTools_ListOfShape LIF;
349       Image.LastImage( F, LIF );
350       for (itl.Initialize(LIF); itl.More(); itl.Next())
351         {
352           const TopoDS_Shape& IF = itl.Value();
353           TopExp_Explorer EdExp( IF, TopAbs_EDGE );
354           for (; EdExp.More(); EdExp.Next())
355             {
356               TopoDS_Shape E = EdExp.Current();
357               TopTools_ListOfShape VList;
358               TopoDS_Iterator VerExp( E );
359               for (; VerExp.More(); VerExp.Next())
360                 VList.Append( VerExp.Value() );
361               TopTools_ListIteratorOfListOfShape itlv( VList );
362               for (; itlv.More(); itlv.Next())
363                 {
364                   const TopoDS_Shape& V = itlv.Value();
365                   if (myVerVerMap.IsBound( V ))
366                     {
367                       TopoDS_Shape NewV = myVerVerMap( V );
368                       E.Free( Standard_True );
369                       NewV.Orientation( V.Orientation() );
370                       Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
371                       Handle(BRep_TVertex)& NewTV = *((Handle(BRep_TVertex)*) &NewV.TShape());
372                       if (TV->Tolerance() > NewTV->Tolerance())
373                         NewTV->Tolerance( TV->Tolerance() );
374                       NewTV->ChangePoints().Append( TV->ChangePoints() );
375                       AsDes->Replace( V, NewV );
376                       BB.Remove( E, V );
377                       BB.Add( E, NewV );
378                     }
379                 }
380             }
381         }
382     }
383 }
384
385
386 //=======================================================================
387 //function : BuildFaces
388 //purpose  : 
389 //=======================================================================
390   
391 void BRepOffset_MakeLoops::BuildFaces(const TopTools_ListOfShape&   LF, 
392                                       const Handle(BRepAlgo_AsDes)& AsDes, 
393                                       BRepAlgo_Image&               Image)
394 {
395   TopTools_ListIteratorOfListOfShape itr,itl,itLCE;
396   Standard_Boolean                   ToRebuild;
397   BRepAlgo_Loop                    Loops;
398   Loops.VerticesForSubstitute( myVerVerMap );
399   BRep_Builder                       B;
400
401   //----------------------------------
402   // Loop on all faces //.
403   //----------------------------------
404   for (itr.Initialize(LF); itr.More(); itr.Next()) {
405     TopoDS_Face F = TopoDS::Face(itr.Value());
406     Loops.Init(F);
407     ToRebuild = Standard_False;
408     TopTools_ListOfShape        AddedEdges;
409     
410     if (!Image.HasImage(F)) {
411       //----------------------------------
412       // Face F not yet reconstructed.
413       //----------------------------------
414       const TopTools_ListOfShape& LE = AsDes->Descendant(F);
415       //----------------------------------------------------------------
416       // first loop to find if the edges of the face were reconstructed.
417       // - maj on map MONV. Some vertices on reconstructed edges
418       // coincide geometrically with old but are not IsSame.
419       //----------------------------------------------------------------
420       TopTools_DataMapOfShapeShape MONV;
421       TopoDS_Vertex OV1,OV2,NV1,NV2;
422       
423       for (itl.Initialize(LE); itl.More(); itl.Next()) {
424         TopoDS_Edge E = TopoDS::Edge(itl.Value());
425         if (Image.HasImage(E)) {
426           const TopTools_ListOfShape& LCE = Image.Image(E);
427           if (LCE.Extent() == 1 && LCE.First().IsSame(E)) {
428             TopoDS_Shape aLocalShape = LCE.First().Oriented(E.Orientation());
429             TopoDS_Edge CE = TopoDS::Edge(aLocalShape);
430 //          TopoDS_Edge CE = TopoDS::Edge(LCE.First().Oriented(E.Orientation()));
431             Loops.AddConstEdge(CE);
432             continue;
433           }
434           //----------------------------------
435           // F should be reconstructed.
436           //----------------------------------
437           ToRebuild = Standard_True;
438           for (itLCE.Initialize(LCE); itLCE.More(); itLCE.Next()) {
439             TopoDS_Shape aLocalShape = itLCE.Value().Oriented(E.Orientation());
440             TopoDS_Edge CE = TopoDS::Edge(aLocalShape); 
441 //          TopoDS_Edge CE = TopoDS::Edge(itLCE.Value().Oriented(E.Orientation())); 
442             TopExp::Vertices (E ,OV1,OV2);
443             TopExp::Vertices (CE,NV1,NV2);
444             if (!OV1.IsSame(NV1)) MONV.Bind(OV1,NV1);
445             if (!OV2.IsSame(NV2)) MONV.Bind(OV2,NV2);
446             Loops.AddConstEdge(CE);
447           }
448         }
449       }
450       if (ToRebuild) {
451 #ifdef DRAW
452 //POP for NT
453         if ( Affich) {
454           char* name = new char[100];
455           sprintf(name,"CF_%d",NbF++);
456           DBRep::Set(name,F);
457         }
458 #endif
459
460         //-----------------------------------------------------------
461         // Non-reconstructed edges on other faces are added.  
462         // If their vertices were reconstructed they are reconstructed.
463         //-----------------------------------------------------------
464         for (itl.Initialize(LE); itl.More(); itl.Next()) {
465           Standard_Real f,l;
466           TopoDS_Edge E = TopoDS::Edge(itl.Value());
467           BRep_Tool::Range(E,f,l);
468           if (!Image.HasImage(E)) {
469             TopExp::Vertices (E,OV1,OV2);
470             TopTools_ListOfShape LV;
471             if (MONV.IsBound(OV1)) {
472               TopoDS_Vertex VV = TopoDS::Vertex(MONV(OV1));
473               VV.Orientation(TopAbs_FORWARD);
474               LV.Append(VV);
475               TopoDS_Shape aLocalShape = VV.Oriented(TopAbs_INTERNAL);
476               B.UpdateVertex(TopoDS::Vertex(aLocalShape),
477                              f,E,BRep_Tool::Tolerance(VV));
478             }
479             if (MONV.IsBound(OV2)) {
480               TopoDS_Vertex VV = TopoDS::Vertex(MONV(OV2));
481               VV.Orientation(TopAbs_REVERSED);
482               LV.Append(VV);
483               TopoDS_Shape aLocalShape = VV.Oriented(TopAbs_INTERNAL);
484               B.UpdateVertex(TopoDS::Vertex(aLocalShape),
485                              l,E,BRep_Tool::Tolerance(VV));
486 //            B.UpdateVertex(TopoDS::Vertex(VV.Oriented(TopAbs_INTERNAL)),
487 //                           l,E,BRep_Tool::Tolerance(VV));
488             }
489             if (LV.IsEmpty()) Loops.AddConstEdge(E);
490             else  {
491               Loops.AddEdge    (E,LV);
492               AddedEdges.Append(E);
493             }
494           }
495         }
496       }  
497     }
498     if (ToRebuild) {
499       //------------------------
500       // Reconstruction.
501       //------------------------
502       Loops.Perform();
503       Loops.WiresToFaces();
504       //------------------------
505       // MAJ SD.
506       //------------------------
507       const TopTools_ListOfShape&  NF = Loops.NewFaces();
508       //-----------------------
509       // F => New faces;
510       //-----------------------
511       Image.Bind(F,NF); 
512
513       TopTools_ListIteratorOfListOfShape itAdded;
514       for (itAdded.Initialize(AddedEdges); itAdded.More(); itAdded.Next()) {
515         const TopoDS_Edge& E = TopoDS::Edge(itAdded.Value());
516         //-----------------------
517         //  E => New edges;
518         //-----------------------
519         if (Image.HasImage(E)) {
520           Image.Add(E,Loops.NewEdges(E));
521         }
522         else {
523           Image.Bind(E,Loops.NewEdges(E));
524         }
525       }
526     }
527   }
528   Loops.GetVerticesForSubstitute( myVerVerMap );
529   if (myVerVerMap.IsEmpty())
530     return;
531   BRep_Builder BB;
532   for (itr.Initialize( LF ); itr.More(); itr.Next())
533     {
534       TopoDS_Shape F = itr.Value();
535       TopTools_ListOfShape LIF;
536       Image.LastImage( F, LIF );
537       for (itl.Initialize(LIF); itl.More(); itl.Next())
538         {
539           const TopoDS_Shape& IF = itl.Value();
540           TopExp_Explorer EdExp( IF, TopAbs_EDGE );
541           for (; EdExp.More(); EdExp.Next())
542             {
543               TopoDS_Shape E = EdExp.Current();
544               TopTools_ListOfShape VList;
545               TopoDS_Iterator VerExp( E );
546               for (; VerExp.More(); VerExp.Next())
547                 VList.Append( VerExp.Value() );
548               TopTools_ListIteratorOfListOfShape itlv( VList );
549               for (; itlv.More(); itlv.Next())
550                 {
551                   const TopoDS_Shape& V = itlv.Value();
552                   if (myVerVerMap.IsBound( V ))
553                     {
554                       TopoDS_Shape NewV = myVerVerMap( V );
555                       E.Free( Standard_True );
556                       NewV.Orientation( V.Orientation() );
557                       Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
558                       Handle(BRep_TVertex)& NewTV = *((Handle(BRep_TVertex)*) &NewV.TShape());
559                       if (TV->Tolerance() > NewTV->Tolerance())
560                         NewTV->Tolerance( TV->Tolerance() );
561                       NewTV->ChangePoints().Append( TV->ChangePoints() );
562                       AsDes->Replace( V, NewV );
563                       BB.Remove( E, V );
564                       BB.Add( E, NewV );
565                     }
566                 }
567             }
568         }
569     }
570 }