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