0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[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;
3ed30348 262 exp.Init(wir,TopAbs_EDGE);
263 if (exp.More()) {
7fd59977 264 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
265 Standard_Real f,l;
266 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
267 Standard_Real prm;
268
d3f26155 269 if (!Precision::IsNegativeInfinite(f) && !Precision::IsPositiveInfinite(l)) {
7fd59977 270 prm = (f+l)/2.;
271 }
272 else {
d3f26155 273 if (Precision::IsNegativeInfinite(f) && Precision::IsPositiveInfinite(l)){
274 prm = 0.;
7fd59977 275 }
276 else if (Precision::IsNegativeInfinite(f)) {
d3f26155 277 prm = l-1.;
7fd59977 278 }
279 else {
d3f26155 280 prm = f+1.;
7fd59977 281 }
282 }
283
284 gp_Pnt2d pt2d(C2d->Value(prm));
285 BRepTopAdaptor_FClass2d FClass2d(F,Precision::PConfusion());
286 TopAbs_State st2=FClass2d.Perform(pt2d,Standard_False);
287 return(st2 == TopAbs_IN);
288 }
289 return Standard_False;
290}
291//=======================================================================
292//function : Store
293//purpose :
294//=======================================================================
295
296static void Store (const TopoDS_Wire& W2,
d3f26155 297 const TopoDS_Wire& W1,
298 TopTools_DataMapOfShapeListOfShape& keyIsIn,
299 TopTools_DataMapOfShapeListOfShape& keyContains)
7fd59977 300{
301 if (!keyIsIn.IsBound(W2)) {
302 TopTools_ListOfShape empty;
303 keyIsIn.Bind(W2,empty);
304 }
305 keyIsIn(W2).Append(W1);
306 if (!keyContains.IsBound(W1)) {
307 TopTools_ListOfShape empty;
308 keyContains.Bind(W1,empty);
309 }
310 keyContains(W1).Append(W2);
311}
312//=======================================================================
313//function : BuildFaceIn
314//purpose :
315//=======================================================================
316
d3f26155 317static void BuildFaceIn( TopoDS_Face& F,
318 const TopoDS_Wire& W,
319 TopTools_DataMapOfShapeListOfShape& KeyContains,
320 TopTools_DataMapOfShapeListOfShape& KeyIsIn,
321 TopAbs_Orientation Orientation,
322 TopTools_ListOfShape& Faces)
7fd59977 323{
324 BRep_Builder B;
325
326 if (!KeyContains.IsBound(W) || KeyContains(W).IsEmpty()) return;
327
0d969553 328// Removal of W in KeyIsIn.
7fd59977 329// for (TopTools_ListIteratorOfListOfShape it(KeyContains(W)); it.More(); it.Next()) {
330
331 TopTools_ListIteratorOfListOfShape it;
332 for (it.Initialize(KeyContains(W)); it.More(); it.Next()) {
333 const TopoDS_Wire& WI = TopoDS::Wire(it.Value());
334 TopTools_ListOfShape& L2 = KeyIsIn(WI);
335 TopTools_ListIteratorOfListOfShape it2;
336 for (it2.Initialize(L2); it2.More(); it2.Next()) {
337 if (it2.Value().IsSame(W)) {
d3f26155 338 L2.Remove(it2);
339 break;
7fd59977 340 }
341 }
342 }
343
344 TopTools_ListOfShape WireExt;
345
346 for (it.Initialize(KeyContains(W)); it.More(); it.Next()) {
347 const TopoDS_Wire& WI = TopoDS::Wire(it.Value());
348 TopTools_ListOfShape& L2 = KeyIsIn(WI);
349
350 if (L2.IsEmpty()) {
351 WireExt.Append(WI);
352 }
353 }
354
355 for (it.Initialize(WireExt); it.More(); it.Next()) {
356 const TopoDS_Wire& WI = TopoDS::Wire(it.Value());
357 TopTools_ListOfShape& L2 = KeyIsIn(WI);
358 if (L2.IsEmpty()) {
359 if (Orientation == TopAbs_FORWARD) {
d3f26155 360 TopoDS_Wire NWI(WI);
361 NWI.Reverse();
362 // TopoDS_Wire NWI = TopoDS::Wire(WI.Reversed());
363 B.Add(F,NWI);
364 BuildFaceIn (F,WI,KeyContains, KeyIsIn,TopAbs_REVERSED,Faces);
7fd59977 365 }
366 else {
d3f26155 367 TopoDS_Shape aLocalShape = Faces.First().EmptyCopied();
368 TopoDS_Face NF = TopoDS::Face(aLocalShape);
369 // TopoDS_Face NF = TopoDS::Face(Faces.First().EmptyCopied());;
370 B.Add (NF,WI);
371 Faces.Append (NF);
372 BuildFaceIn (NF, WI, KeyContains, KeyIsIn, TopAbs_FORWARD,Faces);
7fd59977 373 }
374 }
375 }
376}
377
378//=======================================================================
379//function : Perform
380//purpose :
381//=======================================================================
382
383void BRepAlgo_FaceRestrictor::PerformWithCorrection()
384{
385 BRep_Builder B;
386
387 myDone = Standard_False;
388 TopTools_ListIteratorOfListOfShape it(wires);
389 //---------------------------------------------------------
0d969553 390 // Reorientation of all closed wires to the left.
7fd59977 391 //---------------------------------------------------------
392 for (; it.More(); it.Next()) {
393 TopoDS_Wire& W = TopoDS::Wire(it.Value());
394 TopoDS_Shape aLocalShape = myFace.EmptyCopied();
395 TopoDS_Face NF = TopoDS::Face(aLocalShape);
396// TopoDS_Face NF = TopoDS::Face(myFace.EmptyCopied());
397 NF.Orientation(TopAbs_FORWARD);
398 B.Add(NF,W);
399
400 if (IsClosed(W)) {
401 BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
402 if(FClass2d.PerformInfinitePoint() != TopAbs_OUT) {
d3f26155 403 W.Reverse();
7fd59977 404 }
405 }
406 }
407 //---------------------------------------------------------
0d969553 408 // Classification of wires ones compared to the others.
7fd59977 409 //---------------------------------------------------------
410 Standard_Integer j,i = 1;
411
412 for (it.Initialize(wires) ; it.More(); it.Next()) {
413 TopoDS_Wire& W1 = TopoDS::Wire(it.Value());
414 TopTools_ListIteratorOfListOfShape it2(wires);
415 j = 1;
416
417 if (IsClosed(W1)) {
418 TopoDS_Shape aLocalShape = myFace.EmptyCopied();
419 TopoDS_Face NF = TopoDS::Face(aLocalShape);
420// TopoDS_Face NF = TopoDS::Face(myFace.EmptyCopied());
421 NF.Orientation(TopAbs_FORWARD);
422 B.Add(NF,W1);
423
424 BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
425 while (it2.More()) {
d3f26155 426 const TopoDS_Wire& W2 = TopoDS::Wire(it2.Value());
427 if (!W1.IsSame(W2) && IsInside (W2,NF,FClass2d)) {
428 Store (W2,W1,keyIsIn,keyContains);
429 }
430 it2.Next();
431 j++;
7fd59977 432 }
433 }
434 i++;
435 }
436 TopTools_ListOfShape WireExt;
437
438 for (it.Initialize(wires) ; it.More(); it.Next()) {
439 const TopoDS_Wire& W = TopoDS::Wire(it.Value());
440 if (!keyIsIn.IsBound(W) || keyIsIn(W).IsEmpty()) {
441 WireExt.Append(W);
442 }
443 }
444
445 for (it.Initialize(WireExt) ; it.More(); it.Next()) {
446 const TopoDS_Wire& W = TopoDS::Wire(it.Value());
447 if (!keyIsIn.IsBound(W) || keyIsIn(W).IsEmpty()) {
448 TopoDS_Shape aLocalShape = myFace.EmptyCopied();
449 TopoDS_Face NewFace = TopoDS::Face(aLocalShape);
450// TopoDS_Face NewFace = TopoDS::Face(myFace.EmptyCopied());
451 NewFace.Orientation(TopAbs_FORWARD);
452 B.Add (NewFace,W);
453 faces.Append(NewFace);
454 //--------------------------------------------
0d969553 455 // Construction of a face by exterior wire.
7fd59977 456 //--------------------------------------------
457 BuildFaceIn(NewFace,W, keyContains, keyIsIn, TopAbs_FORWARD, faces);
458 }
459 }
460 myDone = Standard_True;
461}
462
463
464
465
466
467
468
469
470
471