0023258: Missing parenthesis
[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     }
186     WTF.AddWire(W);
187   }
188
189   WTF.MakeFaces(myFace,faces);
190
191   myDone = Standard_True;
192 }
193
194
195 //=======================================================================
196 //function : IsDone
197 //purpose  : 
198 //=======================================================================
199
200 Standard_Boolean BRepAlgo_FaceRestrictor::IsDone() const 
201 {
202   return myDone;
203 }
204
205
206 //=======================================================================
207 //function : More
208 //purpose  : 
209 //=======================================================================
210
211 Standard_Boolean BRepAlgo_FaceRestrictor::More() const 
212 {
213   return (!faces.IsEmpty());
214 }
215
216
217 //=======================================================================
218 //function : Next
219 //purpose  : 
220 //=======================================================================
221
222 void BRepAlgo_FaceRestrictor::Next()
223 {
224   faces.RemoveFirst();
225 }
226
227
228 //=======================================================================
229 //function : Current
230 //purpose  : 
231 //=======================================================================
232
233 TopoDS_Face BRepAlgo_FaceRestrictor::Current() const 
234 {
235   return (TopoDS::Face(faces.First()));
236 }
237
238 //=======================================================================
239 //function : Standard_Boolean
240 //purpose  : 
241 //=======================================================================
242
243 static Standard_Boolean IsClosed (const TopoDS_Wire& W)
244      
245 {
246   if (W.Closed()) return 1;
247   TopoDS_Vertex V1,V2;
248   TopExp::Vertices (W, V1,V2);
249   return (V1.IsSame(V2));
250 }
251
252
253 //=======================================================================
254 //function : IsInside
255 //purpose  : 
256 //=======================================================================
257
258 static Standard_Boolean IsInside(const TopoDS_Wire&       wir,
259                                  const TopoDS_Face&       F,
260                                  BRepTopAdaptor_FClass2d& /*FClass2d*/)
261 {
262
263 //Standard_Real U,V;
264   TopExp_Explorer exp;
265   for (exp.Init(wir,TopAbs_EDGE);
266        exp.More();
267        exp.Next()) {
268     const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
269     Standard_Real f,l;
270     Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
271     Standard_Real prm;
272
273     if (!Precision::IsNegativeInfinite(f) && 
274         !Precision::IsPositiveInfinite(l)) {
275       prm = (f+l)/2.;
276     }
277     else {
278       if (Precision::IsNegativeInfinite(f) && 
279           Precision::IsPositiveInfinite(l)){
280         prm = 0.;
281       }
282       else if (Precision::IsNegativeInfinite(f)) {
283         prm = l-1.;
284       }
285       else {
286         prm = f+1.;
287       }
288     }
289
290     gp_Pnt2d pt2d(C2d->Value(prm));
291     BRepTopAdaptor_FClass2d FClass2d(F,Precision::PConfusion());
292     TopAbs_State st2=FClass2d.Perform(pt2d,Standard_False);
293     return(st2 == TopAbs_IN);     
294   }
295   return Standard_False;
296 }
297 //=======================================================================
298 //function : Store
299 //purpose  : 
300 //=======================================================================
301
302 static void Store (const TopoDS_Wire& W2,
303                    const TopoDS_Wire& W1,
304                    TopTools_DataMapOfShapeListOfShape& keyIsIn,
305                    TopTools_DataMapOfShapeListOfShape& keyContains)
306 {
307   if (!keyIsIn.IsBound(W2)) {
308     TopTools_ListOfShape empty;
309     keyIsIn.Bind(W2,empty);
310   }
311   keyIsIn(W2).Append(W1);
312   if (!keyContains.IsBound(W1)) {
313     TopTools_ListOfShape empty;
314     keyContains.Bind(W1,empty);
315   }
316   keyContains(W1).Append(W2);
317 }
318 //=======================================================================
319 //function : BuildFaceIn
320 //purpose  : 
321 //=======================================================================
322
323 static void BuildFaceIn(      TopoDS_Face& F, 
324                         const TopoDS_Wire& W, 
325                         TopTools_DataMapOfShapeListOfShape& KeyContains, 
326                         TopTools_DataMapOfShapeListOfShape& KeyIsIn,
327                         TopAbs_Orientation                  Orientation,
328                         TopTools_ListOfShape&               Faces)
329 {
330   BRep_Builder B;
331   
332   if (!KeyContains.IsBound(W) || KeyContains(W).IsEmpty()) return;
333
334 // Removal of W in KeyIsIn.
335 //  for (TopTools_ListIteratorOfListOfShape it(KeyContains(W)); it.More(); it.Next()) {
336
337   TopTools_ListIteratorOfListOfShape it;
338   for (it.Initialize(KeyContains(W)); it.More(); it.Next()) {
339     const TopoDS_Wire&    WI = TopoDS::Wire(it.Value());
340     TopTools_ListOfShape& L2 = KeyIsIn(WI);
341     TopTools_ListIteratorOfListOfShape it2;
342     for (it2.Initialize(L2); it2.More(); it2.Next()) {
343       if (it2.Value().IsSame(W)) {
344         L2.Remove(it2);
345         break;
346       }
347     }
348   }
349
350   TopTools_ListOfShape WireExt;
351
352   for (it.Initialize(KeyContains(W)); it.More(); it.Next()) {
353     const TopoDS_Wire&    WI = TopoDS::Wire(it.Value());
354     TopTools_ListOfShape& L2 = KeyIsIn(WI);
355    
356     if (L2.IsEmpty()) {
357       WireExt.Append(WI);
358     }
359   }
360   
361   for (it.Initialize(WireExt); it.More(); it.Next()) {
362     const TopoDS_Wire&    WI = TopoDS::Wire(it.Value());
363     TopTools_ListOfShape& L2 = KeyIsIn(WI);
364     if (L2.IsEmpty()) {
365       if (Orientation == TopAbs_FORWARD) {
366         TopoDS_Wire NWI(WI);
367         NWI.Reverse();
368 //      TopoDS_Wire NWI = TopoDS::Wire(WI.Reversed());
369         B.Add(F,NWI);
370         BuildFaceIn (F,WI,KeyContains, KeyIsIn,TopAbs_REVERSED,Faces);
371       }
372       else {
373         TopoDS_Shape aLocalShape  = Faces.First().EmptyCopied();
374         TopoDS_Face NF = TopoDS::Face(aLocalShape);
375 //      TopoDS_Face NF = TopoDS::Face(Faces.First().EmptyCopied());;
376         B.Add        (NF,WI);
377         Faces.Append (NF);
378         BuildFaceIn (NF, WI, KeyContains, KeyIsIn, TopAbs_FORWARD,Faces);
379       }
380     }
381   }
382 }
383
384 //=======================================================================
385 //function : Perform
386 //purpose  : 
387 //=======================================================================
388
389 void BRepAlgo_FaceRestrictor::PerformWithCorrection()
390 {
391   BRep_Builder B;
392
393   myDone = Standard_False;
394   TopTools_ListIteratorOfListOfShape it(wires);
395   //---------------------------------------------------------
396   // Reorientation of all closed wires to the left.
397   //---------------------------------------------------------
398   for (; it.More(); it.Next()) {
399     TopoDS_Wire& W  = TopoDS::Wire(it.Value());
400     TopoDS_Shape aLocalShape = myFace.EmptyCopied();
401     TopoDS_Face  NF = TopoDS::Face(aLocalShape);
402 //    TopoDS_Face  NF = TopoDS::Face(myFace.EmptyCopied());
403     NF.Orientation(TopAbs_FORWARD);
404     B.Add(NF,W);
405     
406     if (IsClosed(W)) {  
407       BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
408       if(FClass2d.PerformInfinitePoint() != TopAbs_OUT) { 
409         W.Reverse();
410       }
411     }
412   }
413   //---------------------------------------------------------
414   // Classification of wires ones compared to the others.
415   //---------------------------------------------------------
416   Standard_Integer j,i = 1;
417
418   for (it.Initialize(wires) ; it.More(); it.Next()) {
419     TopoDS_Wire& W1  = TopoDS::Wire(it.Value());
420     TopTools_ListIteratorOfListOfShape it2(wires);  
421     j = 1;    
422
423     if (IsClosed(W1)) {
424       TopoDS_Shape aLocalShape = myFace.EmptyCopied();
425       TopoDS_Face  NF = TopoDS::Face(aLocalShape);
426 //      TopoDS_Face  NF = TopoDS::Face(myFace.EmptyCopied());
427       NF.Orientation(TopAbs_FORWARD);
428       B.Add(NF,W1);
429       
430       BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
431       while (it2.More()) {
432         const TopoDS_Wire& W2 = TopoDS::Wire(it2.Value());
433         if (!W1.IsSame(W2) && IsInside (W2,NF,FClass2d)) {
434           Store (W2,W1,keyIsIn,keyContains);
435         } 
436         it2.Next();
437         j++;
438       }
439     }
440     i++;
441   }
442   TopTools_ListOfShape WireExt;
443   
444   for (it.Initialize(wires) ; it.More(); it.Next()) {
445     const TopoDS_Wire& W = TopoDS::Wire(it.Value());
446     if (!keyIsIn.IsBound(W) || keyIsIn(W).IsEmpty()) {
447       WireExt.Append(W);
448     }
449   }
450   
451   for (it.Initialize(WireExt) ; it.More(); it.Next()) {
452     const TopoDS_Wire& W = TopoDS::Wire(it.Value());
453     if (!keyIsIn.IsBound(W) || keyIsIn(W).IsEmpty()) {
454       TopoDS_Shape aLocalShape = myFace.EmptyCopied();
455       TopoDS_Face NewFace = TopoDS::Face(aLocalShape);
456 //      TopoDS_Face NewFace = TopoDS::Face(myFace.EmptyCopied());
457       NewFace.Orientation(TopAbs_FORWARD);
458       B.Add     (NewFace,W);
459       faces.Append(NewFace); 
460       //--------------------------------------------
461       // Construction of a face by exterior wire.
462       //--------------------------------------------
463       BuildFaceIn(NewFace,W, keyContains, keyIsIn, TopAbs_FORWARD, faces);
464     }
465   }
466   myDone = Standard_True;
467 }
468
469
470
471
472
473
474
475
476
477