PageRenderTime 55ms CodeModel.GetById 13ms app.highlight 36ms RepoModel.GetById 1ms app.codeStats 0ms

/src/contrib/geom-5.1.2.7/src/Partition/Partition_Loop.cpp

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