1 // Created on: 1996-01-09
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 // Modified by skv - Mon May 31 12:34:09 2004 OCC5865
24 #include <LocOpe_Spliter.ixx>
26 #include <LocOpe_ProjectedWires.hxx>
28 #include <TopTools_MapOfShape.hxx>
29 #include <TopTools_DataMapOfShapeShape.hxx>
30 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
31 #include <TopTools_ListIteratorOfListOfShape.hxx>
32 #include <TopTools_MapIteratorOfMapOfShape.hxx>
33 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
34 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
35 #include <TopExp_Explorer.hxx>
36 #include <TopoDS_Iterator.hxx>
37 #include <TopoDS_Vertex.hxx>
38 #include <TopoDS_Edge.hxx>
39 #include <TopoDS_Wire.hxx>
40 #include <TopoDS_Face.hxx>
42 #include <LocOpe_BuildWires.hxx>
44 #include <gp_Vec2d.hxx>
46 #include <Geom_Curve.hxx>
47 #include <GeomAPI_ProjectPointOnCurve.hxx>
48 #include <BRep_Tool.hxx>
50 #include <BRepTools_Substitution.hxx>
51 #include <LocOpe_SplitShape.hxx>
53 #include <BRep_Builder.hxx>
58 #include <Standard_ConstructionError.hxx>
61 // Modified by skv - Mon May 31 13:00:30 2004 OCC5865 Begin
62 // static void RebuildWires(TopTools_ListOfShape&);
63 static void RebuildWires(TopTools_ListOfShape&,
64 const Handle(LocOpe_ProjectedWires)&);
65 // Modified by skv - Mon May 31 13:00:31 2004 OCC5865 End
67 static void Put(const TopoDS_Shape&,
68 TopTools_DataMapOfShapeListOfShape&);
70 static void Select(const TopoDS_Edge&,
71 TopTools_ListOfShape&);
74 //=======================================================================
77 //=======================================================================
79 void LocOpe_Spliter::Perform(const Handle(LocOpe_ProjectedWires)& PW)
81 if (myShape.IsNull()) {
82 Standard_NullObject::Raise();
84 myDone = Standard_False;
90 TopTools_MapOfShape mapV,mapE;
91 TopTools_DataMapOfShapeShape EdgOnEdg;
92 TopTools_IndexedDataMapOfShapeListOfShape mapFE;
93 TopExp_Explorer exp,exp2;
95 // 1ere etape : substitution des vertex
98 TopTools_ListOfShape lsubs;
99 BRepTools_Substitution theSubs;
102 for (PW->InitEdgeIterator(); PW->MoreEdge(); PW->NextEdge()) {
103 const TopoDS_Edge& edg = PW->Edge();
105 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
106 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
107 if (!mapV.Contains(vtx)) {
108 if (PW->OnVertex(vtx,Vb)) {
111 TopoDS_Vertex vsub = TopoDS::Vertex(vtx.Oriented(TopAbs_FORWARD));
112 gp_Pnt p1 = BRep_Tool::Pnt(vsub), p2 = BRep_Tool::Pnt(Vb);
113 Standard_Real d = p1.Distance(p2);
114 d = d + BRep_Tool::Tolerance(Vb);
115 BB.UpdateVertex(vsub, d);
117 theSubs.Substitute(Vb.Oriented(TopAbs_FORWARD),lsubs);
124 theSubs.Build(myShape);
125 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdesc(myMap);
126 if (theSubs.IsCopied(myShape)) {
127 // on n`a fait que des substitutions de vertex. Donc chaque element
128 // est remplace par lui meme ou par un seul element du meme type.
129 for (; itdesc.More(); itdesc.Next()) {
130 if (theSubs.IsCopied(itdesc.Key())) {
131 const TopTools_ListOfShape& lsub = theSubs.Copy(itdesc.Key());
133 if (lsub.Extent() != 1) {
134 Standard_ConstructionError::Raise();
137 myMap(itdesc.Key()).Clear();
138 myMap(itdesc.Key()).Append(lsub.First());
143 myRes = myMap(myShape).First();
144 LocOpe_SplitShape theCFace(myRes);
146 // Adds every vertices lying on an edge of the shape, and prepares
147 // work to rebuild wires on each face
151 for (PW->InitEdgeIterator(); PW->MoreEdge(); PW->NextEdge()) {
152 const TopoDS_Edge& edg = PW->Edge();
153 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
154 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
155 if (!mapV.Contains(vtx)) {
157 if (PW->OnEdge(vtx,Ed,prm)) {
158 // on devrait verifier que le vtx n`existe pas deja sur l`edge
159 if(!myMap.IsBound(Ed)) continue;
160 Ed = TopoDS::Edge(myMap(Ed).First());
161 theCFace.Add(vtx,prm,Ed);
166 if (PW->OnEdge(Ebis)) {
167 // Ebis = TopoDS::Edge(myMap(Ebis).First());
168 EdgOnEdg.Bind(edg,Ebis);
171 TopoDS_Face fac = PW->OnFace();
172 if(!myMap.IsBound(fac)) continue;
173 fac = TopoDS::Face(myMap(fac).First());
174 if (!mapFE.Contains(fac)) {
175 TopTools_ListOfShape thelist;
176 mapFE.Add(fac, thelist);
178 mapFE.ChangeFromKey(fac).Append(edg);
182 // Rebuilds wires on each face of the shape
184 TopTools_ListIteratorOfListOfShape itl;
185 for (Standard_Integer i=1; i<=mapFE.Extent(); i++) {
186 const TopoDS_Face& fac = TopoDS::Face(mapFE.FindKey(i));
187 TopTools_ListOfShape& ledges = mapFE(i);
188 // Modified by skv - Mon May 31 12:32:54 2004 OCC5865 Begin
189 // RebuildWires(ledges);
190 RebuildWires(ledges, PW);
191 // Modified by skv - Mon May 31 12:32:54 2004 OCC5865 End
192 for (itl.Initialize(ledges); itl.More(); itl.Next()) {
193 theCFace.Add(TopoDS::Wire(itl.Value()),fac);
198 // Mise a jour des descendants
200 for (itdesc.Reset(); itdesc.More(); itdesc.Next()) {
201 const TopoDS_Shape& sori = itdesc.Key();
202 const TopoDS_Shape& scib = itdesc.Value().First();
203 myMap(sori) = theCFace.DescendantShapes(scib);
206 const TopTools_ListOfShape& lres = myMap(myShape);
208 TopAbs_ShapeEnum typS = myShape.ShapeType();
209 if (typS == TopAbs_FACE && lres.Extent() >=2) {
212 B.MakeShell(TopoDS::Shell(myRes));
213 myRes.Orientation(TopAbs_FORWARD);
214 for (itl.Initialize(lres); itl.More(); itl.Next()) {
215 B.Add(myRes,itl.Value().Oriented(myShape.Orientation()));
218 else if (typS == TopAbs_EDGE && lres.Extent() >=2) {
221 B.MakeWire(TopoDS::Wire(myRes));
222 myRes.Orientation(TopAbs_FORWARD);
223 for (itl.Initialize(lres); itl.More(); itl.Next()) {
224 B.Add(myRes,itl.Value().Oriented(myShape.Orientation()));
228 if (lres.Extent() != 1) {
231 myRes = lres.First();
235 for (TopTools_DataMapIteratorOfDataMapOfShapeShape itee(EdgOnEdg);
238 const TopoDS_Edge& e1 = TopoDS::Edge(itee.Key());
239 // on recherche dans les descendants de e2 l`edge qui correspont a e1
241 TopoDS_Vertex vf1,vl1,vf2,vl2;
242 TopExp::Vertices(e1,vf1,vl1);
244 for (itl.Initialize(myMap(itee.Value()));
247 const TopoDS_Edge& e2 = TopoDS::Edge(itl.Value());
248 TopExp::Vertices(e2,vf2,vl2);
250 if (!vl1.IsSame(vf1)) {
251 if (vf1.IsSame(vf2) && vl1.IsSame(vl2)) {
252 lsubs.Append(e2.Oriented(TopAbs_FORWARD));
255 else if (vf1.IsSame(vl2) && vl1.IsSame(vf2)) {
256 lsubs.Append(e2.Oriented(TopAbs_REVERSED));
260 else { // discrimination sur les tangentes
261 if (vf2.IsSame(vl2) && vl2.IsSame(vl1)) { // tout au meme point
266 Handle(Geom_Curve) C = BRep_Tool::Curve(e1,Loc,f,l);
268 v1.Transform(Loc.Transformation());
270 C = BRep_Tool::Curve(e2,Loc,f,l);
272 v2.Transform(Loc.Transformation());
273 if (v1.Dot(v2) >0.) {
274 lsubs.Append(e2.Oriented(TopAbs_FORWARD));
277 lsubs.Append(e2.Oriented(TopAbs_REVERSED));
283 if (lsubs.Extent() >= 2) { // il faut faire un choix
286 if (lsubs.Extent() == 1) {
287 TopoDS_Shape ebase = lsubs.First();
289 lsubs.Append(e1.Oriented(ebase.Orientation()));
290 theSubs.Substitute(ebase.Oriented(TopAbs_FORWARD),lsubs);
294 cout << "Pb pour substitution" << endl;
299 theSubs.Build(myRes);
301 for (itdesc.Reset(); itdesc.More(); itdesc.Next()) {
302 TopTools_ListOfShape& ldesc = myMap(itdesc.Key());
303 TopTools_ListOfShape newdesc;
304 for (itl.Initialize(ldesc); itl.More(); itl.Next()) {
305 if (theSubs.IsCopied(itl.Value())) {
306 const TopTools_ListOfShape& lsub = theSubs.Copy(itl.Value());
308 if (lsub.Extent() != 1) {
309 Standard_ConstructionError::Raise();
312 newdesc.Append(lsub.First());
315 newdesc.Append(itl.Value());
318 myMap(itdesc.Key()) = newdesc;
321 if (theSubs.IsCopied(myRes)) {
322 myRes = theSubs.Copy(myRes).First();
329 TopTools_MapIteratorOfMapOfShape itms;
331 for (exp.Init(myRes, TopAbs_FACE); exp.More(); exp.Next()) {
332 const TopoDS_Face& fac = TopoDS::Face(exp.Current());
333 for (exp2.Init(fac,TopAbs_EDGE); exp2.More(); exp2.Next()) {
334 const TopoDS_Edge& edg = TopoDS::Edge(exp2.Current());
335 for (itms.Initialize(mapE);
336 itms.More(); itms.Next()) {
337 if (itms.Key().IsSame(edg) &&
338 edg.Orientation() == itms.Key().Orientation()) {
355 /* JAG : Ne peut pas marcher
357 Standard_Boolean full = mapV.IsEmpty();
359 full = Standard_True;
360 itms.Initialize(mapV);
361 const TopoDS_Face& fac = TopoDS::Face(itms.Key());
362 for (exp.Init(fac,TopAbs_EDGE); exp.More(); exp.Next()) {
363 if (!mapE.Contains(exp.Current())) {
364 for (itl.Initialize(myLeft); itl.More(); itl.Next()) {
365 const TopoDS_Face& fac2 = TopoDS::Face(itl.Value());
366 for (exp2.Init(fac2,TopAbs_EDGE); exp2.More(); exp2.Next()) {
367 if (exp2.Current().IsSame(exp.Current())) {
370 full = mapV.IsEmpty();
386 // Map des edges ou les connexions sont possibles
387 TopTools_MapOfShape Mapebord;
388 for (itl.Initialize(myLeft); itl.More(); itl.Next()) {
389 for (exp.Init(itl.Value(),TopAbs_EDGE); exp.More(); exp.Next()) {
390 if (!mapE.Contains(exp.Current())) {
391 if (!Mapebord.Add(exp.Current())) {
392 Mapebord.Remove(exp.Current());
399 while (Mapebord.Extent() != 0) {
400 itms.Initialize(Mapebord);
401 TopoDS_Shape edg = itms.Key();
403 for (itms.Initialize(mapV); itms.More(); itms.Next()) {
404 const TopoDS_Shape& fac = itms.Key();
405 for (exp.Init(fac,TopAbs_EDGE); exp.More(); exp.Next()) {
406 if (exp.Current().IsSame(edg)) {
411 break; // face a gauche
415 TopoDS_Shape fac = itms.Key();
416 for (exp.Init(fac,TopAbs_EDGE); exp.More(); exp.Next()) {
417 if (!Mapebord.Add(exp.Current())) {
418 Mapebord.Remove(exp.Current());
425 Mapebord.Remove(edg);
429 myDone = Standard_True;
433 //=======================================================================
434 //function : DescendantShapes
436 //=======================================================================
438 const TopTools_ListOfShape& LocOpe_Spliter::
439 DescendantShapes(const TopoDS_Shape& F)
441 if (!myDone) {StdFail_NotDone::Raise();}
442 if (myMap.IsBound(F))
445 static TopTools_ListOfShape empty;
451 //=======================================================================
452 //function : DirectLeft
454 //=======================================================================
456 const TopTools_ListOfShape& LocOpe_Spliter::DirectLeft() const
458 if (!myDone) {StdFail_NotDone::Raise();}
464 //=======================================================================
467 //=======================================================================
469 const TopTools_ListOfShape& LocOpe_Spliter::Left() const
471 if (!myDone) {StdFail_NotDone::Raise();}
477 //=======================================================================
478 //function : RebuildWires
480 //=======================================================================
482 // Modified by skv - Mon May 31 12:31:39 2004 OCC5865 Begin
483 //static void RebuildWires(TopTools_ListOfShape& ledge)
484 static void RebuildWires(TopTools_ListOfShape& ledge,
485 const Handle(LocOpe_ProjectedWires)& PW)
487 LocOpe_BuildWires theBuild(ledge, PW);
488 // Modified by skv - Mon May 31 12:31:40 2004 OCC5865 End
489 if (!theBuild.IsDone()) {
490 Standard_ConstructionError::Raise();
492 ledge = theBuild.Result();
499 //=======================================================================
502 //=======================================================================
504 static void Put(const TopoDS_Shape& S,
505 TopTools_DataMapOfShapeListOfShape& theMap)
507 if (theMap.IsBound(S)) {
510 TopTools_ListOfShape thelist;
511 theMap.Bind(S, thelist);
513 for (TopoDS_Iterator it(S); it.More(); it.Next()) {
514 Put(it.Value(),theMap);
519 //=======================================================================
522 //=======================================================================
524 static void Select(const TopoDS_Edge& Ebase,
525 TopTools_ListOfShape& lsubs)
530 Handle(Geom_Curve) C;
532 Standard_Real f,l,dmin = RealLast();
533 Standard_Integer i=0,imin = 0;
535 C = BRep_Tool::Curve(Ebase,Loc,f,l);
537 if (!Loc.IsIdentity()) {
538 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
539 C = *((Handle(Geom_Curve)*)&GG);
541 gp_Pnt Pt(C->Value((f+l)/2.));
543 GeomAPI_ProjectPointOnCurve proj;
544 // for (TopTools_ListIteratorOfListOfShape itl(lsubs);
545 TopTools_ListIteratorOfListOfShape itl(lsubs);
546 for ( ;itl.More();itl.Next()) {
548 const TopoDS_Edge& edg = TopoDS::Edge(itl.Value());
549 C = BRep_Tool::Curve(edg,Loc,f,l);
550 if (!Loc.IsIdentity()) {
551 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
552 C = *((Handle(Geom_Curve)*)&GG);
555 if (proj.NbPoints() > 0) {
556 if (proj.LowerDistance() < dmin) {
558 dmin = proj.LowerDistance();
566 itl.Initialize(lsubs);