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