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