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