0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / BRepSweep / BRepSweep_NumLinearRegularSweep.cxx
1 // Created on: 1992-07-02
2 // Created by: Philippe DAUTRY
3 // Copyright (c) 1992-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
18 #include <BRepSweep_Builder.hxx>
19 #include <BRepSweep_Iterator.hxx>
20 #include <BRepSweep_NumLinearRegularSweep.hxx>
21 #include <BRepSweep_Tool.hxx>
22 #include <Standard_DomainError.hxx>
23 #include <Standard_NoMoreObject.hxx>
24 #include <Standard_NoSuchObject.hxx>
25 #include <Standard_RangeError.hxx>
26 #include <Sweep_NumShape.hxx>
27 #include <Sweep_NumShapeIterator.hxx>
28 #include <Sweep_NumShapeTool.hxx>
29 #include <TopAbs.hxx>
30 #include <TopAbs_Orientation.hxx>
31 #include <TopoDS_Shape.hxx>
32 #include <TopTools_SequenceOfShape.hxx>
33
34 //=======================================================================
35 //function : BRepSweep_NumLinearRegularSweep
36 //purpose  : Create a Regular Sweep.
37 //=======================================================================
38 BRepSweep_NumLinearRegularSweep::BRepSweep_NumLinearRegularSweep
39   (const BRepSweep_Builder& aBuilder,
40   const TopoDS_Shape& aGenShape,
41   const Sweep_NumShape& aDirShape):
42
43 myBuilder(aBuilder),
44   myGenShape(aGenShape),
45   myDirWire(aDirShape),
46
47   myGenShapeTool(aGenShape),
48   myDirShapeTool(aDirShape),
49
50   // *****************************************************************
51   // Les Tableaux
52   // *****************************************************************
53
54   myShapes(1,myGenShapeTool.NbShapes(),
55   1,myDirShapeTool.NbShapes()),
56   myBuiltShapes(1,myGenShapeTool.NbShapes(),
57   1,myDirShapeTool.NbShapes())
58 {
59   myBuiltShapes.Init(Standard_False); 
60 }
61
62 //=======================================================================
63 //function : ~BRepSweep_NumLinearRegularSweep
64 //purpose  : Destructor
65 //=======================================================================
66
67 BRepSweep_NumLinearRegularSweep::~BRepSweep_NumLinearRegularSweep()
68 {
69 }
70
71 //=======================================================================
72 //function : Shape
73 //purpose  : Returns the global Shape.
74 //=======================================================================
75
76 TopoDS_Shape BRepSweep_NumLinearRegularSweep::Shape () 
77 {
78   if (HasShape(myGenShape,myDirWire)) return Shape(myGenShape,myDirWire);
79   else {
80     TopoDS_Shape bidon;
81     return bidon;
82   }
83 }
84
85
86 //=======================================================================
87 //function : Shape
88 //purpose  : Returns the Shape generated with aGenS.
89 //=======================================================================
90
91 TopoDS_Shape BRepSweep_NumLinearRegularSweep::Shape (const TopoDS_Shape& aGenS) 
92 {
93   if (myGenShapeTool.Index(aGenS) != 0 &&
94     HasShape(aGenS,myDirWire)) return Shape(aGenS,myDirWire);
95   else {
96     TopoDS_Shape bidon;
97     return bidon;
98   }
99 }
100
101
102 //=======================================================================
103 //function : Shape
104 //purpose  : Returns the Shape indexed by the arguments.
105 //=======================================================================
106
107 TopoDS_Shape BRepSweep_NumLinearRegularSweep::Shape (const TopoDS_Shape& aGenS, 
108   const Sweep_NumShape& aDirS)
109 {
110   Standard_Integer iGenS = myGenShapeTool.Index(aGenS);
111   Standard_Integer iDirS = myDirShapeTool.Index(aDirS);
112   if (!myBuiltShapes(iGenS,iDirS)){
113     TopoDS_Shape newShape;
114     TopoDS_Shape bGenS,cGenS,subGenS,subsubGenS;
115     Sweep_NumShape bDirS,subDirS;
116     BRepSweep_Iterator It;
117     Sweep_NumShapeIterator Kt;
118     BRepSweep_Iterator Lt;
119     TopAbs_Orientation Or,Pr;
120     if (myDirShapeTool.Type(aDirS)==TopAbs_VERTEX){
121       //Ici on construit les "planchers" du Shape.
122       TopAbs_ShapeEnum aGenSType = myGenShapeTool.Type(aGenS);
123       switch (aGenSType){
124       case TopAbs_VERTEX : 
125         myShapes(iGenS,iDirS)=MakeEmptyVertex(aGenS,aDirS);
126         break;
127       case TopAbs_EDGE :
128         myShapes(iGenS,iDirS)=MakeEmptyGeneratingEdge(aGenS,aDirS);
129         break;
130       case TopAbs_WIRE :
131         myBuilder.MakeWire(myShapes(iGenS,iDirS));
132         break;
133       case TopAbs_FACE :
134         myShapes(iGenS,iDirS)=MakeEmptyFace(aGenS,aDirS);
135         break;
136       case TopAbs_SHELL :
137         myBuilder.MakeShell(myShapes(iGenS,iDirS));
138         break;
139       case TopAbs_SOLID :
140         throw Standard_NoSuchObject("Solids are not Processed");
141         break;
142       case TopAbs_COMPSOLID :
143         throw Standard_NoSuchObject("Solids are not Processed");
144         break;
145       case TopAbs_COMPOUND :
146         myBuilder.MakeCompound(myShapes(iGenS,iDirS));
147         break;
148       default:
149         throw Standard_NoSuchObject("Unknown Shape");
150         break;
151       }
152       bGenS = aGenS;
153       myGenShapeTool.SetOrientation(bGenS,TopAbs_FORWARD);
154       for (It.Init(bGenS);It.More();It.Next()){
155         subGenS = It.Value();
156         Or = It.Orientation();
157         if(HasShape(subGenS,aDirS)){
158           newShape = Shape(subGenS,aDirS);
159           if (GGDShapeIsToAdd(myShapes(iGenS,iDirS),newShape,
160             aGenS,subGenS,aDirS)){
161               //Les "planchers" doivent etre construits par les 
162               //fonctions de construcion geometrique identiquement 
163               //au shape generateur.
164               //On leur recolle juste une orientation pour etre bien 
165               //sur.
166
167               myBuilder.Add(myShapes(iGenS,iDirS),newShape,Or);
168               TopAbs_ShapeEnum subGenSType = myGenShapeTool.Type(subGenS);
169               if (aGenSType==TopAbs_FACE){   
170                 if(subGenSType==TopAbs_VERTEX){
171                   SetParameters(myShapes(iGenS,iDirS),
172                     newShape,aGenS,subGenS,aDirS);
173                 }
174                 else if(subGenSType==TopAbs_EDGE){
175                   SetPCurve(myShapes(iGenS,iDirS),newShape,
176                     aGenS,subGenS,aDirS,Or);
177                 }           
178                 else if(subGenSType==TopAbs_WIRE){
179                   BRepSweep_Iterator Jt;
180                   cGenS = subGenS;
181                   myGenShapeTool.SetOrientation(cGenS,TopAbs_FORWARD);
182                   for (Jt.Init(cGenS);Jt.More();Jt.Next()){
183                     subsubGenS = Jt.Value();
184                     Pr = Jt.Orientation();
185                     if(HasShape(subsubGenS,aDirS)){
186                       TopoDS_Shape newsubEdge = Shape(subsubGenS,aDirS);
187                       SetPCurve(myShapes(iGenS,iDirS),newsubEdge,
188                         aGenS,subsubGenS,aDirS,Pr);
189                     }
190                   }
191                 }
192               }
193               else if(aGenSType==TopAbs_EDGE){
194                 SetGeneratingParameter(myShapes(iGenS,iDirS),
195                   newShape,bGenS,subGenS,aDirS);
196               }
197           }
198         }
199       }
200     }
201     else if (myDirShapeTool.Type(aDirS)==TopAbs_EDGE){
202       //Ici on construit les murs du Shape.
203       TopAbs_ShapeEnum aGenSType = myGenShapeTool.Type(aGenS);
204       TopoDS_Shape newWire,newShell;
205       TopTools_SequenceOfShape WireSeq;
206       Standard_Boolean sepwires = Standard_False;
207       switch (aGenSType){
208       case TopAbs_VERTEX : 
209         myShapes(iGenS,iDirS)=MakeEmptyDirectingEdge(aGenS,aDirS);
210         break;
211       case TopAbs_EDGE :
212         //On cree un wire intermediaire qui contient tous les edges
213         //du montant (face) du Shape pour le cas standard, et une 
214         //sequence de wires pour les cas merdiques necessitant des
215         //wires independants.
216         myBuilder.MakeWire(newWire);
217         myShapes(iGenS,iDirS)=MakeEmptyFace(aGenS,aDirS);
218         break;
219       case TopAbs_WIRE :
220         myBuilder.MakeShell(myShapes(iGenS,iDirS));
221         break;
222       case TopAbs_FACE :
223         //On cree un shell intermediaire dans lequel on jette toutes 
224         //les faces en direct, pour eviter les empilages compliques 
225         //de shells et sous shells dans la structure du solide.
226         myBuilder.MakeShell(newShell);
227         myBuilder.MakeSolid(myShapes(iGenS,iDirS));
228         break;
229       case TopAbs_SHELL :
230         myBuilder.MakeCompSolid(myShapes(iGenS,iDirS));
231         break;
232       case TopAbs_SOLID :
233         throw Standard_NoSuchObject("Solids are not Processed");
234         break;
235       case TopAbs_COMPSOLID :
236         throw Standard_NoSuchObject("Solids are not Processed");
237         break;
238       case TopAbs_COMPOUND :
239         myBuilder.MakeCompound(myShapes(iGenS,iDirS));
240         break;
241       default:
242         throw Standard_NoSuchObject("Unknown Shape");
243         break;
244       }
245       bGenS = aGenS;
246       myGenShapeTool.SetOrientation(bGenS,TopAbs_FORWARD);
247       for (It.Init(bGenS);It.More();It.Next()){
248         subGenS = It.Value();
249         if(HasShape(subGenS,aDirS)){
250           newShape = Shape(subGenS,aDirS);
251           if (GGDShapeIsToAdd(myShapes(iGenS,iDirS),newShape,
252             aGenS,subGenS,aDirS)){
253               TopAbs_ShapeEnum subGenSType = myGenShapeTool.Type(subGenS);
254               if (aGenSType==TopAbs_EDGE){   
255                 Or = It.Orientation();
256                 if (SeparatedWires(myShapes(iGenS,iDirS),newShape,
257                   aGenS,subGenS,aDirS)){
258                     sepwires = Standard_True;
259                     TopoDS_Shape wi;
260                     myBuilder.MakeWire(wi);
261                     myBuilder.Add(wi,newShape,Or);
262                     wi.Closed(BRep_Tool::IsClosed(wi));
263                     WireSeq.Append(wi);
264                 }
265                 else{
266                   myBuilder.Add(newWire,newShape,Or);
267                 }
268                 SetDirectingPCurve (myShapes(iGenS,iDirS),
269                   newShape,bGenS,subGenS,aDirS,Or);
270               }
271               else if (aGenSType==TopAbs_WIRE){
272                 Or = It.Orientation();
273                 myBuilder.Add(myShapes(iGenS,iDirS),newShape,Or);
274               }
275               else if (aGenSType==TopAbs_FACE){
276                 Or = It.Orientation();
277                 if(subGenSType == TopAbs_WIRE) {
278                   for (Lt.Init(newShape);Lt.More();Lt.Next()){
279                     myBuilder.Add(newShell,Lt.Value(),
280                       TopAbs::Compose(Lt.Orientation(),Or));
281                   }
282                 }
283                 else if(subGenSType == TopAbs_EDGE) {
284                   myBuilder.Add(newShell,newShape,Or);
285                 }
286               }
287               else if(aGenSType == TopAbs_SHELL){
288                 Or = TopAbs_FORWARD;
289                 myBuilder.Add(myShapes(iGenS,iDirS),newShape,Or);
290               }
291               else if(aGenSType == TopAbs_COMPOUND){
292                 Or = TopAbs_FORWARD;
293                 myBuilder.Add(myShapes(iGenS,iDirS),newShape,Or);
294               }
295               else{
296                 Or = It.Orientation();
297                 myBuilder.Add(myShapes(iGenS,iDirS),newShape,Or);
298               }
299           }
300         }
301       }
302       bDirS = aDirS;
303       for (Kt.Init(bDirS);Kt.More();Kt.Next()){
304         subDirS = Kt.Value();
305         if(HasShape(aGenS,subDirS)){
306           newShape = Shape(aGenS,subDirS);
307           if (GDDShapeIsToAdd(myShapes(iGenS,iDirS),newShape,
308             aGenS,aDirS,subDirS)){
309               if (aGenSType==TopAbs_EDGE){   
310                 Or = TopAbs::Reverse(Kt.Orientation());
311                 myBuilder.Add(newWire,newShape,Or);
312                 SetGeneratingPCurve
313                   (myShapes(iGenS,iDirS),newShape,aGenS,aDirS,subDirS,Or);
314               }
315               else if(aGenSType==TopAbs_VERTEX){
316                 Or = Kt.Orientation();
317                 myBuilder.Add(myShapes(iGenS,iDirS),newShape,Or);
318                 SetDirectingParameter
319                   (myShapes(iGenS,iDirS),newShape,aGenS,aDirS,subDirS);
320               }
321               else if(aGenSType==TopAbs_FACE){
322                 Or = Kt.Orientation();
323                 myBuilder.Add(newShell,newShape,Or);
324               }
325           }
326         }
327       }
328       if (aGenSType==TopAbs_EDGE){
329         if (sepwires){
330           for(Standard_Integer ij = 1;ij <= WireSeq.Length();ij++){
331             myBuilder.Add(myShapes(iGenS,iDirS),WireSeq.Value(ij));
332           }
333         }
334         else{
335           newWire.Closed(BRep_Tool::IsClosed(newWire));
336           myBuilder.Add(myShapes(iGenS,iDirS),newWire);
337         }
338         myBuiltShapes(iGenS,iDirS) = Standard_True;
339         SetContinuity(aGenS,aDirS);
340       }
341       if (aGenSType==TopAbs_WIRE){
342         SetContinuity(aGenS,aDirS);
343       } 
344       if (aGenSType==TopAbs_FACE){
345         newShell.Closed (BRep_Tool::IsClosed (newShell));
346         TopoDS_Shape temp = SplitShell(newShell);
347         TopAbs_Orientation ShellOri = DirectSolid(aGenS,aDirS);
348         Lt.Init(temp);
349         if(Lt.More()) Lt.Next();
350         if(Lt.More()){
351           for (Lt.Init(temp);Lt.More();Lt.Next()){
352             myBuilder.Add(myShapes(iGenS,iDirS),Lt.Value(), ShellOri);
353           }
354         }
355         else myBuilder.Add(myShapes(iGenS,iDirS),newShell, ShellOri);
356       }
357     }
358     else if (myDirShapeTool.Type(aDirS)==TopAbs_WIRE){
359       TopAbs_ShapeEnum aGenSType = myGenShapeTool.Type(aGenS);
360       switch (aGenSType){
361       case TopAbs_VERTEX : 
362         myBuilder.MakeWire(myShapes(iGenS,iDirS));
363         break;
364       case TopAbs_EDGE :
365         myBuilder.MakeShell(myShapes(iGenS,iDirS));
366         break;
367       case TopAbs_WIRE :
368         myBuilder.MakeShell(myShapes(iGenS,iDirS));
369         break;
370       case TopAbs_FACE :
371         myBuilder.MakeCompSolid(myShapes(iGenS,iDirS));
372         break;
373       case TopAbs_SHELL :
374         myBuilder.MakeCompSolid(myShapes(iGenS,iDirS));
375         break;
376       case TopAbs_SOLID :
377         throw Standard_NoSuchObject("Solids are not Processed");
378         break;
379       case TopAbs_COMPSOLID :
380         throw Standard_NoSuchObject("Solids are not Processed");
381         break;
382       case TopAbs_COMPOUND :
383         myBuilder.MakeCompound(myShapes(iGenS,iDirS));
384         break;
385       default:
386         throw Standard_NoSuchObject("Unknown Shape");
387         break;
388       }
389       bDirS = aDirS;
390       for (Kt.Init(aDirS);Kt.More();Kt.Next()){
391         subDirS = Kt.Value();
392         if(HasShape(aGenS,subDirS)){
393           Or = Kt.Orientation();
394           newShape = Shape(aGenS,subDirS);
395           myBuilder.Add(myShapes(iGenS,iDirS),newShape,Or);
396         }
397       }
398     }
399     myBuiltShapes(iGenS,iDirS) = Standard_True;
400   }
401   // Change the "Closed" flag only for Wires and Shells
402   if (myShapes(iGenS, iDirS).ShapeType() == TopAbs_WIRE ||
403     myShapes(iGenS, iDirS).ShapeType() == TopAbs_SHELL)
404     myShapes(iGenS,iDirS).Closed (BRep_Tool::IsClosed (myShapes(iGenS,iDirS)));
405   return myShapes(iGenS,iDirS);
406 }
407
408
409 //=======================================================================
410 //function : FirstShape
411 //purpose  : Returns the Shape indexed by the arguments.
412 //=======================================================================
413
414 TopoDS_Shape BRepSweep_NumLinearRegularSweep::FirstShape ()
415 {
416   TopoDS_Shape result;
417   if (myDirShapeTool.HasFirstVertex()){
418     if(HasShape(myGenShape,myDirShapeTool.FirstVertex()))
419       result = Shape(myGenShape,myDirShapeTool.FirstVertex());
420   }
421   return result;
422 }
423
424
425 //=======================================================================
426 //function : LastShape
427 //purpose  : Returns the Shape indexed by the arguments.
428 //=======================================================================
429
430 TopoDS_Shape BRepSweep_NumLinearRegularSweep::LastShape ()
431 {
432   TopoDS_Shape result;
433   if (myDirShapeTool.HasLastVertex()){
434     if(HasShape(myGenShape,myDirShapeTool.LastVertex()))
435       result = Shape(myGenShape,myDirShapeTool.LastVertex());
436   }
437   return result;
438 }
439
440
441 //=======================================================================
442 //function : FirstShape
443 //purpose  : Returns the Shape indexed by the arguments.
444 //=======================================================================
445
446 TopoDS_Shape BRepSweep_NumLinearRegularSweep::FirstShape (const TopoDS_Shape& aGenS)
447 {
448   TopoDS_Shape result;
449   if (myDirShapeTool.HasFirstVertex()){
450     if(HasShape(aGenS,myDirShapeTool.FirstVertex()))
451       result = Shape(aGenS,myDirShapeTool.FirstVertex());
452   }
453   return result;
454 }
455
456
457 //=======================================================================
458 //function : LastShape
459 //purpose  : Returns the Shape indexed by the arguments.
460 //=======================================================================
461
462 TopoDS_Shape BRepSweep_NumLinearRegularSweep::LastShape (const TopoDS_Shape& aGenS)
463 {
464   TopoDS_Shape result;
465   if (myDirShapeTool.HasLastVertex()){
466     if(HasShape(aGenS,myDirShapeTool.LastVertex()))
467       result = Shape(aGenS,myDirShapeTool.LastVertex());
468   }
469   return result;
470 }
471
472 //=======================================================================
473 //function : Closed
474 //purpose  : 
475 //=======================================================================
476
477 Standard_Boolean BRepSweep_NumLinearRegularSweep::Closed()const 
478 {
479   return myDirWire.Closed();
480 }
481
482 //=======================================================================
483 //function : SplitShell
484 //purpose  : 
485 //=======================================================================
486
487 TopoDS_Shape BRepSweep_NumLinearRegularSweep::SplitShell(const TopoDS_Shape& aNewShape)const 
488 {
489   TopoDS_Shape comp;
490   myBuilder.MakeCompound(comp);
491   myBuilder.Add(comp,aNewShape);
492   return comp;
493 }
494