0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[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
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7fd59977 17
42cf5bc1 18#include <BRep_Builder.hxx>
19#include <BRep_Tool.hxx>
20#include <BRepAlgo_FaceRestrictor.hxx>
7fd59977 21#include <BRepTopAdaptor_FClass2d.hxx>
7fd59977 22#include <Geom2d_Curve.hxx>
23#include <Geom_Curve.hxx>
42cf5bc1 24#include <Geom_Surface.hxx>
7fd59977 25#include <Geom_TrimmedCurve.hxx>
7fd59977 26#include <GeomProjLib.hxx>
27#include <gp_Pnt2d.hxx>
7fd59977 28#include <Precision.hxx>
42cf5bc1 29#include <TopExp.hxx>
30#include <TopExp_Explorer.hxx>
31#include <TopoDS.hxx>
32#include <TopoDS_Edge.hxx>
33#include <TopoDS_Face.hxx>
34#include <TopoDS_Vertex.hxx>
35#include <TopoDS_Wire.hxx>
36#include <TopOpeBRepBuild_WireToFace.hxx>
37#include <TopTools_ListIteratorOfListOfShape.hxx>
7fd59977 38
39//=======================================================================
40//function : BRepAlgo_FaceRestrictor
41//purpose :
42//=======================================================================
7fd59977 43BRepAlgo_FaceRestrictor::BRepAlgo_FaceRestrictor()
44{}
45
46//=======================================================================
47//function :
48//purpose :
49//=======================================================================
50
51void BRepAlgo_FaceRestrictor::Init(const TopoDS_Face& F,
d3f26155 52 const Standard_Boolean Proj,
53 const Standard_Boolean CorrectionOrientation)
7fd59977 54{
55 myFace = F; modeProj = Proj; myCorrection = CorrectionOrientation;
56}
57
58
59//=======================================================================
60//function : Add
61//purpose :
62//=======================================================================
63
64void BRepAlgo_FaceRestrictor::Add(TopoDS_Wire& W)
65{
66 wires.Append(W);
67}
68
69
70//=======================================================================
71//function : Clear
72//purpose :
73//=======================================================================
74
75void BRepAlgo_FaceRestrictor::Clear()
76{
77 wires.Clear();
78 faces.Clear();
79}
80
81//=======================================================================
82//function : ChangePcurve
83//purpose :
84//=======================================================================
85
86static Standard_Boolean ChangePCurve (TopoDS_Edge& E,
d3f26155 87 const Handle(Geom_Surface)& S,
88 TopLoc_Location& L)
7fd59977 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
107static void ProjCurve3d (TopoDS_Edge& E,
d3f26155 108 const Handle(Geom_Surface)& S,
109 TopLoc_Location& L)
7fd59977 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());
d3f26155 122}
7fd59977 123
124//=======================================================================
125//function : Perform
126//purpose :
127//=======================================================================
128
129void 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 //--------------------------------------------------------------------
0d969553 141 // return geometry of the reference face.
7fd59977 142 //--------------------------------------------------------------------
143 TopLoc_Location L;
144 const Handle(Geom_Surface)& S = BRep_Tool::Surface(myFace,L);
145
146 //-----------------------------------------------------------------------
0d969553
Y
147 // test if edges are on S. otherwise add S to the first pcurve.
148 // or projection of the edge on F.
7fd59977 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()) {
0d969553 157 // update the surface on edges.
7fd59977 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()) {
d3f26155 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 }
7fd59977 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
194Standard_Boolean BRepAlgo_FaceRestrictor::IsDone() const
195{
196 return myDone;
197}
198
199
200//=======================================================================
201//function : More
202//purpose :
203//=======================================================================
204
205Standard_Boolean BRepAlgo_FaceRestrictor::More() const
206{
207 return (!faces.IsEmpty());
208}
209
210
211//=======================================================================
212//function : Next
213//purpose :
214//=======================================================================
215
216void BRepAlgo_FaceRestrictor::Next()
217{
218 faces.RemoveFirst();
219}
220
221
222//=======================================================================
223//function : Current
224//purpose :
225//=======================================================================
226
227TopoDS_Face BRepAlgo_FaceRestrictor::Current() const
228{
229 return (TopoDS::Face(faces.First()));
230}
231
232//=======================================================================
233//function : Standard_Boolean
234//purpose :
235//=======================================================================
236
237static 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
252static Standard_Boolean IsInside(const TopoDS_Wire& wir,
d3f26155 253 const TopoDS_Face& F,
254 BRepTopAdaptor_FClass2d& /*FClass2d*/)
7fd59977 255{
7fd59977 256 TopExp_Explorer exp;
3ed30348 257 exp.Init(wir,TopAbs_EDGE);
258 if (exp.More()) {
7fd59977 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
d3f26155 264 if (!Precision::IsNegativeInfinite(f) && !Precision::IsPositiveInfinite(l)) {
7fd59977 265 prm = (f+l)/2.;
266 }
267 else {
d3f26155 268 if (Precision::IsNegativeInfinite(f) && Precision::IsPositiveInfinite(l)){
269 prm = 0.;
7fd59977 270 }
271 else if (Precision::IsNegativeInfinite(f)) {
d3f26155 272 prm = l-1.;
7fd59977 273 }
274 else {
d3f26155 275 prm = f+1.;
7fd59977 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
291static void Store (const TopoDS_Wire& W2,
d3f26155 292 const TopoDS_Wire& W1,
293 TopTools_DataMapOfShapeListOfShape& keyIsIn,
294 TopTools_DataMapOfShapeListOfShape& keyContains)
7fd59977 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
d3f26155 312static 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)
7fd59977 318{
319 BRep_Builder B;
320
321 if (!KeyContains.IsBound(W) || KeyContains(W).IsEmpty()) return;
322
0d969553 323// Removal of W in KeyIsIn.
7fd59977 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)) {
d3f26155 333 L2.Remove(it2);
334 break;
7fd59977 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) {
d3f26155 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);
7fd59977 360 }
361 else {
d3f26155 362 TopoDS_Shape aLocalShape = Faces.First().EmptyCopied();
363 TopoDS_Face NF = TopoDS::Face(aLocalShape);
8c2d3314 364 // TopoDS_Face NF = TopoDS::Face(Faces.First().EmptyCopied());
d3f26155 365 B.Add (NF,WI);
366 Faces.Append (NF);
367 BuildFaceIn (NF, WI, KeyContains, KeyIsIn, TopAbs_FORWARD,Faces);
7fd59977 368 }
369 }
370 }
371}
372
373//=======================================================================
374//function : Perform
375//purpose :
376//=======================================================================
377
378void BRepAlgo_FaceRestrictor::PerformWithCorrection()
379{
380 BRep_Builder B;
381
382 myDone = Standard_False;
383 TopTools_ListIteratorOfListOfShape it(wires);
384 //---------------------------------------------------------
0d969553 385 // Reorientation of all closed wires to the left.
7fd59977 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) {
d3f26155 398 W.Reverse();
7fd59977 399 }
400 }
401 }
402 //---------------------------------------------------------
0d969553 403 // Classification of wires ones compared to the others.
7fd59977 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()) {
d3f26155 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++;
7fd59977 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 //--------------------------------------------
0d969553 450 // Construction of a face by exterior wire.
7fd59977 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