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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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>
30 #include <TopAbs_Orientation.hxx>
31 #include <TopoDS_Shape.hxx>
32 #include <TopTools_SequenceOfShape.hxx>
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):
45 myGenShape(aGenShape),
48 myGenShapeTool(aGenShape),
49 myDirShapeTool(aDirShape),
51 // *****************************************************************
53 // *****************************************************************
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())
62 myBuiltShapes.Init(Standard_False);
63 myUsedShapes.Init(Standard_False);
66 //=======================================================================
67 //function : ~BRepSweep_NumLinearRegularSweep
68 //purpose : Destructor
69 //=======================================================================
71 BRepSweep_NumLinearRegularSweep::~BRepSweep_NumLinearRegularSweep()
75 //=======================================================================
77 //purpose : Returns the global Shape.
78 //=======================================================================
80 TopoDS_Shape BRepSweep_NumLinearRegularSweep::Shape ()
82 if (HasShape(myGenShape,myDirWire)) return Shape(myGenShape,myDirWire);
90 //=======================================================================
92 //purpose : Returns the Shape generated with aGenS.
93 //=======================================================================
95 TopoDS_Shape BRepSweep_NumLinearRegularSweep::Shape (const TopoDS_Shape& aGenS)
97 if (myGenShapeTool.Index(aGenS) != 0 &&
98 HasShape(aGenS,myDirWire)) return Shape(aGenS,myDirWire);
106 //=======================================================================
108 //purpose : Returns the Shape indexed by the arguments.
109 //=======================================================================
111 TopoDS_Shape BRepSweep_NumLinearRegularSweep::Shape (const TopoDS_Shape& aGenS,
112 const Sweep_NumShape& aDirS)
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);
129 myShapes(iGenS,iDirS)=MakeEmptyVertex(aGenS,aDirS);
132 myShapes(iGenS,iDirS)=MakeEmptyGeneratingEdge(aGenS,aDirS);
135 myBuilder.MakeWire(myShapes(iGenS,iDirS));
138 myShapes(iGenS,iDirS)=MakeEmptyFace(aGenS,aDirS);
141 myBuilder.MakeShell(myShapes(iGenS,iDirS));
144 throw Standard_NoSuchObject("Solids are not Processed");
146 case TopAbs_COMPSOLID :
147 throw Standard_NoSuchObject("Solids are not Processed");
149 case TopAbs_COMPOUND :
150 myBuilder.MakeCompound(myShapes(iGenS,iDirS));
153 throw Standard_NoSuchObject("Unknown Shape");
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
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);
181 else if(subGenSType==TopAbs_EDGE){
182 SetPCurve(myShapes(iGenS,iDirS),newShape,
183 aGenS,subGenS,aDirS,Or);
185 else if(subGenSType==TopAbs_WIRE){
186 BRepSweep_Iterator Jt;
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);
200 else if(aGenSType==TopAbs_EDGE){
201 SetGeneratingParameter(myShapes(iGenS,iDirS),
202 newShape,bGenS,subGenS,aDirS);
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;
216 myShapes(iGenS,iDirS)=MakeEmptyDirectingEdge(aGenS,aDirS);
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);
227 myBuilder.MakeShell(myShapes(iGenS,iDirS));
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));
237 myBuilder.MakeCompSolid(myShapes(iGenS,iDirS));
240 throw Standard_NoSuchObject("Solids are not Processed");
242 case TopAbs_COMPSOLID :
243 throw Standard_NoSuchObject("Solids are not Processed");
245 case TopAbs_COMPOUND :
246 myBuilder.MakeCompound(myShapes(iGenS,iDirS));
249 throw Standard_NoSuchObject("Unknown Shape");
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;
269 myBuilder.MakeWire(wi);
270 myBuilder.Add(wi,newShape,Or);
271 myUsedShapes(iNewGenS, iNewDirS) = Standard_True;
272 wi.Closed(BRep_Tool::IsClosed(wi));
276 myBuilder.Add(newWire,newShape,Or);
277 myUsedShapes(iNewGenS, iNewDirS) = Standard_True;
279 SetDirectingPCurve (myShapes(iGenS,iDirS),
280 newShape,bGenS,subGenS,aDirS,Or);
282 else if (aGenSType==TopAbs_WIRE){
283 Or = It.Orientation();
284 myBuilder.Add(myShapes(iGenS,iDirS),newShape,Or);
285 myUsedShapes(iNewGenS, iNewDirS) = Standard_True;
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));
295 else if(subGenSType == TopAbs_EDGE) {
296 myBuilder.Add(newShell,newShape,Or);
297 myUsedShapes(iNewGenS, iNewDirS) = Standard_True;
300 else if(aGenSType == TopAbs_SHELL){
302 myBuilder.Add(myShapes(iGenS,iDirS),newShape,Or);
303 myUsedShapes(iNewGenS, iNewDirS) = Standard_True;
305 else if(aGenSType == TopAbs_COMPOUND){
307 myBuilder.Add(myShapes(iGenS,iDirS),newShape,Or);
308 myUsedShapes(iNewGenS, iNewDirS) = Standard_True;
311 Or = It.Orientation();
312 myBuilder.Add(myShapes(iGenS,iDirS),newShape,Or);
313 myUsedShapes(iNewGenS, iNewDirS) = Standard_True;
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;
332 (myShapes(iGenS,iDirS),newShape,aGenS,aDirS,subDirS,Or);
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);
341 else if(aGenSType==TopAbs_FACE){
342 Or = Kt.Orientation();
343 myBuilder.Add(newShell,newShape,Or);
344 myUsedShapes(iNewGenS, iNewDirS) = Standard_True;
349 if (aGenSType==TopAbs_EDGE){
351 for(Standard_Integer ij = 1;ij <= WireSeq.Length();ij++){
352 myBuilder.Add(myShapes(iGenS,iDirS),WireSeq.Value(ij));
356 newWire.Closed(BRep_Tool::IsClosed(newWire));
357 myBuilder.Add(myShapes(iGenS,iDirS),newWire);
359 myBuiltShapes(iGenS,iDirS) = Standard_True;
360 SetContinuity(aGenS,aDirS);
362 if (aGenSType==TopAbs_WIRE){
363 SetContinuity(aGenS,aDirS);
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);
370 if(Lt.More()) Lt.Next();
372 for (Lt.Init(temp);Lt.More();Lt.Next()){
373 myBuilder.Add(myShapes(iGenS,iDirS),Lt.Value(), ShellOri);
376 else myBuilder.Add(myShapes(iGenS,iDirS),newShell, ShellOri);
379 else if (myDirShapeTool.Type(aDirS)==TopAbs_WIRE){
380 TopAbs_ShapeEnum aGenSType = myGenShapeTool.Type(aGenS);
383 myBuilder.MakeWire(myShapes(iGenS,iDirS));
386 myBuilder.MakeShell(myShapes(iGenS,iDirS));
389 myBuilder.MakeShell(myShapes(iGenS,iDirS));
392 myBuilder.MakeCompSolid(myShapes(iGenS,iDirS));
395 myBuilder.MakeCompSolid(myShapes(iGenS,iDirS));
398 throw Standard_NoSuchObject("Solids are not Processed");
400 case TopAbs_COMPSOLID :
401 throw Standard_NoSuchObject("Solids are not Processed");
403 case TopAbs_COMPOUND :
404 myBuilder.MakeCompound(myShapes(iGenS,iDirS));
407 throw Standard_NoSuchObject("Unknown Shape");
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;
423 myBuiltShapes(iGenS,iDirS) = Standard_True;
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);
433 //=======================================================================
434 //function : FirstShape
435 //purpose : Returns the Shape indexed by the arguments.
436 //=======================================================================
438 TopoDS_Shape BRepSweep_NumLinearRegularSweep::FirstShape ()
441 if (myDirShapeTool.HasFirstVertex()){
442 if(HasShape(myGenShape,myDirShapeTool.FirstVertex()))
443 result = Shape(myGenShape,myDirShapeTool.FirstVertex());
449 //=======================================================================
450 //function : LastShape
451 //purpose : Returns the Shape indexed by the arguments.
452 //=======================================================================
454 TopoDS_Shape BRepSweep_NumLinearRegularSweep::LastShape ()
457 if (myDirShapeTool.HasLastVertex()){
458 if(HasShape(myGenShape,myDirShapeTool.LastVertex()))
459 result = Shape(myGenShape,myDirShapeTool.LastVertex());
465 //=======================================================================
466 //function : FirstShape
467 //purpose : Returns the Shape indexed by the arguments.
468 //=======================================================================
470 TopoDS_Shape BRepSweep_NumLinearRegularSweep::FirstShape (const TopoDS_Shape& aGenS)
473 if (myDirShapeTool.HasFirstVertex()){
474 if(HasShape(aGenS,myDirShapeTool.FirstVertex()))
475 result = Shape(aGenS,myDirShapeTool.FirstVertex());
481 //=======================================================================
482 //function : LastShape
483 //purpose : Returns the Shape indexed by the arguments.
484 //=======================================================================
486 TopoDS_Shape BRepSweep_NumLinearRegularSweep::LastShape (const TopoDS_Shape& aGenS)
489 if (myDirShapeTool.HasLastVertex()){
490 if(HasShape(aGenS,myDirShapeTool.LastVertex()))
491 result = Shape(aGenS,myDirShapeTool.LastVertex());
496 //=======================================================================
499 //=======================================================================
501 Standard_Boolean BRepSweep_NumLinearRegularSweep::Closed()const
503 return myDirWire.Closed();
506 //=======================================================================
507 //function : SplitShell
509 //=======================================================================
511 TopoDS_Shape BRepSweep_NumLinearRegularSweep::SplitShell(const TopoDS_Shape& aNewShape)const
514 myBuilder.MakeCompound(comp);
515 myBuilder.Add(comp,aNewShape);
519 //=======================================================================
522 //=======================================================================
523 Standard_Boolean BRepSweep_NumLinearRegularSweep::IsUsed(const TopoDS_Shape& aGenS) const
525 Standard_Integer iGenS = myGenShapeTool.Index(aGenS);
528 return Standard_False;
531 Standard_Boolean isBuilt = Standard_False;
532 Standard_Boolean isUsed = Standard_False;
533 for (j = 2; j <= myBuiltShapes.UpperCol(); ++j)
535 isBuilt = isBuilt || myBuiltShapes(iGenS, j);
536 isUsed = isUsed || myUsedShapes(iGenS, j);
540 if (aGenS.ShapeType() == TopAbs_VERTEX && IsInvariant(aGenS))
542 if (myUsedShapes(iGenS, 1) || !Closed())
548 return Standard_False;
557 if (isBuilt) //&& !IsUsed
559 if (!HasShape(aGenS, myDirWire) && !Closed())
561 return Standard_True;
563 else if (aGenS.ShapeType() == TopAbs_VERTEX && !Closed())
565 if (!myBuiltShapes(iGenS, 1))
567 return Standard_True;
574 //=======================================================================
575 //function : GenIsUsed
577 //=======================================================================
578 Standard_Boolean BRepSweep_NumLinearRegularSweep::GenIsUsed(const TopoDS_Shape& aGenS) const
580 Standard_Integer iGenS = myGenShapeTool.Index(aGenS);
583 return Standard_False;
587 return myBuiltShapes(iGenS, 1);
591 return myBuiltShapes(iGenS, 1) && myUsedShapes(iGenS, 1);