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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : Partition_Loop.cxx
25 // Author : Benedicte MARTIN
32 #include "Partition_Loop.ixx"
34 #include "utilities.h"
36 #include <BRep_Builder.hxx>
37 #include <BRepAlgo_FaceRestrictor.hxx>
38 #include <BRep_Tool.hxx>
40 #include <Geom2d_Curve.hxx>
41 #include <Geom_Surface.hxx>
43 #include <TopTools_SequenceOfShape.hxx>
44 #include <TopTools_ListIteratorOfListOfShape.hxx>
45 #include <TopTools_MapOfShape.hxx>
46 #include <TopTools_MapIteratorOfMapOfShape.hxx>
47 #include <TopTools_MapOfOrientedShape.hxx>
48 #include <TopTools_DataMapOfShapeShape.hxx>
49 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
52 #include <gp_Pnt2d.hxx>
55 #include <TopoDS_Vertex.hxx>
56 #include <TopoDS_Wire.hxx>
57 #include <TopoDS_Iterator.hxx>
59 #include <Precision.hxx>
60 #include <BRep_TVertex.hxx>
61 #include <BRep_TEdge.hxx>
64 #include <TopExp_Explorer.hxx>
66 static char* name = new char[100];
69 //=======================================================================
70 //function : Partition_Loop
72 //=======================================================================
73 Partition_Loop::Partition_Loop()
77 //=======================================================================
80 //=======================================================================
81 void Partition_Loop::Init(const TopoDS_Face& F)
89 //=======================================================================
90 //function : AddConstEdge
92 //=======================================================================
93 void Partition_Loop::AddConstEdge (const TopoDS_Edge& E)
95 myConstEdges.Append(E);
99 //=======================================================================
100 //function : FindDelta
102 //=======================================================================
103 static Standard_Real FindDelta(TopTools_ListOfShape& LE,
104 const TopoDS_Face& F)
106 Standard_Real dist, f, l;
107 Standard_Real d = Precision::Infinite();
108 TopTools_ListIteratorOfListOfShape itl;
110 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
111 const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
112 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l);
113 gp_Pnt2d p = C->Value(f);
114 gp_Pnt2d pp = C->Value(l);
115 Standard_Real d1 = p.Distance(pp);
122 //=======================================================================
123 //function : SelectEdge
124 //purpose : Find the edge <NE> connected <CE> by the vertex <CV> in the list <LE>.
125 // <NE> Is erased of the list. If <CE> is too in the list <LE>
126 // with the same orientation, it's erased of the list
127 //=======================================================================
128 static Standard_Boolean SelectEdge(const TopoDS_Face& F,
129 const TopoDS_Edge& CE,
130 const TopoDS_Vertex& CV,
132 TopTools_ListOfShape& LE)
134 TopTools_ListIteratorOfListOfShape itl;
136 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
137 if (itl.Value().IsEqual(CE)) {
143 if (LE.Extent() > 1) {
144 //--------------------------------------------------------------
145 // Several possible edges.
146 // - Test the edges differents of CE
147 //--------------------------------------------------------------
148 Standard_Real cf, cl, f, l;
149 TopoDS_Face FForward = F;
150 Handle(Geom2d_Curve) Cc, C;
151 FForward.Orientation(TopAbs_FORWARD);
153 Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl);
154 Standard_Real dist,distmin = 100*BRep_Tool::Tolerance(CV);
156 if (CE.Orientation () == TopAbs_FORWARD) uc = cl;
159 gp_Pnt2d P2,PV = Cc->Value(uc);
161 Standard_Real delta = FindDelta(LE,FForward);
163 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
164 const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
166 C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
167 if (E.Orientation () == TopAbs_FORWARD) u = f;
170 dist = PV.Distance(P2);
171 if (dist <= distmin){
178 Standard_Real anglemax = - PI;
179 TopoDS_Edge SelectedEdge;
180 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
181 const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
183 C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
184 if (E.Orientation () == TopAbs_FORWARD) u = f;
187 dist = PV.Distance(P2);
188 if (dist <= distmin + (1./3)*delta){
190 gp_Vec2d CTg1, CTg2, Tg1, Tg2;
191 Cc->D2(uc, PC, CTg1, CTg2);
192 C->D2(u, P, Tg1, Tg2);
196 if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) {
197 angle = CTg1.Angle(Tg1.Reversed());
199 else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) {
200 angle = (CTg1.Reversed()).Angle(Tg1);
202 else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) {
203 angle = CTg1.Angle(Tg1);
205 else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) {
206 angle = (CTg1.Reversed()).Angle(Tg1.Reversed());
208 if (angle >= anglemax) {
215 for ( itl.Initialize(LE); itl.More(); itl.Next()) {
216 const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
217 if (E.IsEqual(SelectedEdge)) {
218 NE = TopoDS::Edge(E);
224 else if (LE.Extent() == 1) {
225 NE = TopoDS::Edge(LE.First());
229 return Standard_False;
231 return Standard_True;
234 //=======================================================================
235 //function : SamePnt2d
237 //=======================================================================
238 static Standard_Boolean SamePnt2d(TopoDS_Vertex V,
243 Standard_Real f1,f2,l1,l2;
245 TopoDS_Shape aLocalF = F.Oriented(TopAbs_FORWARD);
246 TopoDS_Face FF = TopoDS::Face(aLocalF);
247 Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,FF,f1,l1);
248 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,FF,f2,l2);
249 if (E1.Orientation () == TopAbs_FORWARD) P1 = C1->Value(f1);
250 else P1 = C1->Value(l1);
252 if (E2.Orientation () == TopAbs_FORWARD) P2 = C2->Value(l2);
253 else P2 = C2->Value(f2);
254 Standard_Real Tol = 100*BRep_Tool::Tolerance(V);
255 Standard_Real Dist = P1.Distance(P2);
259 //=======================================================================
260 //function : PurgeNewEdges
262 //=======================================================================
263 static void PurgeNewEdges(TopTools_ListOfShape& ConstEdges,
264 const TopTools_MapOfOrientedShape& UsedEdges)
266 TopTools_ListIteratorOfListOfShape it(ConstEdges);
268 const TopoDS_Shape& NE = it.Value();
269 if (!UsedEdges.Contains(NE)) {
270 ConstEdges.Remove(it);
278 //=======================================================================
279 //function : StoreInMVE
281 //=======================================================================
282 static void StoreInMVE (const TopoDS_Face& F,
284 TopTools_DataMapOfShapeListOfShape& MVE )
287 TopoDS_Vertex V1, V2;
288 TopTools_ListOfShape Empty;
290 TopExp::Vertices(E,V1,V2);
291 if (!MVE.IsBound(V1)) {
296 if (!MVE.IsBound(V2)) {
302 //=======================================================================
305 //=======================================================================
306 void Partition_Loop::Perform()
309 TopTools_DataMapOfShapeListOfShape MVE;
310 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit, Mapit1;
311 TopTools_ListIteratorOfListOfShape itl;
314 //-----------------------------------
315 // Construction map vertex => edges
316 //-----------------------------------
317 for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
318 TopoDS_Edge& E = TopoDS::Edge(itl.Value());
319 StoreInMVE(myFace,E,MVE);
322 //----------------------------------------------
323 // Construction of all the wires and of all the new faces.
324 //----------------------------------------------
325 TopTools_MapOfOrientedShape UsedEdges;
327 while (!MVE.IsEmpty()) {
329 TopoDS_Edge CE,NE,EF;
332 Standard_Boolean End= Standard_False;
335 //--------------------------------
337 //--------------------------------
338 Mapit.Initialize(MVE);
339 EF = CE = TopoDS::Edge(Mapit.Value().First());
341 TopExp::Vertices(CE,V1,V2);
342 //--------------------------------
344 //--------------------------------
345 if (CE.Orientation() == TopAbs_FORWARD) {
351 if (!MVE.IsBound(CV)) continue;
352 for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
353 if (itl.Value().IsEqual(CE)) {
361 //-------------------------------
362 // Construction of a wire.
363 //-------------------------------
364 TopExp::Vertices(CE,V1,V2);
365 if (!CV.IsSame(V1)) CV = V1; else CV = V2;
372 if (!MVE.IsBound(CV) || MVE(CV).IsEmpty() || CV.IsSame(VF) ) {
374 if (MVE(CV).Extent() == 1 ) MVE.UnBind(CV);
376 for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
377 if (itl.Value().IsEqual(CE)) {
391 Standard_Boolean find = SelectEdge(myFace,CE,CV,NE,MVE(CV));
394 if (MVE(CV).IsEmpty()) MVE.UnBind(CV);
396 MESSAGE ( " CE is NULL !!! " )
401 MESSAGE ( " edge doesn't exist " )
407 //-----------------------------
408 // Test if the wire is closed
409 //-----------------------------
410 if (VF.IsSame(CV) && SamePnt2d(VF,EF,CE,myFace)) {
413 MESSAGE ( "wire not closed" )
415 myNewWires.Append (NW);
418 PurgeNewEdges(myConstEdges,UsedEdges);
423 //=======================================================================
424 //function : NewWires
426 //=======================================================================
427 const TopTools_ListOfShape& Partition_Loop::NewWires() const
432 //=======================================================================
433 //function : NewFaces
435 //=======================================================================
436 const TopTools_ListOfShape& Partition_Loop::NewFaces() const
441 //=======================================================================
442 //function : WiresToFaces
444 //=======================================================================
445 void Partition_Loop::WiresToFaces()
447 if (!myNewWires.IsEmpty()) {
448 BRepAlgo_FaceRestrictor FR;
450 TopAbs_Orientation OriF = myFace.Orientation();
451 TopoDS_Shape aLocalS = myFace.Oriented(TopAbs_FORWARD);
453 FR.Init (TopoDS::Face(aLocalS),Standard_False);
454 TopTools_ListIteratorOfListOfShape it(myNewWires);
455 for (; it.More(); it.Next()) {
456 FR.Add(TopoDS::Wire(it.Value()));
462 for (; FR.More(); FR.Next()) {
463 myNewFaces.Append(FR.Current().Oriented(OriF));