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 TopTools_MapOfShape theFacesWithSection;
152 for (PW->InitEdgeIterator(); PW->MoreEdge(); PW->NextEdge()) {
153 const TopoDS_Edge& edg = PW->Edge();
154 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
155 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
156 if (!mapV.Contains(vtx)) {
158 if (PW->OnEdge(vtx,Ed,prm)) {
159 // on devrait verifier que le vtx n`existe pas deja sur l`edge
160 if(!myMap.IsBound(Ed)) continue;
161 Ed = TopoDS::Edge(myMap(Ed).First());
162 theCFace.Add(vtx,prm,Ed);
167 if (PW->OnEdge(Ebis)) {
168 // Ebis = TopoDS::Edge(myMap(Ebis).First());
169 EdgOnEdg.Bind(edg,Ebis);
172 TopoDS_Face fac = PW->OnFace();
173 if(!myMap.IsBound(fac)) continue;
174 Standard_Boolean IsFaceWithSec = PW->IsFaceWithSection(fac);
175 fac = TopoDS::Face(myMap(fac).First());
177 theFacesWithSection.Add(fac);
178 if (!mapFE.Contains(fac)) {
179 TopTools_ListOfShape thelist;
180 mapFE.Add(fac, thelist);
182 mapFE.ChangeFromKey(fac).Append(edg);
186 // Rebuilds wires on each face of the shape
188 TopTools_ListIteratorOfListOfShape itl;
189 for (Standard_Integer i=1; i<=mapFE.Extent(); i++) {
190 const TopoDS_Face& fac = TopoDS::Face(mapFE.FindKey(i));
191 TopTools_ListOfShape& ledges = mapFE(i);
192 // Modified by skv - Mon May 31 12:32:54 2004 OCC5865 Begin
193 // RebuildWires(ledges);
194 RebuildWires(ledges, PW);
195 // Modified by skv - Mon May 31 12:32:54 2004 OCC5865 End
196 if (theFacesWithSection.Contains(fac))
197 theCFace.Add(ledges, fac);
199 for (itl.Initialize(ledges); itl.More(); itl.Next())
200 theCFace.Add(TopoDS::Wire(itl.Value()),fac);
204 // Mise a jour des descendants
206 for (itdesc.Reset(); itdesc.More(); itdesc.Next()) {
207 const TopoDS_Shape& sori = itdesc.Key();
208 const TopoDS_Shape& scib = itdesc.Value().First();
209 myMap(sori) = theCFace.DescendantShapes(scib);
212 const TopTools_ListOfShape& lres = myMap(myShape);
214 TopAbs_ShapeEnum typS = myShape.ShapeType();
215 if (typS == TopAbs_FACE && lres.Extent() >=2) {
218 B.MakeShell(TopoDS::Shell(myRes));
219 myRes.Orientation(TopAbs_FORWARD);
220 for (itl.Initialize(lres); itl.More(); itl.Next()) {
221 B.Add(myRes,itl.Value().Oriented(myShape.Orientation()));
224 else if (typS == TopAbs_EDGE && lres.Extent() >=2) {
227 B.MakeWire(TopoDS::Wire(myRes));
228 myRes.Orientation(TopAbs_FORWARD);
229 for (itl.Initialize(lres); itl.More(); itl.Next()) {
230 B.Add(myRes,itl.Value().Oriented(myShape.Orientation()));
234 if (lres.Extent() != 1) {
237 myRes = lres.First();
241 for (TopTools_DataMapIteratorOfDataMapOfShapeShape itee(EdgOnEdg);
244 const TopoDS_Edge& e1 = TopoDS::Edge(itee.Key());
245 // on recherche dans les descendants de e2 l`edge qui correspont a e1
247 TopoDS_Vertex vf1,vl1,vf2,vl2;
248 TopExp::Vertices(e1,vf1,vl1);
250 for (itl.Initialize(myMap(itee.Value()));
253 const TopoDS_Edge& e2 = TopoDS::Edge(itl.Value());
254 TopExp::Vertices(e2,vf2,vl2);
256 if (!vl1.IsSame(vf1)) {
257 if (vf1.IsSame(vf2) && vl1.IsSame(vl2)) {
258 lsubs.Append(e2.Oriented(TopAbs_FORWARD));
261 else if (vf1.IsSame(vl2) && vl1.IsSame(vf2)) {
262 lsubs.Append(e2.Oriented(TopAbs_REVERSED));
266 else { // discrimination sur les tangentes
267 if (vf2.IsSame(vl2) && vl2.IsSame(vl1)) { // tout au meme point
272 Handle(Geom_Curve) C = BRep_Tool::Curve(e1,Loc,f,l);
274 v1.Transform(Loc.Transformation());
276 C = BRep_Tool::Curve(e2,Loc,f,l);
278 v2.Transform(Loc.Transformation());
279 if (v1.Dot(v2) >0.) {
280 lsubs.Append(e2.Oriented(TopAbs_FORWARD));
283 lsubs.Append(e2.Oriented(TopAbs_REVERSED));
289 if (lsubs.Extent() >= 2) { // il faut faire un choix
292 if (lsubs.Extent() == 1) {
293 TopoDS_Shape ebase = lsubs.First();
295 lsubs.Append(e1.Oriented(ebase.Orientation()));
296 theSubs.Substitute(ebase.Oriented(TopAbs_FORWARD),lsubs);
300 cout << "Pb pour substitution" << endl;
305 theSubs.Build(myRes);
307 for (itdesc.Reset(); itdesc.More(); itdesc.Next()) {
308 TopTools_ListOfShape& ldesc = myMap(itdesc.Key());
309 TopTools_ListOfShape newdesc;
310 for (itl.Initialize(ldesc); itl.More(); itl.Next()) {
311 if (theSubs.IsCopied(itl.Value())) {
312 const TopTools_ListOfShape& lsub = theSubs.Copy(itl.Value());
314 if (lsub.Extent() != 1) {
315 Standard_ConstructionError::Raise();
318 newdesc.Append(lsub.First());
321 newdesc.Append(itl.Value());
324 myMap(itdesc.Key()) = newdesc;
327 if (theSubs.IsCopied(myRes)) {
328 myRes = theSubs.Copy(myRes).First();
335 TopTools_MapIteratorOfMapOfShape itms;
337 for (exp.Init(myRes, TopAbs_FACE); exp.More(); exp.Next()) {
338 const TopoDS_Face& fac = TopoDS::Face(exp.Current());
339 for (exp2.Init(fac,TopAbs_EDGE); exp2.More(); exp2.Next()) {
340 const TopoDS_Edge& edg = TopoDS::Edge(exp2.Current());
341 for (itms.Initialize(mapE);
342 itms.More(); itms.Next()) {
343 if (itms.Key().IsSame(edg) &&
344 edg.Orientation() == itms.Key().Orientation()) {
361 /* JAG : Ne peut pas marcher
363 Standard_Boolean full = mapV.IsEmpty();
365 full = Standard_True;
366 itms.Initialize(mapV);
367 const TopoDS_Face& fac = TopoDS::Face(itms.Key());
368 for (exp.Init(fac,TopAbs_EDGE); exp.More(); exp.Next()) {
369 if (!mapE.Contains(exp.Current())) {
370 for (itl.Initialize(myLeft); itl.More(); itl.Next()) {
371 const TopoDS_Face& fac2 = TopoDS::Face(itl.Value());
372 for (exp2.Init(fac2,TopAbs_EDGE); exp2.More(); exp2.Next()) {
373 if (exp2.Current().IsSame(exp.Current())) {
376 full = mapV.IsEmpty();
392 // Map des edges ou les connexions sont possibles
393 TopTools_MapOfShape Mapebord;
394 for (itl.Initialize(myLeft); itl.More(); itl.Next()) {
395 for (exp.Init(itl.Value(),TopAbs_EDGE); exp.More(); exp.Next()) {
396 if (!mapE.Contains(exp.Current())) {
397 if (!Mapebord.Add(exp.Current())) {
398 Mapebord.Remove(exp.Current());
405 while (Mapebord.Extent() != 0) {
406 itms.Initialize(Mapebord);
407 TopoDS_Shape edg = itms.Key();
409 for (itms.Initialize(mapV); itms.More(); itms.Next()) {
410 const TopoDS_Shape& fac = itms.Key();
411 for (exp.Init(fac,TopAbs_EDGE); exp.More(); exp.Next()) {
412 if (exp.Current().IsSame(edg)) {
417 break; // face a gauche
421 TopoDS_Shape fac = itms.Key();
422 for (exp.Init(fac,TopAbs_EDGE); exp.More(); exp.Next()) {
423 if (!Mapebord.Add(exp.Current())) {
424 Mapebord.Remove(exp.Current());
431 Mapebord.Remove(edg);
435 myDone = Standard_True;
439 //=======================================================================
440 //function : DescendantShapes
442 //=======================================================================
444 const TopTools_ListOfShape& LocOpe_Spliter::
445 DescendantShapes(const TopoDS_Shape& F)
447 if (!myDone) {StdFail_NotDone::Raise();}
448 if (myMap.IsBound(F))
451 static TopTools_ListOfShape empty;
457 //=======================================================================
458 //function : DirectLeft
460 //=======================================================================
462 const TopTools_ListOfShape& LocOpe_Spliter::DirectLeft() const
464 if (!myDone) {StdFail_NotDone::Raise();}
470 //=======================================================================
473 //=======================================================================
475 const TopTools_ListOfShape& LocOpe_Spliter::Left() const
477 if (!myDone) {StdFail_NotDone::Raise();}
483 //=======================================================================
484 //function : RebuildWires
486 //=======================================================================
488 // Modified by skv - Mon May 31 12:31:39 2004 OCC5865 Begin
489 //static void RebuildWires(TopTools_ListOfShape& ledge)
490 static void RebuildWires(TopTools_ListOfShape& ledge,
491 const Handle(LocOpe_ProjectedWires)& PW)
493 LocOpe_BuildWires theBuild(ledge, PW);
494 // Modified by skv - Mon May 31 12:31:40 2004 OCC5865 End
495 if (!theBuild.IsDone()) {
496 Standard_ConstructionError::Raise();
498 ledge = theBuild.Result();
505 //=======================================================================
508 //=======================================================================
510 static void Put(const TopoDS_Shape& S,
511 TopTools_DataMapOfShapeListOfShape& theMap)
513 if (theMap.IsBound(S)) {
516 TopTools_ListOfShape thelist;
517 theMap.Bind(S, thelist);
519 for (TopoDS_Iterator it(S); it.More(); it.Next()) {
520 Put(it.Value(),theMap);
525 //=======================================================================
528 //=======================================================================
530 static void Select(const TopoDS_Edge& Ebase,
531 TopTools_ListOfShape& lsubs)
536 Handle(Geom_Curve) C;
538 Standard_Real f,l,dmin = RealLast();
539 Standard_Integer i=0,imin = 0;
541 C = BRep_Tool::Curve(Ebase,Loc,f,l);
543 if (!Loc.IsIdentity()) {
544 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
545 C = *((Handle(Geom_Curve)*)&GG);
547 gp_Pnt Pt(C->Value((f+l)/2.));
549 GeomAPI_ProjectPointOnCurve proj;
550 // for (TopTools_ListIteratorOfListOfShape itl(lsubs);
551 TopTools_ListIteratorOfListOfShape itl(lsubs);
552 for ( ;itl.More();itl.Next()) {
554 const TopoDS_Edge& edg = TopoDS::Edge(itl.Value());
555 C = BRep_Tool::Curve(edg,Loc,f,l);
556 if (!Loc.IsIdentity()) {
557 Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation());
558 C = *((Handle(Geom_Curve)*)&GG);
561 if (proj.NbPoints() > 0) {
562 if (proj.LowerDistance() < dmin) {
564 dmin = proj.LowerDistance();
572 itl.Initialize(lsubs);