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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAlgo_FaceRestrictor.hxx>
21 #include <BRepTopAdaptor_FClass2d.hxx>
22 #include <Geom2d_Curve.hxx>
23 #include <Geom_Curve.hxx>
24 #include <Geom_Surface.hxx>
25 #include <Geom_TrimmedCurve.hxx>
26 #include <GeomProjLib.hxx>
27 #include <gp_Pnt2d.hxx>
28 #include <Precision.hxx>
30 #include <TopExp_Explorer.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>
39 //=======================================================================
40 //function : BRepAlgo_FaceRestrictor
42 //=======================================================================
43 BRepAlgo_FaceRestrictor::BRepAlgo_FaceRestrictor()
46 //=======================================================================
49 //=======================================================================
51 void BRepAlgo_FaceRestrictor::Init(const TopoDS_Face& F,
52 const Standard_Boolean Proj,
53 const Standard_Boolean CorrectionOrientation)
55 myFace = F; modeProj = Proj; myCorrection = CorrectionOrientation;
59 //=======================================================================
62 //=======================================================================
64 void BRepAlgo_FaceRestrictor::Add(TopoDS_Wire& W)
70 //=======================================================================
73 //=======================================================================
75 void BRepAlgo_FaceRestrictor::Clear()
81 //=======================================================================
82 //function : ChangePcurve
84 //=======================================================================
86 static Standard_Boolean ChangePCurve (TopoDS_Edge& E,
87 const Handle(Geom_Surface)& S,
91 Handle(Geom_Surface) SE;
92 Handle(Geom2d_Curve) C2;
96 BRep_Tool::CurveOnSurface (E,C2,SE,LE,f,l,1);
98 BB.UpdateEdge(E,C2,S,L,Precision::Confusion());
102 //=======================================================================
103 //function : ProjCurve3d
105 //=======================================================================
107 static void ProjCurve3d (TopoDS_Edge& E,
108 const Handle(Geom_Surface)& S,
114 Handle(Geom_Curve) C = BRep_Tool::Curve(E,LE,f,l);
115 Handle(Geom_TrimmedCurve) CT = new Geom_TrimmedCurve(C,f,l);
117 TopLoc_Location LL = L.Inverted().Multiplied(LE);
118 CT->Transform(LL.Transformation());
120 Handle(Geom2d_Curve) C2 = GeomProjLib::Curve2d (CT,S);
121 BB.UpdateEdge(E,C2,S,L,Precision::Confusion());
124 //=======================================================================
127 //=======================================================================
129 void BRepAlgo_FaceRestrictor::Perform()
133 PerformWithCorrection();
137 myDone = Standard_False;
138 TopTools_ListIteratorOfListOfShape it(wires);
140 //--------------------------------------------------------------------
141 // return geometry of the reference face.
142 //--------------------------------------------------------------------
144 const Handle(Geom_Surface)& S = BRep_Tool::Surface(myFace,L);
146 //-----------------------------------------------------------------------
147 // test if edges are on S. otherwise add S to the first pcurve.
148 // or projection of the edge on F.
149 //----------------------------------------------------------------------
154 TopOpeBRepBuild_WireToFace WTF;
156 for ( ; it.More(); it.Next()) {
157 // update the surface on edges.
158 const TopoDS_Wire& W = TopoDS::Wire(it.Value());
160 for (Exp.Init(W,TopAbs_EDGE); Exp.More(); Exp.Next()) {
162 TopoDS_Edge E = TopoDS::Edge(Exp.Current());
163 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,S,L,f,l);
166 // no pcurve on the reference surface.
168 // Projection of the 3D curve on surface.
169 ProjCurve3d ( E, S, L);
172 // return the first pcurve glued on <S>
173 Standard_Boolean YaPCurve = ChangePCurve (E, S, L);
175 ProjCurve3d (E, S, L);
183 WTF.MakeFaces(myFace,faces);
185 myDone = Standard_True;
189 //=======================================================================
192 //=======================================================================
194 Standard_Boolean BRepAlgo_FaceRestrictor::IsDone() const
200 //=======================================================================
203 //=======================================================================
205 Standard_Boolean BRepAlgo_FaceRestrictor::More() const
207 return (!faces.IsEmpty());
211 //=======================================================================
214 //=======================================================================
216 void BRepAlgo_FaceRestrictor::Next()
222 //=======================================================================
225 //=======================================================================
227 TopoDS_Face BRepAlgo_FaceRestrictor::Current() const
229 return (TopoDS::Face(faces.First()));
232 //=======================================================================
233 //function : Standard_Boolean
235 //=======================================================================
237 static Standard_Boolean IsClosed (const TopoDS_Wire& W)
240 if (W.Closed()) return 1;
242 TopExp::Vertices (W, V1,V2);
243 return (V1.IsSame(V2));
247 //=======================================================================
248 //function : IsInside
250 //=======================================================================
252 static Standard_Boolean IsInside(const TopoDS_Wire& wir,
253 const TopoDS_Face& F,
254 BRepTopAdaptor_FClass2d& /*FClass2d*/)
257 exp.Init(wir,TopAbs_EDGE);
259 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
261 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
264 if (!Precision::IsNegativeInfinite(f) && !Precision::IsPositiveInfinite(l)) {
268 if (Precision::IsNegativeInfinite(f) && Precision::IsPositiveInfinite(l)){
271 else if (Precision::IsNegativeInfinite(f)) {
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);
284 return Standard_False;
286 //=======================================================================
289 //=======================================================================
291 static void Store (const TopoDS_Wire& W2,
292 const TopoDS_Wire& W1,
293 TopTools_DataMapOfShapeListOfShape& keyIsIn,
294 TopTools_DataMapOfShapeListOfShape& keyContains)
296 if (!keyIsIn.IsBound(W2)) {
297 TopTools_ListOfShape empty;
298 keyIsIn.Bind(W2,empty);
300 keyIsIn(W2).Append(W1);
301 if (!keyContains.IsBound(W1)) {
302 TopTools_ListOfShape empty;
303 keyContains.Bind(W1,empty);
305 keyContains(W1).Append(W2);
307 //=======================================================================
308 //function : BuildFaceIn
310 //=======================================================================
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)
321 if (!KeyContains.IsBound(W) || KeyContains(W).IsEmpty()) return;
323 // Removal of W in KeyIsIn.
324 // for (TopTools_ListIteratorOfListOfShape it(KeyContains(W)); it.More(); it.Next()) {
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)) {
339 TopTools_ListOfShape WireExt;
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);
350 for (it.Initialize(WireExt); it.More(); it.Next()) {
351 const TopoDS_Wire& WI = TopoDS::Wire(it.Value());
352 TopTools_ListOfShape& L2 = KeyIsIn(WI);
354 if (Orientation == TopAbs_FORWARD) {
357 // TopoDS_Wire NWI = TopoDS::Wire(WI.Reversed());
359 BuildFaceIn (F,WI,KeyContains, KeyIsIn,TopAbs_REVERSED,Faces);
362 TopoDS_Shape aLocalShape = Faces.First().EmptyCopied();
363 TopoDS_Face NF = TopoDS::Face(aLocalShape);
364 // TopoDS_Face NF = TopoDS::Face(Faces.First().EmptyCopied());
367 BuildFaceIn (NF, WI, KeyContains, KeyIsIn, TopAbs_FORWARD,Faces);
373 //=======================================================================
376 //=======================================================================
378 void BRepAlgo_FaceRestrictor::PerformWithCorrection()
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);
396 BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
397 if(FClass2d.PerformInfinitePoint() != TopAbs_OUT) {
402 //---------------------------------------------------------
403 // Classification of wires ones compared to the others.
404 //---------------------------------------------------------
405 Standard_Integer j,i = 1;
407 for (it.Initialize(wires) ; it.More(); it.Next()) {
408 TopoDS_Wire& W1 = TopoDS::Wire(it.Value());
409 TopTools_ListIteratorOfListOfShape it2(wires);
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);
419 BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
421 const TopoDS_Wire& W2 = TopoDS::Wire(it2.Value());
422 if (!W1.IsSame(W2) && IsInside (W2,NF,FClass2d)) {
423 Store (W2,W1,keyIsIn,keyContains);
431 TopTools_ListOfShape WireExt;
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()) {
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);
448 faces.Append(NewFace);
449 //--------------------------------------------
450 // Construction of a face by exterior wire.
451 //--------------------------------------------
452 BuildFaceIn(NewFace,W, keyContains, keyIsIn, TopAbs_FORWARD, faces);
455 myDone = Standard_True;