0024058: Eliminate compiler warning C4702 in MSVC++ with warning level 4
[occt.git] / src / BRepAlgo / BRepAlgo_FaceRestrictor.cxx
1 // Created on: 1995-09-01
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #include <BRepAlgo_FaceRestrictor.ixx>
23
24 #include <BRepTopAdaptor_FClass2d.hxx>
25 #include <TopoDS.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopoDS_Edge.hxx>
28 #include <TopExp_Explorer.hxx>
29 #include <TopExp.hxx>
30 #include <TopOpeBRepBuild_WireToFace.hxx>
31 #include <TopTools_ListIteratorOfListOfShape.hxx>
32 #include <Geom_Surface.hxx>
33 #include <Geom2d_Curve.hxx>
34 #include <Geom_Curve.hxx>
35 #include <Geom_TrimmedCurve.hxx>
36 #include <BRep_Builder.hxx>
37 #include <BRep_Tool.hxx>
38 #include <GeomProjLib.hxx>
39 #include <gp_Pnt2d.hxx>
40
41 #include <Precision.hxx>
42
43 //=======================================================================
44 //function : BRepAlgo_FaceRestrictor
45 //purpose  : 
46 //=======================================================================
47
48 BRepAlgo_FaceRestrictor::BRepAlgo_FaceRestrictor()
49 {}
50
51 //=======================================================================
52 //function : 
53 //purpose  : 
54 //=======================================================================
55
56 void BRepAlgo_FaceRestrictor::Init(const TopoDS_Face&     F,
57                                    const Standard_Boolean Proj,
58                                    const Standard_Boolean CorrectionOrientation)
59 {
60   myFace = F; modeProj = Proj;  myCorrection = CorrectionOrientation;
61 }
62
63
64 //=======================================================================
65 //function : Add
66 //purpose  : 
67 //=======================================================================
68
69 void BRepAlgo_FaceRestrictor::Add(TopoDS_Wire& W)
70 {
71   wires.Append(W);
72 }
73
74
75 //=======================================================================
76 //function : Clear
77 //purpose  : 
78 //=======================================================================
79
80 void BRepAlgo_FaceRestrictor::Clear()
81 {
82   wires.Clear();
83   faces.Clear();
84 }
85
86 //=======================================================================
87 //function : ChangePcurve
88 //purpose  : 
89 //=======================================================================
90
91 static Standard_Boolean  ChangePCurve (TopoDS_Edge&          E,
92                                        const Handle(Geom_Surface)& S,
93                                        TopLoc_Location&      L)
94 {
95   BRep_Builder         BB;
96   Handle(Geom_Surface) SE;
97   Handle(Geom2d_Curve) C2;
98   TopLoc_Location      LE;
99   Standard_Real        f,l;
100
101   BRep_Tool::CurveOnSurface (E,C2,SE,LE,f,l,1);
102   if (!C2.IsNull()) 
103     BB.UpdateEdge(E,C2,S,L,Precision::Confusion());
104   return (C2.IsNull());
105 }
106
107 //=======================================================================
108 //function : ProjCurve3d
109 //purpose  : 
110 //=======================================================================
111
112 static void ProjCurve3d (TopoDS_Edge&          E,
113                          const Handle(Geom_Surface)& S,
114                          TopLoc_Location&      L)
115 {
116   BRep_Builder              BB;
117   TopLoc_Location           LE;
118   Standard_Real             f,l;
119   Handle(Geom_Curve)        C  = BRep_Tool::Curve(E,LE,f,l);
120   Handle(Geom_TrimmedCurve) CT = new Geom_TrimmedCurve(C,f,l);
121   
122   TopLoc_Location LL = L.Inverted().Multiplied(LE);
123   CT->Transform(LL.Transformation());
124   
125   Handle(Geom2d_Curve) C2 = GeomProjLib::Curve2d (CT,S);
126   BB.UpdateEdge(E,C2,S,L,Precision::Confusion());
127 }
128
129 //=======================================================================
130 //function : Perform
131 //purpose  : 
132 //=======================================================================
133
134 void BRepAlgo_FaceRestrictor::Perform()
135 {
136
137   if (myCorrection) {
138     PerformWithCorrection();
139     return;
140   }
141
142   myDone = Standard_False;
143   TopTools_ListIteratorOfListOfShape it(wires);
144
145   //--------------------------------------------------------------------
146   // return geometry of the reference face.
147   //--------------------------------------------------------------------
148   TopLoc_Location L;
149   const Handle(Geom_Surface)& S = BRep_Tool::Surface(myFace,L);
150
151   //-----------------------------------------------------------------------
152   // test if edges are on S. otherwise  add S to the first pcurve.
153   // or projection of the edge on F.
154   //---------------------------------------------------------------------- 
155   TopExp_Explorer Exp;
156 //  BRep_Builder    BB;
157   Standard_Real   f,l;
158
159   TopOpeBRepBuild_WireToFace WTF;
160
161   for ( ; it.More(); it.Next()) {
162     // update the surface on edges.
163     const TopoDS_Wire& W = TopoDS::Wire(it.Value());
164
165     for (Exp.Init(W,TopAbs_EDGE); Exp.More(); Exp.Next()) {
166
167       TopoDS_Edge E = TopoDS::Edge(Exp.Current());
168       Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,S,L,f,l);
169       
170       if (C2.IsNull()) {
171         // no pcurve on the reference surface.
172         if (modeProj) {
173           // Projection of the 3D curve on surface.
174           ProjCurve3d ( E, S, L);
175         }
176         else {
177           // return the first pcurve glued on <S>
178           Standard_Boolean YaPCurve = ChangePCurve (E, S, L);
179           if (!YaPCurve) {
180             ProjCurve3d (E, S, L);
181           }
182         }
183       }
184     }
185     WTF.AddWire(W);
186   }
187
188   WTF.MakeFaces(myFace,faces);
189
190   myDone = Standard_True;
191 }
192
193
194 //=======================================================================
195 //function : IsDone
196 //purpose  : 
197 //=======================================================================
198
199 Standard_Boolean BRepAlgo_FaceRestrictor::IsDone() const 
200 {
201   return myDone;
202 }
203
204
205 //=======================================================================
206 //function : More
207 //purpose  : 
208 //=======================================================================
209
210 Standard_Boolean BRepAlgo_FaceRestrictor::More() const 
211 {
212   return (!faces.IsEmpty());
213 }
214
215
216 //=======================================================================
217 //function : Next
218 //purpose  : 
219 //=======================================================================
220
221 void BRepAlgo_FaceRestrictor::Next()
222 {
223   faces.RemoveFirst();
224 }
225
226
227 //=======================================================================
228 //function : Current
229 //purpose  : 
230 //=======================================================================
231
232 TopoDS_Face BRepAlgo_FaceRestrictor::Current() const 
233 {
234   return (TopoDS::Face(faces.First()));
235 }
236
237 //=======================================================================
238 //function : Standard_Boolean
239 //purpose  : 
240 //=======================================================================
241
242 static Standard_Boolean IsClosed (const TopoDS_Wire& W)
243      
244 {
245   if (W.Closed()) return 1;
246   TopoDS_Vertex V1,V2;
247   TopExp::Vertices (W, V1,V2);
248   return (V1.IsSame(V2));
249 }
250
251
252 //=======================================================================
253 //function : IsInside
254 //purpose  : 
255 //=======================================================================
256
257 static Standard_Boolean IsInside(const TopoDS_Wire&       wir,
258                                  const TopoDS_Face&       F,
259                                  BRepTopAdaptor_FClass2d& /*FClass2d*/)
260 {
261   TopExp_Explorer exp;
262   for (exp.Init(wir,TopAbs_EDGE);
263        exp.More();
264        exp.Next()) {
265     const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
266     Standard_Real f,l;
267     Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
268     Standard_Real prm;
269
270     if (!Precision::IsNegativeInfinite(f) && !Precision::IsPositiveInfinite(l)) {
271       prm = (f+l)/2.;
272     }
273     else {
274       if (Precision::IsNegativeInfinite(f) && Precision::IsPositiveInfinite(l)){
275         prm = 0.;
276       }
277       else if (Precision::IsNegativeInfinite(f)) {
278         prm = l-1.;
279       }
280       else {
281         prm = f+1.;
282       }
283     }
284
285     gp_Pnt2d pt2d(C2d->Value(prm));
286     BRepTopAdaptor_FClass2d FClass2d(F,Precision::PConfusion());
287     TopAbs_State st2=FClass2d.Perform(pt2d,Standard_False);
288     return(st2 == TopAbs_IN);     
289   }
290   return Standard_False;
291 }
292 //=======================================================================
293 //function : Store
294 //purpose  : 
295 //=======================================================================
296
297 static void Store (const TopoDS_Wire& W2,
298                    const TopoDS_Wire& W1,
299                    TopTools_DataMapOfShapeListOfShape& keyIsIn,
300                    TopTools_DataMapOfShapeListOfShape& keyContains)
301 {
302   if (!keyIsIn.IsBound(W2)) {
303     TopTools_ListOfShape empty;
304     keyIsIn.Bind(W2,empty);
305   }
306   keyIsIn(W2).Append(W1);
307   if (!keyContains.IsBound(W1)) {
308     TopTools_ListOfShape empty;
309     keyContains.Bind(W1,empty);
310   }
311   keyContains(W1).Append(W2);
312 }
313 //=======================================================================
314 //function : BuildFaceIn
315 //purpose  : 
316 //=======================================================================
317
318 static void BuildFaceIn(  TopoDS_Face& F, 
319                           const TopoDS_Wire& W, 
320                           TopTools_DataMapOfShapeListOfShape& KeyContains, 
321                           TopTools_DataMapOfShapeListOfShape& KeyIsIn,
322                           TopAbs_Orientation                  Orientation,
323                           TopTools_ListOfShape&               Faces)
324 {
325   BRep_Builder B;
326   
327   if (!KeyContains.IsBound(W) || KeyContains(W).IsEmpty()) return;
328
329 // Removal of W in KeyIsIn.
330 //  for (TopTools_ListIteratorOfListOfShape it(KeyContains(W)); it.More(); it.Next()) {
331
332   TopTools_ListIteratorOfListOfShape it;
333   for (it.Initialize(KeyContains(W)); it.More(); it.Next()) {
334     const TopoDS_Wire&    WI = TopoDS::Wire(it.Value());
335     TopTools_ListOfShape& L2 = KeyIsIn(WI);
336     TopTools_ListIteratorOfListOfShape it2;
337     for (it2.Initialize(L2); it2.More(); it2.Next()) {
338       if (it2.Value().IsSame(W)) {
339         L2.Remove(it2);
340         break;
341       }
342     }
343   }
344
345   TopTools_ListOfShape WireExt;
346
347   for (it.Initialize(KeyContains(W)); it.More(); it.Next()) {
348     const TopoDS_Wire&    WI = TopoDS::Wire(it.Value());
349     TopTools_ListOfShape& L2 = KeyIsIn(WI);
350    
351     if (L2.IsEmpty()) {
352       WireExt.Append(WI);
353     }
354   }
355   
356   for (it.Initialize(WireExt); it.More(); it.Next()) {
357     const TopoDS_Wire&    WI = TopoDS::Wire(it.Value());
358     TopTools_ListOfShape& L2 = KeyIsIn(WI);
359     if (L2.IsEmpty()) {
360       if (Orientation == TopAbs_FORWARD) {
361         TopoDS_Wire NWI(WI);
362         NWI.Reverse();
363         // TopoDS_Wire NWI = TopoDS::Wire(WI.Reversed());
364         B.Add(F,NWI);
365         BuildFaceIn (F,WI,KeyContains, KeyIsIn,TopAbs_REVERSED,Faces);
366       }
367       else {
368         TopoDS_Shape aLocalShape  = Faces.First().EmptyCopied();
369         TopoDS_Face NF = TopoDS::Face(aLocalShape);
370         // TopoDS_Face NF = TopoDS::Face(Faces.First().EmptyCopied());;
371         B.Add        (NF,WI);
372         Faces.Append (NF);
373         BuildFaceIn (NF, WI, KeyContains, KeyIsIn, TopAbs_FORWARD,Faces);
374       }
375     }
376   }
377 }
378
379 //=======================================================================
380 //function : Perform
381 //purpose  : 
382 //=======================================================================
383
384 void BRepAlgo_FaceRestrictor::PerformWithCorrection()
385 {
386   BRep_Builder B;
387
388   myDone = Standard_False;
389   TopTools_ListIteratorOfListOfShape it(wires);
390   //---------------------------------------------------------
391   // Reorientation of all closed wires to the left.
392   //---------------------------------------------------------
393   for (; it.More(); it.Next()) {
394     TopoDS_Wire& W  = TopoDS::Wire(it.Value());
395     TopoDS_Shape aLocalShape = myFace.EmptyCopied();
396     TopoDS_Face  NF = TopoDS::Face(aLocalShape);
397 //    TopoDS_Face  NF = TopoDS::Face(myFace.EmptyCopied());
398     NF.Orientation(TopAbs_FORWARD);
399     B.Add(NF,W);
400     
401     if (IsClosed(W)) {  
402       BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
403       if(FClass2d.PerformInfinitePoint() != TopAbs_OUT) { 
404         W.Reverse();
405       }
406     }
407   }
408   //---------------------------------------------------------
409   // Classification of wires ones compared to the others.
410   //---------------------------------------------------------
411   Standard_Integer j,i = 1;
412
413   for (it.Initialize(wires) ; it.More(); it.Next()) {
414     TopoDS_Wire& W1  = TopoDS::Wire(it.Value());
415     TopTools_ListIteratorOfListOfShape it2(wires);  
416     j = 1;    
417
418     if (IsClosed(W1)) {
419       TopoDS_Shape aLocalShape = myFace.EmptyCopied();
420       TopoDS_Face  NF = TopoDS::Face(aLocalShape);
421 //      TopoDS_Face  NF = TopoDS::Face(myFace.EmptyCopied());
422       NF.Orientation(TopAbs_FORWARD);
423       B.Add(NF,W1);
424       
425       BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
426       while (it2.More()) {
427         const TopoDS_Wire& W2 = TopoDS::Wire(it2.Value());
428         if (!W1.IsSame(W2) && IsInside (W2,NF,FClass2d)) {
429           Store (W2,W1,keyIsIn,keyContains);
430         } 
431         it2.Next();
432         j++;
433       }
434     }
435     i++;
436   }
437   TopTools_ListOfShape WireExt;
438   
439   for (it.Initialize(wires) ; it.More(); it.Next()) {
440     const TopoDS_Wire& W = TopoDS::Wire(it.Value());
441     if (!keyIsIn.IsBound(W) || keyIsIn(W).IsEmpty()) {
442       WireExt.Append(W);
443     }
444   }
445   
446   for (it.Initialize(WireExt) ; it.More(); it.Next()) {
447     const TopoDS_Wire& W = TopoDS::Wire(it.Value());
448     if (!keyIsIn.IsBound(W) || keyIsIn(W).IsEmpty()) {
449       TopoDS_Shape aLocalShape = myFace.EmptyCopied();
450       TopoDS_Face NewFace = TopoDS::Face(aLocalShape);
451 //      TopoDS_Face NewFace = TopoDS::Face(myFace.EmptyCopied());
452       NewFace.Orientation(TopAbs_FORWARD);
453       B.Add     (NewFace,W);
454       faces.Append(NewFace); 
455       //--------------------------------------------
456       // Construction of a face by exterior wire.
457       //--------------------------------------------
458       BuildFaceIn(NewFace,W, keyContains, keyIsIn, TopAbs_FORWARD, faces);
459     }
460   }
461   myDone = Standard_True;
462 }
463
464
465
466
467
468
469
470
471
472