1 #ifdef OCCGEOMETRY
2 
3 //  GEOM PARTITION : partition algorithm
4 //
5 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
6 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2.1 of the License.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 //  You should have received a copy of the GNU Lesser General Public
19 //  License along with this library; if not, write to the Free Software
20 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21 //
22 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
23 //
24 //
25 //
26 //  File   : Partition_Loop.cxx
27 //  Author : Benedicte MARTIN
28 //  Module : GEOM
29 //  $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Loop.cxx,v 1.6 2008/03/31 14:20:28 wabro Exp $
30 
31 //using namespace std;
32 #include <cstdio>
33 #include <climits>
34 
35 #include "Partition_Loop.ixx"
36 
37 #include "utilities.h"
38 
39 #include <BRep_Builder.hxx>
40 #include <BRepAlgo_FaceRestrictor.hxx>
41 #include <BRep_Tool.hxx>
42 
43 #include <Geom2d_Curve.hxx>
44 #include <Geom_Surface.hxx>
45 
46 #include <TopTools_SequenceOfShape.hxx>
47 #include <TopTools_ListIteratorOfListOfShape.hxx>
48 #include <TopTools_MapOfShape.hxx>
49 #include <TopTools_MapIteratorOfMapOfShape.hxx>
50 #include <TopTools_MapOfOrientedShape.hxx>
51 #include <TopTools_DataMapOfShapeShape.hxx>
52 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
53 
54 #include <gp_Pnt.hxx>
55 #include <gp_Pnt2d.hxx>
56 
57 #include <TopoDS.hxx>
58 #include <TopoDS_Vertex.hxx>
59 #include <TopoDS_Wire.hxx>
60 #include <TopoDS_Iterator.hxx>
61 
62 #include <Precision.hxx>
63 #include <BRep_TVertex.hxx>
64 #include <BRep_TEdge.hxx>
65 
66 #include <TopExp.hxx>
67 #include <TopExp_Explorer.hxx>
68 
69 static char* name = new char[100];
70 static int nbe = 0;
71 
72 #ifdef WIN32
73 #define M_PI 3.14159265358979323846
74 #endif
75 
76 //=======================================================================
77 //function : Partition_Loop
78 //purpose  :
79 //=======================================================================
Partition_Loop()80 Partition_Loop::Partition_Loop()
81 {
82 }
83 
84 //=======================================================================
85 //function : Init
86 //purpose  :
87 //=======================================================================
Init(const TopoDS_Face & F)88 void Partition_Loop::Init(const TopoDS_Face& F)
89 {
90   myConstEdges.Clear();
91   myNewWires  .Clear();
92   myNewFaces  .Clear();
93   myFace = F;
94 }
95 
96 //=======================================================================
97 //function : AddConstEdge
98 //purpose  :
99 //=======================================================================
AddConstEdge(const TopoDS_Edge & E)100 void Partition_Loop::AddConstEdge (const TopoDS_Edge& E)
101 {
102   myConstEdges.Append(E);
103 }
104 
105 
106 //=======================================================================
107 //function : FindDelta
108 //purpose  :
109 //=======================================================================
FindDelta(TopTools_ListOfShape & LE,const TopoDS_Face & F)110 static Standard_Real FindDelta(TopTools_ListOfShape& LE,
111 			       const TopoDS_Face& F)
112 {
113   Standard_Real dist, f, l;
114   Standard_Real d = Precision::Infinite();
115   TopTools_ListIteratorOfListOfShape itl;
116 
117   for ( itl.Initialize(LE); itl.More(); itl.Next()) {
118     const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
119     Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l);
120     gp_Pnt2d p = C->Value(f);
121     gp_Pnt2d pp = C->Value(l);
122     Standard_Real d1 = p.Distance(pp);
123     if (d1<d) { d=d1;}
124   }
125   dist = d ;
126   return dist;
127 }
128 
129 //=======================================================================
130 //function : SelectEdge
131 //purpose  : Find the edge <NE> connected <CE> by the vertex <CV> in the list <LE>.
132 //           <NE> Is erased  of the list. If <CE> is too in the list <LE>
133 //			 with the same orientation, it's erased of the list
134 //=======================================================================
SelectEdge(const TopoDS_Face & F,const TopoDS_Edge & CE,const TopoDS_Vertex & CV,TopoDS_Edge & NE,TopTools_ListOfShape & LE)135 static Standard_Boolean  SelectEdge(const TopoDS_Face&    F,
136 				    const TopoDS_Edge&    CE,
137 				    const TopoDS_Vertex&  CV,
138 				    TopoDS_Edge&          NE,
139 				    TopTools_ListOfShape& LE)
140 {
141   TopTools_ListIteratorOfListOfShape itl;
142   NE.Nullify();
143   for ( itl.Initialize(LE); itl.More(); itl.Next()) {
144     if (itl.Value().IsEqual(CE)) {
145       LE.Remove(itl);
146       break;
147     }
148   }
149 
150   if (LE.Extent() > 1) {
151     //--------------------------------------------------------------
152     // Several possible edges.
153     // - Test the edge difference of CE
154     //--------------------------------------------------------------
155     Standard_Real   cf, cl, f, l;
156     TopoDS_Face FForward = F;
157     Handle(Geom2d_Curve) Cc, C;
158     FForward.Orientation(TopAbs_FORWARD);
159 
160     Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl);
161     Standard_Real dist,distmin  = 100*BRep_Tool::Tolerance(CV);
162     Standard_Real uc,u;
163     if (CE.Orientation () == TopAbs_FORWARD) uc = cl;
164     else                                     uc = cf;
165 
166     gp_Pnt2d P2,PV = Cc->Value(uc);
167 
168     Standard_Real delta = FindDelta(LE,FForward);
169 
170     for ( itl.Initialize(LE); itl.More(); itl.Next()) {
171       const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
172       if (!E.IsSame(CE)) {
173 	C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
174 	if (E.Orientation () == TopAbs_FORWARD) u = f;
175 	else                                    u = l;
176 	P2 = C->Value(u);
177 	dist = PV.Distance(P2);
178 	if (dist <= distmin){
179 	  distmin = dist;
180 	}
181 
182       }
183     }
184 
185     Standard_Real anglemax = - M_PI;
186     TopoDS_Edge   SelectedEdge;
187     for ( itl.Initialize(LE); itl.More(); itl.Next()) {
188       const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
189       if (!E.IsSame(CE)) {
190 	C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
191 	if (E.Orientation () == TopAbs_FORWARD) u = f;
192 	else                                    u = l;
193 	P2 = C->Value(u);
194 	dist = PV.Distance(P2);
195 	if (dist <= distmin + (1./3)*delta){
196 	  gp_Pnt2d PC, P;
197 	  gp_Vec2d CTg1, CTg2, Tg1, Tg2;
198 	  Cc->D2(uc, PC, CTg1, CTg2);
199 	  C->D2(u, P, Tg1, Tg2);
200 
201 	  Standard_Real angle;
202 
203 	  if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) {
204 	    angle = CTg1.Angle(Tg1.Reversed());
205 	  }
206 	  else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) {
207 	    angle = (CTg1.Reversed()).Angle(Tg1);
208 	  }
209 	  else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) {
210 	    angle = CTg1.Angle(Tg1);
211 	  }
212 	  else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) {
213 	    angle = (CTg1.Reversed()).Angle(Tg1.Reversed());
214 	  }
215 	  if (angle >= anglemax) {
216 	    anglemax = angle ;
217 	    SelectedEdge = E;
218 	  }
219 	}
220       }
221     }
222     for ( itl.Initialize(LE); itl.More(); itl.Next()) {
223       const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
224       if (E.IsEqual(SelectedEdge)) {
225 	NE = TopoDS::Edge(E);
226 	LE.Remove(itl);
227 	break;
228       }
229     }
230   }
231   else if (LE.Extent() == 1) {
232     NE = TopoDS::Edge(LE.First());
233     LE.RemoveFirst();
234   }
235   else {
236     return Standard_False;
237   }
238   return Standard_True;
239 }
240 
241 //=======================================================================
242 //function : SamePnt2d
243 //purpose  :
244 //=======================================================================
SamePnt2d(TopoDS_Vertex V,TopoDS_Edge & E1,TopoDS_Edge & E2,TopoDS_Face & F)245 static Standard_Boolean  SamePnt2d(TopoDS_Vertex  V,
246 				   TopoDS_Edge&   E1,
247 				   TopoDS_Edge&   E2,
248 				   TopoDS_Face&   F)
249 {
250   Standard_Real   f1,f2,l1,l2;
251   gp_Pnt2d        P1,P2;
252   TopoDS_Shape aLocalF = F.Oriented(TopAbs_FORWARD);
253   TopoDS_Face FF = TopoDS::Face(aLocalF);
254   Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,FF,f1,l1);
255   Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,FF,f2,l2);
256   if (E1.Orientation () == TopAbs_FORWARD) P1 = C1->Value(f1);
257   else                                     P1 = C1->Value(l1);
258 
259   if (E2.Orientation () == TopAbs_FORWARD) P2 = C2->Value(l2);
260   else                                     P2 = C2->Value(f2);
261   Standard_Real Tol  = 100*BRep_Tool::Tolerance(V);
262   Standard_Real Dist = P1.Distance(P2);
263   return Dist < Tol;
264 }
265 
266 //=======================================================================
267 //function : PurgeNewEdges
268 //purpose  :
269 //=======================================================================
PurgeNewEdges(TopTools_ListOfShape & ConstEdges,const TopTools_MapOfOrientedShape & UsedEdges)270 static void  PurgeNewEdges(TopTools_ListOfShape& ConstEdges,
271 			   const TopTools_MapOfOrientedShape&          UsedEdges)
272 {
273   TopTools_ListIteratorOfListOfShape it(ConstEdges);
274   while ( it.More()) {
275     const TopoDS_Shape& NE = it.Value();
276     if (!UsedEdges.Contains(NE)) {
277       ConstEdges.Remove(it);
278     }
279     else {
280       it.Next();
281     }
282   }
283 }
284 
285 //=======================================================================
286 //function : StoreInMVE
287 //purpose  :
288 //=======================================================================
StoreInMVE(const TopoDS_Face & F,TopoDS_Edge & E,TopTools_DataMapOfShapeListOfShape & MVE)289 static void StoreInMVE (const TopoDS_Face& F,
290 			TopoDS_Edge& E,
291 			TopTools_DataMapOfShapeListOfShape& MVE )
292 
293 {
294   TopoDS_Vertex V1, V2;
295   TopTools_ListOfShape Empty;
296 
297   TopExp::Vertices(E,V1,V2);
298   if (!MVE.IsBound(V1)) {
299     MVE.Bind(V1,Empty);
300   }
301   MVE(V1).Append(E);
302 
303   if (!MVE.IsBound(V2)) {
304     MVE.Bind(V2,Empty);
305   }
306   MVE(V2).Append(E);
307 }
308 
309 //=======================================================================
310 //function : Perform
311 //purpose  :
312 //=======================================================================
Perform()313 void Partition_Loop::Perform()
314 {
315 
316   TopTools_DataMapOfShapeListOfShape MVE;
317   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit, Mapit1;
318   TopTools_ListIteratorOfListOfShape                  itl;
319   TopoDS_Vertex                                       V1,V2;
320 
321   //-----------------------------------
322   // Construction map vertex => edges
323   //-----------------------------------
324   for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
325     TopoDS_Edge& E = TopoDS::Edge(itl.Value());
326     StoreInMVE(myFace,E,MVE);
327   }
328 
329   //----------------------------------------------
330   // Construction of all the wires and of all the new faces.
331   //----------------------------------------------
332   TopTools_MapOfOrientedShape UsedEdges;
333 
334   while (!MVE.IsEmpty()) {
335     TopoDS_Vertex    VF,CV;
336     TopoDS_Edge      CE,NE,EF;
337     TopoDS_Wire      NW;
338     BRep_Builder     B;
339     Standard_Boolean End= Standard_False;
340 
341     B.MakeWire(NW);
342     //--------------------------------
343     // EF first edge.
344     //--------------------------------
345     Mapit.Initialize(MVE);
346     EF = CE = TopoDS::Edge(Mapit.Value().First());
347 
348     TopExp::Vertices(CE,V1,V2);
349     //--------------------------------
350     // VF first vertex
351     //--------------------------------
352     if (CE.Orientation() == TopAbs_FORWARD) {
353       CV = VF = V1;
354     }
355     else  {
356       CV = VF = V2;
357     }
358     if (!MVE.IsBound(CV)) continue;
359     for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
360       if (itl.Value().IsEqual(CE)) {
361 	MVE(CV).Remove(itl);
362 	break;
363       }
364     }
365 
366     int i = 0;
367     while (!End) {
368       //-------------------------------
369       // Construction of a wire.
370       //-------------------------------
371       TopExp::Vertices(CE,V1,V2);
372       if (!CV.IsSame(V1)) CV = V1; else CV = V2;
373       B.Add (NW,CE);
374       UsedEdges.Add(CE);
375 
376       //--------------
377       // stop test
378       //--------------
379       if (!MVE.IsBound(CV) || MVE(CV).IsEmpty() || CV.IsSame(VF) ) {
380 	if (CV.IsSame(VF)) {
381 	  if (MVE(CV).Extent() == 1 ) MVE.UnBind(CV);
382 	  else {
383 	    for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
384 	      if (itl.Value().IsEqual(CE)) {
385 		MVE(CV).Remove(itl);
386 		break;
387 	      }
388 	    }
389 	  }
390 	}
391 	End=Standard_True;
392       }
393 
394       //--------------
395       // select edge
396       //--------------
397       else {
398 	Standard_Boolean find = SelectEdge(myFace,CE,CV,NE,MVE(CV));
399 	if (find) {
400 	  CE=NE;
401 	  if (MVE(CV).IsEmpty()) MVE.UnBind(CV);
402 	  if (CE.IsNull() ) {
403 	    MESSAGE ( " CE is  NULL !!! " )
404 	    End=Standard_True;
405 	  }
406 	}
407 	else {
408 	  MESSAGE ( " edge doesn't exist " )
409 	  End=Standard_True;
410 	}
411       }
412     }
413 
414     //-----------------------------
415     // Test if the wire is closed
416     //-----------------------------
417     if (VF.IsSame(CV) && SamePnt2d(VF,EF,CE,myFace)) {
418     }
419     else{
420       MESSAGE ( "wire not closed" )
421     }
422     myNewWires.Append (NW);
423   }
424 
425   PurgeNewEdges(myConstEdges,UsedEdges);
426 
427 }
428 
429 
430 //=======================================================================
431 //function : NewWires
432 //purpose  :
433 //=======================================================================
NewWires() const434 const TopTools_ListOfShape&  Partition_Loop::NewWires() const
435 {
436   return myNewWires;
437 }
438 
439 //=======================================================================
440 //function : NewFaces
441 //purpose  :
442 //=======================================================================
NewFaces() const443 const TopTools_ListOfShape&  Partition_Loop::NewFaces() const
444 {
445   return myNewFaces;
446 }
447 
448 //=======================================================================
449 //function : WiresToFaces
450 //purpose  :
451 //=======================================================================
WiresToFaces()452 void  Partition_Loop::WiresToFaces()
453 {
454   if (!myNewWires.IsEmpty()) {
455     BRepAlgo_FaceRestrictor FR;
456 
457     TopAbs_Orientation OriF = myFace.Orientation();
458     TopoDS_Shape aLocalS = myFace.Oriented(TopAbs_FORWARD);
459 
460     FR.Init (TopoDS::Face(aLocalS),Standard_False);
461     TopTools_ListIteratorOfListOfShape it(myNewWires);
462     for (; it.More(); it.Next()) {
463       FR.Add(TopoDS::Wire(it.Value()));
464     }
465 
466     FR.Perform();
467 
468     if (FR.IsDone()) {
469       for (; FR.More(); FR.Next()) {
470 	myNewFaces.Append(FR.Current().Oriented(OriF));
471       }
472     }
473   }
474 }
475 
476 
477 #endif
478