2 // File : Partition_Loop.cxx
3 // Created : Thu Aug 02 16:25:17 2001
4 // Author : Benedicte MARTIN
7 // Copyright : Open CASCADE
12 #include "Partition_Loop.ixx"
14 #include "utilities.h"
16 #include <BRep_Builder.hxx>
17 #include <BRepAlgo_FaceRestrictor.hxx>
18 #include <BRep_Tool.hxx>
20 #include <Geom2d_Curve.hxx>
21 #include <Geom_Surface.hxx>
23 #include <TopTools_SequenceOfShape.hxx>
24 #include <TopTools_ListIteratorOfListOfShape.hxx>
25 #include <TopTools_MapOfShape.hxx>
26 #include <TopTools_MapIteratorOfMapOfShape.hxx>
27 #include <TopTools_MapOfOrientedShape.hxx>
28 #include <TopTools_DataMapOfShapeShape.hxx>
29 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
32 #include <gp_Pnt2d.hxx>
35 #include <TopoDS_Vertex.hxx>
36 #include <TopoDS_Wire.hxx>
37 #include <TopoDS_Iterator.hxx>
39 #include <Precision.hxx>
40 #include <BRep_TVertex.hxx>
41 #include <BRep_TEdge.hxx>
44 #include <TopExp_Explorer.hxx>
46 static char* name = new char[100];
49 //=======================================================================
50 //function : Partition_Loop
52 //=======================================================================
53 Partition_Loop::Partition_Loop()
57 //=======================================================================
60 //=======================================================================
61 void Partition_Loop::Init(const TopoDS_Face& F)
69 //=======================================================================
70 //function : AddConstEdge
72 //=======================================================================
73 void Partition_Loop::AddConstEdge (const TopoDS_Edge& E)
75 myConstEdges.Append(E);
79 //=======================================================================
80 //function : FindDelta
82 //=======================================================================
83 static Standard_Real FindDelta(TopTools_ListOfShape& LE,
86 Standard_Real dist, f, l;
87 Standard_Real d = Precision::Infinite();
88 TopTools_ListIteratorOfListOfShape itl;
90 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
91 const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
92 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l);
93 gp_Pnt2d p = C->Value(f);
94 gp_Pnt2d pp = C->Value(l);
95 Standard_Real d1 = p.Distance(pp);
102 //=======================================================================
103 //function : SelectEdge
104 //purpose : Find the edge <NE> connected <CE> by the vertex <CV> in the list <LE>.
105 // <NE> Is erased of the list. If <CE> is too in the list <LE>
106 // with the same orientation, it's erased of the list
107 //=======================================================================
108 static Standard_Boolean SelectEdge(const TopoDS_Face& F,
109 const TopoDS_Edge& CE,
110 const TopoDS_Vertex& CV,
112 TopTools_ListOfShape& LE)
114 TopTools_ListIteratorOfListOfShape itl;
116 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
117 if (itl.Value().IsEqual(CE)) {
123 if (LE.Extent() > 1) {
124 //--------------------------------------------------------------
125 // Several possible edges.
126 // - Test the edges differents of CE
127 //--------------------------------------------------------------
128 Standard_Real cf, cl, f, l;
129 TopoDS_Face FForward = F;
130 Handle(Geom2d_Curve) Cc, C;
131 FForward.Orientation(TopAbs_FORWARD);
133 Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl);
134 Standard_Real dist,distmin = 100*BRep_Tool::Tolerance(CV);
136 if (CE.Orientation () == TopAbs_FORWARD) uc = cl;
139 gp_Pnt2d P2,PV = Cc->Value(uc);
141 Standard_Real delta = FindDelta(LE,FForward);
143 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
144 const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
146 C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
147 if (E.Orientation () == TopAbs_FORWARD) u = f;
150 dist = PV.Distance(P2);
151 if (dist <= distmin){
158 Standard_Real anglemax = - PI;
159 TopoDS_Edge SelectedEdge;
160 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
161 const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
163 C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
164 if (E.Orientation () == TopAbs_FORWARD) u = f;
167 dist = PV.Distance(P2);
168 if (dist <= distmin + (1./3)*delta){
170 gp_Vec2d CTg1, CTg2, Tg1, Tg2;
171 Cc->D2(uc, PC, CTg1, CTg2);
172 C->D2(u, P, Tg1, Tg2);
176 if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) {
177 angle = CTg1.Angle(Tg1.Reversed());
179 else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) {
180 angle = (CTg1.Reversed()).Angle(Tg1);
182 else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) {
183 angle = CTg1.Angle(Tg1);
185 else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) {
186 angle = (CTg1.Reversed()).Angle(Tg1.Reversed());
188 if (angle >= anglemax) {
195 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
196 const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
197 if (E.IsEqual(SelectedEdge)) {
198 NE = TopoDS::Edge(E);
204 else if (LE.Extent() == 1) {
205 NE = TopoDS::Edge(LE.First());
209 return Standard_False;
211 return Standard_True;
214 //=======================================================================
215 //function : SamePnt2d
217 //=======================================================================
218 static Standard_Boolean SamePnt2d(TopoDS_Vertex V,
223 Standard_Real f1,f2,l1,l2;
225 TopoDS_Shape aLocalF = F.Oriented(TopAbs_FORWARD);
226 TopoDS_Face FF = TopoDS::Face(aLocalF);
227 Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,FF,f1,l1);
228 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,FF,f2,l2);
229 if (E1.Orientation () == TopAbs_FORWARD) P1 = C1->Value(f1);
230 else P1 = C1->Value(l1);
232 if (E2.Orientation () == TopAbs_FORWARD) P2 = C2->Value(l2);
233 else P2 = C2->Value(f2);
234 Standard_Real Tol = 100*BRep_Tool::Tolerance(V);
235 Standard_Real Dist = P1.Distance(P2);
239 //=======================================================================
240 //function : PurgeNewEdges
242 //=======================================================================
243 static void PurgeNewEdges(TopTools_ListOfShape& ConstEdges,
244 const TopTools_MapOfOrientedShape& UsedEdges)
246 TopTools_ListIteratorOfListOfShape it(ConstEdges);
248 const TopoDS_Shape& NE = it.Value();
249 if (!UsedEdges.Contains(NE)) {
250 ConstEdges.Remove(it);
258 //=======================================================================
259 //function : StoreInMVE
261 //=======================================================================
262 static void StoreInMVE (const TopoDS_Face& F,
264 TopTools_DataMapOfShapeListOfShape& MVE )
267 TopoDS_Vertex V1, V2;
268 TopTools_ListOfShape Empty;
270 TopExp::Vertices(E,V1,V2);
271 if (!MVE.IsBound(V1)) {
276 if (!MVE.IsBound(V2)) {
282 //=======================================================================
285 //=======================================================================
286 void Partition_Loop::Perform()
289 TopTools_DataMapOfShapeListOfShape MVE;
290 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit, Mapit1;
291 TopTools_ListIteratorOfListOfShape itl;
294 //-----------------------------------
295 // Construction map vertex => edges
296 //-----------------------------------
297 for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
298 TopoDS_Edge& E = TopoDS::Edge(itl.Value());
299 StoreInMVE(myFace,E,MVE);
302 //----------------------------------------------
303 // Construction of all the wires and of all the new faces.
304 //----------------------------------------------
305 TopTools_MapOfOrientedShape UsedEdges;
307 while (!MVE.IsEmpty()) {
309 TopoDS_Edge CE,NE,EF;
312 Standard_Boolean End= Standard_False;
315 //--------------------------------
317 //--------------------------------
318 Mapit.Initialize(MVE);
319 EF = CE = TopoDS::Edge(Mapit.Value().First());
321 TopExp::Vertices(CE,V1,V2);
322 //--------------------------------
324 //--------------------------------
325 if (CE.Orientation() == TopAbs_FORWARD) {
331 if (!MVE.IsBound(CV)) continue;
332 for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
333 if (itl.Value().IsEqual(CE)) {
341 //-------------------------------
342 // Construction of a wire.
343 //-------------------------------
344 TopExp::Vertices(CE,V1,V2);
345 if (!CV.IsSame(V1)) CV = V1; else CV = V2;
352 if (!MVE.IsBound(CV) || MVE(CV).IsEmpty() || CV.IsSame(VF) ) {
354 if (MVE(CV).Extent() == 1 ) MVE.UnBind(CV);
356 for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
357 if (itl.Value().IsEqual(CE)) {
371 Standard_Boolean find = SelectEdge(myFace,CE,CV,NE,MVE(CV));
374 if (MVE(CV).IsEmpty()) MVE.UnBind(CV);
376 MESSAGE ( " CE is NULL !!! " )
381 MESSAGE ( " edge doesn't exist " )
387 //-----------------------------
388 // Test if the wire is closed
389 //-----------------------------
390 if (VF.IsSame(CV) && SamePnt2d(VF,EF,CE,myFace)) {
393 MESSAGE ( "wire not closed" )
395 myNewWires.Append (NW);
398 PurgeNewEdges(myConstEdges,UsedEdges);
403 //=======================================================================
404 //function : NewWires
406 //=======================================================================
407 const TopTools_ListOfShape& Partition_Loop::NewWires() const
412 //=======================================================================
413 //function : NewFaces
415 //=======================================================================
416 const TopTools_ListOfShape& Partition_Loop::NewFaces() const
421 //=======================================================================
422 //function : WiresToFaces
424 //=======================================================================
425 void Partition_Loop::WiresToFaces()
427 if (!myNewWires.IsEmpty()) {
428 BRepAlgo_FaceRestrictor FR;
430 TopAbs_Orientation OriF = myFace.Orientation();
431 TopoDS_Shape aLocalS = myFace.Oriented(TopAbs_FORWARD);
433 FR.Init (TopoDS::Face(aLocalS),Standard_False);
434 TopTools_ListIteratorOfListOfShape it(myNewWires);
435 for (; it.More(); it.Next()) {
436 FR.Add(TopoDS::Wire(it.Value()));
442 for (; FR.More(); FR.Next()) {
443 myNewFaces.Append(FR.Current().Oriented(OriF));