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