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);
189 WTF.MakeFaces(myFace,faces);
191 myDone = Standard_True;
195 //=======================================================================
198 //=======================================================================
200 Standard_Boolean BRepAlgo_FaceRestrictor::IsDone() const
206 //=======================================================================
209 //=======================================================================
211 Standard_Boolean BRepAlgo_FaceRestrictor::More() const
213 return (!faces.IsEmpty());
217 //=======================================================================
220 //=======================================================================
222 void BRepAlgo_FaceRestrictor::Next()
228 //=======================================================================
231 //=======================================================================
233 TopoDS_Face BRepAlgo_FaceRestrictor::Current() const
235 return (TopoDS::Face(faces.First()));
238 //=======================================================================
239 //function : Standard_Boolean
241 //=======================================================================
243 static Standard_Boolean IsClosed (const TopoDS_Wire& W)
246 if (W.Closed()) return 1;
248 TopExp::Vertices (W, V1,V2);
249 return (V1.IsSame(V2));
253 //=======================================================================
254 //function : IsInside
256 //=======================================================================
258 static Standard_Boolean IsInside(const TopoDS_Wire& wir,
259 const TopoDS_Face& F,
260 BRepTopAdaptor_FClass2d& /*FClass2d*/)
265 for (exp.Init(wir,TopAbs_EDGE);
268 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
270 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
273 if (!Precision::IsNegativeInfinite(f) &&
274 !Precision::IsPositiveInfinite(l)) {
278 if (Precision::IsNegativeInfinite(f) &&
279 Precision::IsPositiveInfinite(l)){
282 else if (Precision::IsNegativeInfinite(f)) {
290 gp_Pnt2d pt2d(C2d->Value(prm));
291 BRepTopAdaptor_FClass2d FClass2d(F,Precision::PConfusion());
292 TopAbs_State st2=FClass2d.Perform(pt2d,Standard_False);
293 return(st2 == TopAbs_IN);
295 return Standard_False;
297 //=======================================================================
300 //=======================================================================
302 static void Store (const TopoDS_Wire& W2,
303 const TopoDS_Wire& W1,
304 TopTools_DataMapOfShapeListOfShape& keyIsIn,
305 TopTools_DataMapOfShapeListOfShape& keyContains)
307 if (!keyIsIn.IsBound(W2)) {
308 TopTools_ListOfShape empty;
309 keyIsIn.Bind(W2,empty);
311 keyIsIn(W2).Append(W1);
312 if (!keyContains.IsBound(W1)) {
313 TopTools_ListOfShape empty;
314 keyContains.Bind(W1,empty);
316 keyContains(W1).Append(W2);
318 //=======================================================================
319 //function : BuildFaceIn
321 //=======================================================================
323 static void BuildFaceIn( TopoDS_Face& F,
324 const TopoDS_Wire& W,
325 TopTools_DataMapOfShapeListOfShape& KeyContains,
326 TopTools_DataMapOfShapeListOfShape& KeyIsIn,
327 TopAbs_Orientation Orientation,
328 TopTools_ListOfShape& Faces)
332 if (!KeyContains.IsBound(W) || KeyContains(W).IsEmpty()) return;
334 // Removal of W in KeyIsIn.
335 // for (TopTools_ListIteratorOfListOfShape it(KeyContains(W)); it.More(); it.Next()) {
337 TopTools_ListIteratorOfListOfShape it;
338 for (it.Initialize(KeyContains(W)); it.More(); it.Next()) {
339 const TopoDS_Wire& WI = TopoDS::Wire(it.Value());
340 TopTools_ListOfShape& L2 = KeyIsIn(WI);
341 TopTools_ListIteratorOfListOfShape it2;
342 for (it2.Initialize(L2); it2.More(); it2.Next()) {
343 if (it2.Value().IsSame(W)) {
350 TopTools_ListOfShape WireExt;
352 for (it.Initialize(KeyContains(W)); it.More(); it.Next()) {
353 const TopoDS_Wire& WI = TopoDS::Wire(it.Value());
354 TopTools_ListOfShape& L2 = KeyIsIn(WI);
361 for (it.Initialize(WireExt); it.More(); it.Next()) {
362 const TopoDS_Wire& WI = TopoDS::Wire(it.Value());
363 TopTools_ListOfShape& L2 = KeyIsIn(WI);
365 if (Orientation == TopAbs_FORWARD) {
368 // TopoDS_Wire NWI = TopoDS::Wire(WI.Reversed());
370 BuildFaceIn (F,WI,KeyContains, KeyIsIn,TopAbs_REVERSED,Faces);
373 TopoDS_Shape aLocalShape = Faces.First().EmptyCopied();
374 TopoDS_Face NF = TopoDS::Face(aLocalShape);
375 // TopoDS_Face NF = TopoDS::Face(Faces.First().EmptyCopied());;
378 BuildFaceIn (NF, WI, KeyContains, KeyIsIn, TopAbs_FORWARD,Faces);
384 //=======================================================================
387 //=======================================================================
389 void BRepAlgo_FaceRestrictor::PerformWithCorrection()
393 myDone = Standard_False;
394 TopTools_ListIteratorOfListOfShape it(wires);
395 //---------------------------------------------------------
396 // Reorientation of all closed wires to the left.
397 //---------------------------------------------------------
398 for (; it.More(); it.Next()) {
399 TopoDS_Wire& W = TopoDS::Wire(it.Value());
400 TopoDS_Shape aLocalShape = myFace.EmptyCopied();
401 TopoDS_Face NF = TopoDS::Face(aLocalShape);
402 // TopoDS_Face NF = TopoDS::Face(myFace.EmptyCopied());
403 NF.Orientation(TopAbs_FORWARD);
407 BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
408 if(FClass2d.PerformInfinitePoint() != TopAbs_OUT) {
413 //---------------------------------------------------------
414 // Classification of wires ones compared to the others.
415 //---------------------------------------------------------
416 Standard_Integer j,i = 1;
418 for (it.Initialize(wires) ; it.More(); it.Next()) {
419 TopoDS_Wire& W1 = TopoDS::Wire(it.Value());
420 TopTools_ListIteratorOfListOfShape it2(wires);
424 TopoDS_Shape aLocalShape = myFace.EmptyCopied();
425 TopoDS_Face NF = TopoDS::Face(aLocalShape);
426 // TopoDS_Face NF = TopoDS::Face(myFace.EmptyCopied());
427 NF.Orientation(TopAbs_FORWARD);
430 BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion());
432 const TopoDS_Wire& W2 = TopoDS::Wire(it2.Value());
433 if (!W1.IsSame(W2) && IsInside (W2,NF,FClass2d)) {
434 Store (W2,W1,keyIsIn,keyContains);
442 TopTools_ListOfShape WireExt;
444 for (it.Initialize(wires) ; it.More(); it.Next()) {
445 const TopoDS_Wire& W = TopoDS::Wire(it.Value());
446 if (!keyIsIn.IsBound(W) || keyIsIn(W).IsEmpty()) {
451 for (it.Initialize(WireExt) ; it.More(); it.Next()) {
452 const TopoDS_Wire& W = TopoDS::Wire(it.Value());
453 if (!keyIsIn.IsBound(W) || keyIsIn(W).IsEmpty()) {
454 TopoDS_Shape aLocalShape = myFace.EmptyCopied();
455 TopoDS_Face NewFace = TopoDS::Face(aLocalShape);
456 // TopoDS_Face NewFace = TopoDS::Face(myFace.EmptyCopied());
457 NewFace.Orientation(TopAbs_FORWARD);
459 faces.Append(NewFace);
460 //--------------------------------------------
461 // Construction of a face by exterior wire.
462 //--------------------------------------------
463 BuildFaceIn(NewFace,W, keyContains, keyIsIn, TopAbs_FORWARD, faces);
466 myDone = Standard_True;