1 // GEOM PARTITION : partition algorithm
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
24 // File : Partition_Loop.cxx
25 // Author : Benedicte MARTIN
31 #include "Partition_Loop.ixx"
33 #include "utilities.h"
35 #include <BRep_Builder.hxx>
36 #include <BRepAlgo_FaceRestrictor.hxx>
37 #include <BRep_Tool.hxx>
39 #include <Geom2d_Curve.hxx>
40 #include <Geom_Surface.hxx>
42 #include <TopTools_SequenceOfShape.hxx>
43 #include <TopTools_ListIteratorOfListOfShape.hxx>
44 #include <TopTools_MapOfShape.hxx>
45 #include <TopTools_MapIteratorOfMapOfShape.hxx>
46 #include <TopTools_MapOfOrientedShape.hxx>
47 #include <TopTools_DataMapOfShapeShape.hxx>
48 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
51 #include <gp_Pnt2d.hxx>
54 #include <TopoDS_Vertex.hxx>
55 #include <TopoDS_Wire.hxx>
56 #include <TopoDS_Iterator.hxx>
58 #include <Precision.hxx>
59 #include <BRep_TVertex.hxx>
60 #include <BRep_TEdge.hxx>
63 #include <TopExp_Explorer.hxx>
67 static char* name = new char[100];
70 //=======================================================================
71 //function : Partition_Loop
73 //=======================================================================
74 Partition_Loop::Partition_Loop()
78 //=======================================================================
81 //=======================================================================
82 void Partition_Loop::Init(const TopoDS_Face& F)
90 //=======================================================================
91 //function : AddConstEdge
93 //=======================================================================
94 void Partition_Loop::AddConstEdge (const TopoDS_Edge& E)
96 myConstEdges.Append(E);
100 //=======================================================================
101 //function : FindDelta
103 //=======================================================================
104 static Standard_Real FindDelta(TopTools_ListOfShape& LE,
105 const TopoDS_Face& F)
107 Standard_Real dist, f, l;
108 Standard_Real d = Precision::Infinite();
109 TopTools_ListIteratorOfListOfShape itl;
111 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
112 const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
113 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l);
114 gp_Pnt2d p = C->Value(f);
115 gp_Pnt2d pp = C->Value(l);
116 Standard_Real d1 = p.Distance(pp);
123 //=======================================================================
124 //function : SelectEdge
125 //purpose : Find the edge <NE> connected <CE> by the vertex <CV> in the list <LE>.
126 // <NE> Is erased of the list. If <CE> is too in the list <LE>
127 // with the same orientation, it's erased of the list
128 //=======================================================================
129 static Standard_Boolean SelectEdge(const TopoDS_Face& F,
130 const TopoDS_Edge& CE,
131 const TopoDS_Vertex& CV,
133 TopTools_ListOfShape& LE)
135 TopTools_ListIteratorOfListOfShape itl;
137 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
138 if (itl.Value().IsEqual(CE)) {
144 if (LE.Extent() > 1) {
145 //--------------------------------------------------------------
146 // Several possible edges.
147 // - Test the edges differents of CE
148 //--------------------------------------------------------------
149 Standard_Real cf, cl, f, l;
150 TopoDS_Face FForward = F;
151 Handle(Geom2d_Curve) Cc, C;
152 FForward.Orientation(TopAbs_FORWARD);
154 Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl);
155 Standard_Real dist,distmin = 100*BRep_Tool::Tolerance(CV);
157 if (CE.Orientation () == TopAbs_FORWARD) uc = cl;
160 gp_Pnt2d P2,PV = Cc->Value(uc);
162 Standard_Real delta = FindDelta(LE,FForward);
164 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
165 const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
167 C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
168 if (E.Orientation () == TopAbs_FORWARD) u = f;
171 dist = PV.Distance(P2);
172 if (dist <= distmin){
179 Standard_Real anglemax = - PI;
180 TopoDS_Edge SelectedEdge;
181 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
182 const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
184 C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
185 if (E.Orientation () == TopAbs_FORWARD) u = f;
188 dist = PV.Distance(P2);
189 if (dist <= distmin + (1./3)*delta){
191 gp_Vec2d CTg1, CTg2, Tg1, Tg2;
192 Cc->D2(uc, PC, CTg1, CTg2);
193 C->D2(u, P, Tg1, Tg2);
197 if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) {
198 angle = CTg1.Angle(Tg1.Reversed());
200 else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) {
201 angle = (CTg1.Reversed()).Angle(Tg1);
203 else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) {
204 angle = CTg1.Angle(Tg1);
206 else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) {
207 angle = (CTg1.Reversed()).Angle(Tg1.Reversed());
209 if (angle >= anglemax) {
216 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
217 const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
218 if (E.IsEqual(SelectedEdge)) {
219 NE = TopoDS::Edge(E);
225 else if (LE.Extent() == 1) {
226 NE = TopoDS::Edge(LE.First());
230 return Standard_False;
232 return Standard_True;
235 //=======================================================================
236 //function : SamePnt2d
238 //=======================================================================
239 static Standard_Boolean SamePnt2d(TopoDS_Vertex V,
244 Standard_Real f1,f2,l1,l2;
246 TopoDS_Shape aLocalF = F.Oriented(TopAbs_FORWARD);
247 TopoDS_Face FF = TopoDS::Face(aLocalF);
248 Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,FF,f1,l1);
249 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,FF,f2,l2);
250 if (E1.Orientation () == TopAbs_FORWARD) P1 = C1->Value(f1);
251 else P1 = C1->Value(l1);
253 if (E2.Orientation () == TopAbs_FORWARD) P2 = C2->Value(l2);
254 else P2 = C2->Value(f2);
255 Standard_Real Tol = 100*BRep_Tool::Tolerance(V);
256 Standard_Real Dist = P1.Distance(P2);
260 //=======================================================================
261 //function : PurgeNewEdges
263 //=======================================================================
264 static void PurgeNewEdges(TopTools_ListOfShape& ConstEdges,
265 const TopTools_MapOfOrientedShape& UsedEdges)
267 TopTools_ListIteratorOfListOfShape it(ConstEdges);
269 const TopoDS_Shape& NE = it.Value();
270 if (!UsedEdges.Contains(NE)) {
271 ConstEdges.Remove(it);
279 //=======================================================================
280 //function : StoreInMVE
282 //=======================================================================
283 static void StoreInMVE (const TopoDS_Face& F,
285 TopTools_DataMapOfShapeListOfShape& MVE )
288 TopoDS_Vertex V1, V2;
289 TopTools_ListOfShape Empty;
291 TopExp::Vertices(E,V1,V2);
292 if (!MVE.IsBound(V1)) {
297 if (!MVE.IsBound(V2)) {
303 //=======================================================================
306 //=======================================================================
307 void Partition_Loop::Perform()
310 TopTools_DataMapOfShapeListOfShape MVE;
311 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit, Mapit1;
312 TopTools_ListIteratorOfListOfShape itl;
315 //-----------------------------------
316 // Construction map vertex => edges
317 //-----------------------------------
318 for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
319 TopoDS_Edge& E = TopoDS::Edge(itl.Value());
320 StoreInMVE(myFace,E,MVE);
323 //----------------------------------------------
324 // Construction of all the wires and of all the new faces.
325 //----------------------------------------------
326 TopTools_MapOfOrientedShape UsedEdges;
328 while (!MVE.IsEmpty()) {
330 TopoDS_Edge CE,NE,EF;
333 Standard_Boolean End= Standard_False;
336 //--------------------------------
338 //--------------------------------
339 Mapit.Initialize(MVE);
340 EF = CE = TopoDS::Edge(Mapit.Value().First());
342 TopExp::Vertices(CE,V1,V2);
343 //--------------------------------
345 //--------------------------------
346 if (CE.Orientation() == TopAbs_FORWARD) {
352 if (!MVE.IsBound(CV)) continue;
353 for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
354 if (itl.Value().IsEqual(CE)) {
362 //-------------------------------
363 // Construction of a wire.
364 //-------------------------------
365 TopExp::Vertices(CE,V1,V2);
366 if (!CV.IsSame(V1)) CV = V1; else CV = V2;
373 if (!MVE.IsBound(CV) || MVE(CV).IsEmpty() || CV.IsSame(VF) ) {
375 if (MVE(CV).Extent() == 1 ) MVE.UnBind(CV);
377 for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
378 if (itl.Value().IsEqual(CE)) {
392 Standard_Boolean find = SelectEdge(myFace,CE,CV,NE,MVE(CV));
395 if (MVE(CV).IsEmpty()) MVE.UnBind(CV);
397 MESSAGE ( " CE is NULL !!! " )
402 MESSAGE ( " edge doesn't exist " )
408 //-----------------------------
409 // Test if the wire is closed
410 //-----------------------------
411 if (VF.IsSame(CV) && SamePnt2d(VF,EF,CE,myFace)) {
414 MESSAGE ( "wire not closed" )
416 myNewWires.Append (NW);
419 PurgeNewEdges(myConstEdges,UsedEdges);
424 //=======================================================================
425 //function : NewWires
427 //=======================================================================
428 const TopTools_ListOfShape& Partition_Loop::NewWires() const
433 //=======================================================================
434 //function : NewFaces
436 //=======================================================================
437 const TopTools_ListOfShape& Partition_Loop::NewFaces() const
442 //=======================================================================
443 //function : WiresToFaces
445 //=======================================================================
446 void Partition_Loop::WiresToFaces()
448 if (!myNewWires.IsEmpty()) {
449 BRepAlgo_FaceRestrictor FR;
451 TopAbs_Orientation OriF = myFace.Orientation();
452 TopoDS_Shape aLocalS = myFace.Oriented(TopAbs_FORWARD);
454 FR.Init (TopoDS::Face(aLocalS),Standard_False);
455 TopTools_ListIteratorOfListOfShape it(myNewWires);
456 for (; it.More(); it.Next()) {
457 FR.Add(TopoDS::Wire(it.Value()));
463 for (; FR.More(); FR.Next()) {
464 myNewFaces.Append(FR.Current().Oriented(OriF));