0028643: Coding rules - eliminate GCC compiler warnings -Wmisleading-indentation
[occt.git] / src / BRepOffsetAPI / BRepOffsetAPI_MakeOffset.cxx
1 // Created on: 1995-09-18
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1995-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 <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <BRepAlgo_FaceRestrictor.hxx>
22 #include <BRepBuilderAPI_MakeFace.hxx>
23 #include <BRepFill_ListIteratorOfListOfOffsetWire.hxx>
24 #include <BRepFill_OffsetWire.hxx>
25 #include <BRepOffsetAPI_MakeOffset.hxx>
26 #include <BRepTopAdaptor_FClass2d.hxx>
27 #include <Extrema_ExtPS.hxx>
28 #include <gp_Pnt.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <Precision.hxx>
31 #include <StdFail_NotDone.hxx>
32 #include <TopExp.hxx>
33 #include <TopExp_Explorer.hxx>
34 #include <TopoDS.hxx>
35 #include <TopoDS_Compound.hxx>
36 #include <TopoDS_Face.hxx>
37 #include <TopoDS_Shape.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopoDS_Wire.hxx>
40 #include <TopTools_ListIteratorOfListOfShape.hxx>
41
42 #ifdef OCCT_DEBUG
43 #include <BRepTools.hxx>
44 static Standard_Boolean AffichSpine = Standard_False;
45 #endif
46
47 //=======================================================================
48 //function : BRepOffsetAPI_MakeOffset
49 //purpose  : 
50 //=======================================================================
51
52 BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset()
53   : myIsInitialized( Standard_False),
54     myJoin(GeomAbs_Arc),
55     myIsOpenResult(Standard_False)
56 {
57 }
58
59
60 //=======================================================================
61 //function : BRepOffsetAPI_MakeOffset
62 //purpose  : 
63 //=======================================================================
64
65 BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset(const TopoDS_Face& Spine, 
66                                                    const GeomAbs_JoinType Join,
67                                                    const Standard_Boolean IsOpenResult)
68 {
69   Init(Spine, Join, IsOpenResult);
70 }
71
72
73 //=======================================================================
74 //function : Init
75 //purpose  : 
76 //=======================================================================
77
78 void BRepOffsetAPI_MakeOffset::Init(const TopoDS_Face&     Spine,
79                                     const GeomAbs_JoinType Join,
80                                     const Standard_Boolean IsOpenResult)
81 {
82   myFace          = Spine;
83   myIsInitialized = Standard_True;
84   myJoin          = Join;
85   myIsOpenResult  = IsOpenResult;
86   TopExp_Explorer exp;
87   for (exp.Init(myFace,TopAbs_WIRE); exp.More();exp.Next()) {
88     myWires.Append(exp.Current());
89   }
90 }
91
92 //=======================================================================
93 //function : BRepOffsetAPI_MakeOffset
94 //purpose  : 
95 //=======================================================================
96
97 BRepOffsetAPI_MakeOffset::BRepOffsetAPI_MakeOffset(const TopoDS_Wire& Spine, 
98                                                    const GeomAbs_JoinType Join,
99                                                    const Standard_Boolean IsOpenResult)
100 {
101   myWires.Append(Spine);
102   myIsInitialized = Standard_True;
103   myJoin = Join;
104   myIsOpenResult  = IsOpenResult;
105 }
106
107 //=======================================================================
108 //function : Init
109 //purpose  : 
110 //=======================================================================
111
112 void BRepOffsetAPI_MakeOffset::Init(const GeomAbs_JoinType Join,
113                                     const Standard_Boolean IsOpenResult)
114 {
115   myJoin = Join;
116   myIsOpenResult  = IsOpenResult;
117 }
118
119 //=======================================================================
120 //function : BRepOffsetAPI_MakeOffset
121 //purpose  : 
122 //=======================================================================
123
124 void BRepOffsetAPI_MakeOffset::AddWire(const TopoDS_Wire& Spine)
125
126 {
127   myIsInitialized = Standard_True;
128   myWires.Append(Spine);
129 }
130
131 //=======================================================================
132 //function : BuildDomain
133 //purpose  : 
134 //=======================================================================
135
136 static void BuildDomains(TopoDS_Face&               myFace,
137                          TopTools_ListOfShape&      WorkWires,
138                          BRepFill_ListOfOffsetWire& myAlgos,
139                          GeomAbs_JoinType           myJoin,
140                          Standard_Boolean           myIsOpenResult,
141                          Standard_Boolean           isPositive)
142 {
143   BRepAlgo_FaceRestrictor  FR;
144   TopoDS_Vertex            VF,VL;
145   TopTools_ListOfShape     LOW;
146   BRep_Builder             B;
147
148   if (myFace.IsNull()) {
149     myFace   = BRepBuilderAPI_MakeFace(TopoDS::Wire(WorkWires.First()),Standard_True);
150     if (myFace.IsNull())
151       throw StdFail_NotDone("BRepOffsetAPI_MakeOffset : the wire is not planar");
152   }
153 //  Modified by Sergey KHROMOV - Thu Apr 26 16:04:43 2001 Begin
154   TopExp_Explorer anExp(myFace, TopAbs_WIRE);
155   TopoDS_Shape    aWire1 = WorkWires.First();
156   TopoDS_Shape    aWire2;
157   if (anExp.More()) {
158     aWire2 = anExp.Current();
159     if ((aWire1.Orientation() == aWire2.Orientation() && isPositive) ||
160       (aWire1.Orientation() == TopAbs::Complement(aWire2.Orientation()) && !isPositive)) {
161         TopTools_ListOfShape LWires;
162         TopTools_ListIteratorOfListOfShape itl;
163         for (itl.Initialize(WorkWires); itl.More(); itl.Next()) {
164           const TopoDS_Shape& W = itl.Value();
165           LWires.Append(W.Reversed());
166         }
167         WorkWires = LWires;
168     }
169   }
170 //  Modified by Sergey KHROMOV - Thu Apr 26 16:04:44 2001 End
171   FR.Init(myFace,Standard_True);
172   //====================================================
173   // Construction of faces limited by closed wires.
174   //====================================================
175   TopTools_ListIteratorOfListOfShape itl(WorkWires);
176   for (; itl.More(); itl.Next()) {
177     TopoDS_Wire& W = TopoDS::Wire(itl.Value());
178     if (W.Closed()){
179       FR.Add(W);
180       continue;
181     }
182     TopExp::Vertices (W,VF,VL);
183     if (VF.IsSame(VL)) {
184       FR.Add(W);
185     }
186     else {
187       LOW.Append(W);
188     }
189   }
190   FR.Perform();
191   if (!FR.IsDone()) {
192     throw StdFail_NotDone("BRepOffsetAPI_MakeOffset : Build Domains");
193   }
194   TopTools_ListOfShape Faces;
195 #ifdef OCCT_DEBUG
196   Standard_Integer ns = 0;
197 #endif
198   for (; FR.More(); FR.Next()) {
199     Faces.Append(FR.Current());
200 #ifdef OCCT_DEBUG
201     if(AffichSpine)
202     {
203       char name[32];
204       ns++;
205       sprintf(name, "FR%d",ns);
206       BRepTools::Write(FR.Current(), name);
207     }
208 #endif
209   }
210
211   //===========================================
212   // No closed wire => only one domain
213   //===========================================
214   if (Faces.IsEmpty()) {
215     TopoDS_Shape aLocalShape = myFace.EmptyCopied();
216     TopoDS_Face F = TopoDS::Face(aLocalShape);
217 //    TopoDS_Face F = TopoDS::Face(myFace.EmptyCopied());
218     TopTools_ListIteratorOfListOfShape itW(LOW);
219     for ( ; itW.More(); itW.Next()) {
220       B.Add(F,itW.Value());
221     }
222     BRepFill_OffsetWire Algo(F, myJoin, myIsOpenResult);
223     myAlgos.Append(Algo);
224     return;
225   }
226
227   //====================================================
228   // Classification of open wires.
229   //====================================================  
230 //  for (TopTools_ListIteratorOfListOfShape itF(Faces); itF.More(); itF.Next()) {
231   TopTools_ListIteratorOfListOfShape itF;
232   for (itF.Initialize(Faces) ; itF.More(); itF.Next()) {
233     TopoDS_Face&          F = TopoDS::Face(itF.Value());
234     BRepAdaptor_Surface   S(F,0);
235     Standard_Real         Tol = BRep_Tool::Tolerance(F); 
236
237     BRepTopAdaptor_FClass2d CL(F,Precision::Confusion());
238
239     TopTools_ListIteratorOfListOfShape itW(LOW);
240     while (itW.More()) {
241       TopoDS_Wire& W = TopoDS::Wire(itW.Value());
242       //=======================================================
243       // Choice of a point on the wire. + projection on the face.
244       //=======================================================
245       TopExp_Explorer exp(W,TopAbs_VERTEX);
246       TopoDS_Vertex   V  = TopoDS::Vertex(exp.Current());
247       gp_Pnt2d        PV;
248       gp_Pnt          P3d = BRep_Tool::Pnt(V);
249       Extrema_ExtPS ExtPS (P3d,S,Tol,Tol);
250       Standard_Real     Dist2Min = Precision::Infinite();
251       Standard_Real     Found   = Standard_False;
252       for (Standard_Integer ie = 1; ie <= ExtPS.NbExt(); ie++) {
253         Standard_Real X,Y;
254         if (ExtPS.SquareDistance(ie) < Dist2Min) {
255           Dist2Min = ExtPS.SquareDistance(ie);
256           Found   = Standard_True;
257           ExtPS.Point(ie).Parameter(X,Y);
258           PV.SetCoord(X,Y);
259         }
260       }
261       if ( Found && (CL.Perform(PV) == TopAbs_IN)) {
262         // The face that contains a wire is found and it is removed from the list
263         B.Add(F,W);
264         LOW.Remove(itW);
265       }
266       else {
267         itW.Next();
268       }
269     }
270   }
271   //========================================
272   // Creation of algorithms on each domain.
273   //========================================
274   for (itF.Initialize(Faces); itF.More(); itF.Next()) {
275     BRepFill_OffsetWire Algo(TopoDS::Face(itF.Value()), myJoin, myIsOpenResult);
276     myAlgos.Append(Algo);
277   }
278 }
279
280 //=======================================================================
281 //function : Perform
282 //purpose  : 
283 //=======================================================================
284
285 void BRepOffsetAPI_MakeOffset::Perform(const Standard_Real Offset,
286                                        const Standard_Real Alt)
287 {
288   StdFail_NotDone_Raise_if ( !myIsInitialized,
289     "BRepOffsetAPI_MakeOffset : Perform without Init");
290
291   try
292   {
293     Standard_Integer i = 1;
294     BRepFill_ListIteratorOfListOfOffsetWire itOW;
295     TopoDS_Compound Res;
296     BRep_Builder    B;
297     B.MakeCompound (Res);
298     myLastIsLeft = (Offset <= 0);
299
300     if( Offset <= 0. )
301     {
302       if( myLeft.IsEmpty() )
303       {
304         //  Modified by Sergey KHROMOV - Fri Apr 27 14:35:26 2001 Begin
305         BuildDomains(myFace,myWires,myLeft,myJoin,myIsOpenResult, Standard_False);
306         //  Modified by Sergey KHROMOV - Fri Apr 27 14:35:26 2001 End
307       }
308
309       for (itOW.Initialize(myLeft); itOW.More(); itOW.Next())
310       {
311         BRepFill_OffsetWire& Algo = itOW.Value();
312         Algo.Perform(Abs(Offset),Alt);
313         if (Algo.IsDone() && !Algo.Shape().IsNull())
314         {
315           B.Add(Res,Algo.Shape());
316           if (i == 1)
317             myShape = Algo.Shape();
318
319           i++;
320         }
321       }
322     }
323     else
324     {
325       if (myRight.IsEmpty())
326       {
327         //  Modified by Sergey KHROMOV - Fri Apr 27 14:35:28 2001 Begin
328         BuildDomains(myFace,myWires,myRight,myJoin,myIsOpenResult, Standard_True);
329         //  Modified by Sergey KHROMOV - Fri Apr 27 14:35:35 2001 End
330       }
331
332       for(itOW.Initialize(myRight); itOW.More(); itOW.Next())
333       {
334         BRepFill_OffsetWire& Algo = itOW.Value();
335         Algo.Perform(Offset,Alt);
336
337         if (Algo.IsDone() && !Algo.Shape().IsNull())
338         {
339           B.Add(Res,Algo.Shape());
340
341           if (i == 1)
342             myShape = Algo.Shape();
343
344           i++;
345         }
346       }
347     }
348
349     if( i > 2 )
350       myShape = Res;
351
352     if(myShape.IsNull())
353       NotDone();
354     else
355       Done();
356   }
357   catch(Standard_Failure const& anException) {
358 #ifdef OCCT_DEBUG
359     cout<<"An exception was caught in BRepOffsetAPI_MakeOffset::Perform : ";
360     anException.Print(cout); 
361     cout<<endl;
362 #endif
363     (void)anException;
364     NotDone();
365     myShape.Nullify();
366   }
367 }
368
369 //=======================================================================
370 //function : Build
371 //purpose  : 
372 //=======================================================================
373
374 void BRepOffsetAPI_MakeOffset::Build()
375 {
376   Done();
377 }
378
379
380 //=======================================================================
381 //function : ShapesFromShape
382 //purpose  : 
383 //=======================================================================
384
385 const TopTools_ListOfShape& BRepOffsetAPI_MakeOffset::Generated
386   (const TopoDS_Shape& S)
387 {
388   myGenerated.Clear();
389   BRepFill_ListIteratorOfListOfOffsetWire itOW;
390   BRepFill_ListOfOffsetWire* Algos;
391   Algos= &myLeft;
392   if (!myLastIsLeft) {
393     Algos = &myRight;
394   }
395   for (itOW.Initialize(*Algos); itOW.More(); itOW.Next()) {
396     BRepFill_OffsetWire& OW = itOW.Value();
397     TopTools_ListOfShape L;
398     L =  OW.GeneratedShapes(S.Oriented(TopAbs_FORWARD));
399     myGenerated.Append(L);
400     L =  OW.GeneratedShapes(S.Oriented(TopAbs_REVERSED));
401     myGenerated.Append(L);
402   }
403   return myGenerated;
404 }