0024148: Test case bugs/vis/bug24131_markers works wrong with software MS OpenGL
[occt.git] / src / BRepAlgo / BRepAlgo_FaceRestrictor.cxx
CommitLineData
b311480e 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
7fd59977 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
48BRepAlgo_FaceRestrictor::BRepAlgo_FaceRestrictor()
49{}
50
51//=======================================================================
52//function :
53//purpose :
54//=======================================================================
55
56void BRepAlgo_FaceRestrictor::Init(const TopoDS_Face& F,
d3f26155 57 const Standard_Boolean Proj,
58 const Standard_Boolean CorrectionOrientation)
7fd59977 59{
60 myFace = F; modeProj = Proj; myCorrection = CorrectionOrientation;
61}
62
63
64//=======================================================================
65//function : Add
66//purpose :
67//=======================================================================
68
69void BRepAlgo_FaceRestrictor::Add(TopoDS_Wire& W)
70{
71 wires.Append(W);
72}
73
74
75//=======================================================================
76//function : Clear
77//purpose :
78//=======================================================================
79
80void BRepAlgo_FaceRestrictor::Clear()
81{
82 wires.Clear();
83 faces.Clear();
84}
85
86//=======================================================================
87//function : ChangePcurve
88//purpose :
89//=======================================================================
90
91static Standard_Boolean ChangePCurve (TopoDS_Edge& E,
d3f26155 92 const Handle(Geom_Surface)& S,
93 TopLoc_Location& L)
7fd59977 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
112static void ProjCurve3d (TopoDS_Edge& E,
d3f26155 113 const Handle(Geom_Surface)& S,
114 TopLoc_Location& L)
7fd59977 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());
d3f26155 127}
7fd59977 128
129//=======================================================================
130//function : Perform
131//purpose :
132//=======================================================================
133
134void 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 //--------------------------------------------------------------------
0d969553 146 // return geometry of the reference face.
7fd59977 147 //--------------------------------------------------------------------
148 TopLoc_Location L;
149 const Handle(Geom_Surface)& S = BRep_Tool::Surface(myFace,L);
150
151 //-----------------------------------------------------------------------
0d969553
Y
152 // test if edges are on S. otherwise add S to the first pcurve.
153 // or projection of the edge on F.
7fd59977 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()) {
0d969553 162 // update the surface on edges.
7fd59977 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()) {
d3f26155 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 }
7fd59977 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
199Standard_Boolean BRepAlgo_FaceRestrictor::IsDone() const
200{
201 return myDone;
202}
203
204
205//=======================================================================
206//function : More
207//purpose :
208//=======================================================================
209
210Standard_Boolean BRepAlgo_FaceRestrictor::More() const
211{
212 return (!faces.IsEmpty());
213}
214
215
216//=======================================================================
217//function : Next
218//purpose :
219//=======================================================================
220
221void BRepAlgo_FaceRestrictor::Next()
222{
223 faces.RemoveFirst();
224}
225
226
227//=======================================================================
228//function : Current
229//purpose :
230//=======================================================================
231
232TopoDS_Face BRepAlgo_FaceRestrictor::Current() const
233{
234 return (TopoDS::Face(faces.First()));
235}
236
237//=======================================================================
238//function : Standard_Boolean
239//purpose :
240//=======================================================================
241
242static 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
257static Standard_Boolean IsInside(const TopoDS_Wire& wir,
d3f26155 258 const TopoDS_Face& F,
259 BRepTopAdaptor_FClass2d& /*FClass2d*/)
7fd59977 260{
7fd59977 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
d3f26155 270 if (!Precision::IsNegativeInfinite(f) && !Precision::IsPositiveInfinite(l)) {
7fd59977 271 prm = (f+l)/2.;
272 }
273 else {
d3f26155 274 if (Precision::IsNegativeInfinite(f) && Precision::IsPositiveInfinite(l)){
275 prm = 0.;
7fd59977 276 }
277 else if (Precision::IsNegativeInfinite(f)) {
d3f26155 278 prm = l-1.;
7fd59977 279 }
280 else {
d3f26155 281 prm = f+1.;
7fd59977 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
297static void Store (const TopoDS_Wire& W2,
d3f26155 298 const TopoDS_Wire& W1,
299 TopTools_DataMapOfShapeListOfShape& keyIsIn,
300 TopTools_DataMapOfShapeListOfShape& keyContains)
7fd59977 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
d3f26155 318static 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)
7fd59977 324{
325 BRep_Builder B;
326
327 if (!KeyContains.IsBound(W) || KeyContains(W).IsEmpty()) return;
328
0d969553 329// Removal of W in KeyIsIn.
7fd59977 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)) {
d3f26155 339 L2.Remove(it2);
340 break;
7fd59977 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) {
d3f26155 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);
7fd59977 366 }
367 else {
d3f26155 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);
7fd59977 374 }
375 }
376 }
377}
378
379//=======================================================================
380//function : Perform
381//purpose :
382//=======================================================================
383
384void BRepAlgo_FaceRestrictor::PerformWithCorrection()
385{
386 BRep_Builder B;
387
388 myDone = Standard_False;
389 TopTools_ListIteratorOfListOfShape it(wires);
390 //---------------------------------------------------------
0d969553 391 // Reorientation of all closed wires to the left.
7fd59977 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) {
d3f26155 404 W.Reverse();
7fd59977 405 }
406 }
407 }
408 //---------------------------------------------------------
0d969553 409 // Classification of wires ones compared to the others.
7fd59977 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()) {
d3f26155 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++;
7fd59977 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 //--------------------------------------------
0d969553 456 // Construction of a face by exterior wire.
7fd59977 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