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
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.
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.
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.
22 #include <BRepAlgo_FaceRestrictor.ixx>
24 #include <BRepTopAdaptor_FClass2d.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopoDS_Edge.hxx>
28 #include <TopExp_Explorer.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>
41 #include <Precision.hxx>
43 //=======================================================================
44 //function : BRepAlgo_FaceRestrictor
46 //=======================================================================
48 BRepAlgo_FaceRestrictor::BRepAlgo_FaceRestrictor()
51 //=======================================================================
54 //=======================================================================
56 void BRepAlgo_FaceRestrictor::Init(const TopoDS_Face& F,
57 const Standard_Boolean Proj,
58 const Standard_Boolean CorrectionOrientation)
60 myFace = F; modeProj = Proj; myCorrection = CorrectionOrientation;
64 //=======================================================================
67 //=======================================================================
69 void BRepAlgo_FaceRestrictor::Add(TopoDS_Wire& W)
75 //=======================================================================
78 //=======================================================================
80 void BRepAlgo_FaceRestrictor::Clear()
86 //=======================================================================
87 //function : ChangePcurve
89 //=======================================================================
91 static Standard_Boolean ChangePCurve (TopoDS_Edge& E,
92 const Handle(Geom_Surface)& S,
96 Handle(Geom_Surface) SE;
97 Handle(Geom2d_Curve) C2;
101 BRep_Tool::CurveOnSurface (E,C2,SE,LE,f,l,1);
103 BB.UpdateEdge(E,C2,S,L,Precision::Confusion());
104 return (C2.IsNull());
107 //=======================================================================
108 //function : ProjCurve3d
110 //=======================================================================
112 static void ProjCurve3d (TopoDS_Edge& E,
113 const Handle(Geom_Surface)& S,
119 Handle(Geom_Curve) C = BRep_Tool::Curve(E,LE,f,l);
120 Handle(Geom_TrimmedCurve) CT = new Geom_TrimmedCurve(C,f,l);
122 TopLoc_Location LL = L.Inverted().Multiplied(LE);
123 CT->Transform(LL.Transformation());
125 Handle(Geom2d_Curve) C2 = GeomProjLib::Curve2d (CT,S);
126 BB.UpdateEdge(E,C2,S,L,Precision::Confusion());
129 //=======================================================================
132 //=======================================================================
134 void BRepAlgo_FaceRestrictor::Perform()
138 PerformWithCorrection();
142 myDone = Standard_False;
143 TopTools_ListIteratorOfListOfShape it(wires);
145 //--------------------------------------------------------------------
146 // return geometry of the reference face.
147 //--------------------------------------------------------------------
149 const Handle(Geom_Surface)& S = BRep_Tool::Surface(myFace,L);
151 //-----------------------------------------------------------------------
152 // test if edges are on S. otherwise add S to the first pcurve.
153 // or projection of the edge on F.
154 //----------------------------------------------------------------------
159 TopOpeBRepBuild_WireToFace WTF;
161 for ( ; it.More(); it.Next()) {
162 // update the surface on edges.
163 const TopoDS_Wire& W = TopoDS::Wire(it.Value());
165 for (Exp.Init(W,TopAbs_EDGE); Exp.More(); Exp.Next()) {
167 TopoDS_Edge E = TopoDS::Edge(Exp.Current());
168 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,S,L,f,l);
171 // no pcurve on the reference surface.
173 // Projection of the 3D curve on surface.
174 ProjCurve3d ( E, S, L);
177 // return the first pcurve glued on <S>
178 Standard_Boolean YaPCurve = ChangePCurve (E, S, L);
180 ProjCurve3d (E, S, L);
188 WTF.MakeFaces(myFace,faces);
190 myDone = Standard_True;
194 //=======================================================================
197 //=======================================================================
199 Standard_Boolean BRepAlgo_FaceRestrictor::IsDone() const
205 //=======================================================================
208 //=======================================================================
210 Standard_Boolean BRepAlgo_FaceRestrictor::More() const
212 return (!faces.IsEmpty());
216 //=======================================================================
219 //=======================================================================
221 void BRepAlgo_FaceRestrictor::Next()
227 //=======================================================================
230 //=======================================================================
232 TopoDS_Face BRepAlgo_FaceRestrictor::Current() const
234 return (TopoDS::Face(faces.First()));
237 //=======================================================================
238 //function : Standard_Boolean
240 //=======================================================================
242 static Standard_Boolean IsClosed (const TopoDS_Wire& W)
245 if (W.Closed()) return 1;
247 TopExp::Vertices (W, V1,V2);
248 return (V1.IsSame(V2));
252 //=======================================================================
253 //function : IsInside
255 //=======================================================================
257 static Standard_Boolean IsInside(const TopoDS_Wire& wir,
258 const TopoDS_Face& F,
259 BRepTopAdaptor_FClass2d& /*FClass2d*/)
262 for (exp.Init(wir,TopAbs_EDGE);
265 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
267 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
270 if (!Precision::IsNegativeInfinite(f) && !Precision::IsPositiveInfinite(l)) {
274 if (Precision::IsNegativeInfinite(f) && Precision::IsPositiveInfinite(l)){
277 else if (Precision::IsNegativeInfinite(f)) {
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);
290 return Standard_False;
292 //=======================================================================
295 //=======================================================================
297 static void Store (const TopoDS_Wire& W2,
298 const TopoDS_Wire& W1,
299 TopTools_DataMapOfShapeListOfShape& keyIsIn,
300 TopTools_DataMapOfShapeListOfShape& keyContains)
302 if (!keyIsIn.IsBound(W2)) {
303 TopTools_ListOfShape empty;
304 keyIsIn.Bind(W2,empty);
306 keyIsIn(W2).Append(W1);
307 if (!keyContains.IsBound(W1)) {
308 TopTools_ListOfShape empty;
309 keyContains.Bind(W1,empty);
311 keyContains(W1).Append(W2);
313 //=======================================================================
314 //function : BuildFaceIn
316 //=======================================================================
318 static 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)
327 if (!KeyContains.IsBound(W) || KeyContains(W).IsEmpty()) return;
329 // Removal of W in KeyIsIn.
330 // for (TopTools_ListIteratorOfListOfShape it(KeyContains(W)); it.More(); it.Next()) {
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)) {
345 TopTools_ListOfShape WireExt;
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);
356 for (it.Initialize(WireExt); it.More(); it.Next()) {
357 const TopoDS_Wire& WI = TopoDS::Wire(it.Value());
358 TopTools_ListOfShape& L2 = KeyIsIn(WI);
360 if (Orientation == TopAbs_FORWARD) {
363 // TopoDS_Wire NWI = TopoDS::Wire(WI.Reversed());
365 BuildFaceIn (F,WI,KeyContains, KeyIsIn,TopAbs_REVERSED,Faces);
368 TopoDS_Shape aLocalShape = Faces.First().EmptyCopied();
369 TopoDS_Face NF = TopoDS::Face(aLocalShape);
370 // TopoDS_Face NF = TopoDS::Face(Faces.First().EmptyCopied());;
373 BuildFaceIn (NF, WI, KeyContains, KeyIsIn, TopAbs_FORWARD,Faces);
379 //=======================================================================
382 //=======================================================================
384 void BRepAlgo_FaceRestrictor::PerformWithCorrection()
388 myDone = Standard_False;
389 TopTools_ListIteratorOfListOfShape it(wires);
390 //---------------------------------------------------------
391 // Reorientation of all closed wires to the left.
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);
402 BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
403 if(FClass2d.PerformInfinitePoint() != TopAbs_OUT) {
408 //---------------------------------------------------------
409 // Classification of wires ones compared to the others.
410 //---------------------------------------------------------
411 Standard_Integer j,i = 1;
413 for (it.Initialize(wires) ; it.More(); it.Next()) {
414 TopoDS_Wire& W1 = TopoDS::Wire(it.Value());
415 TopTools_ListIteratorOfListOfShape it2(wires);
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);
425 BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
427 const TopoDS_Wire& W2 = TopoDS::Wire(it2.Value());
428 if (!W1.IsSame(W2) && IsInside (W2,NF,FClass2d)) {
429 Store (W2,W1,keyIsIn,keyContains);
437 TopTools_ListOfShape WireExt;
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()) {
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);
454 faces.Append(NewFace);
455 //--------------------------------------------
456 // Construction of a face by exterior wire.
457 //--------------------------------------------
458 BuildFaceIn(NewFace,W, keyContains, keyIsIn, TopAbs_FORWARD, faces);
461 myDone = Standard_True;