0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_FaceBuilder.cxx
1 // Created on: 1996-01-05
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <gp_Pnt.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <Precision.hxx>
23 #include <Standard_ProgramError.hxx>
24 #include <TopAbs_Orientation.hxx>
25 #include <TopExp.hxx>
26 #include <TopoDS.hxx>
27 #include <TopoDS_Compound.hxx>
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Face.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <TopoDS_Vertex.hxx>
32 #include <TopOpeBRepBuild_BlockBuilder.hxx>
33 #include <TopOpeBRepBuild_define.hxx>
34 #include <TopOpeBRepBuild_FaceBuilder.hxx>
35 #include <TopOpeBRepBuild_Loop.hxx>
36 #include <TopOpeBRepBuild_LoopSet.hxx>
37 #include <TopOpeBRepBuild_ShapeSet.hxx>
38 #include <TopOpeBRepBuild_WireEdgeClassifier.hxx>
39 #include <TopOpeBRepBuild_WireEdgeSet.hxx>
40 #include <TopOpeBRepDS_BuildTool.hxx>
41 #include <TopTools_Array1OfShape.hxx>
42 #include <TopTools_DataMapOfShapeInteger.hxx>
43 #include <TopTools_DataMapOfShapeListOfShape.hxx>
44 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
45 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
46 #include <TopTools_IndexedMapOfOrientedShape.hxx>
47 #include <TopTools_IndexedMapOfShape.hxx>
48 #include <TopTools_ListOfShape.hxx>
49
50 //#include <BRepAdaptor_Curve2d.hxx>
51 #undef RM_HANGING
52 // MSV: RM_HANGING behaviour: when state of wire is UNCLOSEDW we do not
53 // remove the whole wire but remove the chains of hanging edges. This would
54 // produce a good result in some cases. But :-( it gives regressions on grid
55 // tests (1cto 021 W4,X4). Therefore I leaved this code not active.
56 #ifdef RM_HANGING
57 #include <TColStd_ListIteratorOfListOfInteger.hxx>
58 #endif
59
60 #ifdef OCCT_DEBUG
61 extern Standard_Boolean TopOpeBRepBuild_GettracePURGE();
62 void debifb() {}
63 #endif
64
65 #ifdef DRAW
66 #include <TopOpeBRepTool_DRAW.hxx>
67 #endif
68
69 //=======================================================================
70 //function : TopOpeBRepBuild_FaceBuilder
71 //purpose  : 
72 //=======================================================================
73 TopOpeBRepBuild_FaceBuilder::TopOpeBRepBuild_FaceBuilder()
74 {
75 }
76
77 //=======================================================================
78 //function : TopOpeBRepBuild_FaceBuilder
79 //purpose  : 
80 //=======================================================================
81 TopOpeBRepBuild_FaceBuilder::TopOpeBRepBuild_FaceBuilder(TopOpeBRepBuild_WireEdgeSet& WES,const TopoDS_Shape& F,const Standard_Boolean ForceClass)
82 {
83   InitFaceBuilder(WES,F,ForceClass);
84 }
85
86 //=======================================================================
87 //function : InitFaceBuilder
88 //purpose  : 
89 //=======================================================================
90 void TopOpeBRepBuild_FaceBuilder::InitFaceBuilder(TopOpeBRepBuild_WireEdgeSet& WES,const TopoDS_Shape& F,const Standard_Boolean ForceClass) 
91 {
92   myFace = TopoDS::Face(F);
93   MakeLoops(WES);
94   TopOpeBRepBuild_BlockBuilder& BB = myBlockBuilder;
95   TopOpeBRepBuild_WireEdgeClassifier WEC(F,BB);
96   TopOpeBRepBuild_LoopSet& LS = myLoopSet;
97   myFaceAreaBuilder.InitFaceAreaBuilder(LS,WEC,ForceClass);
98 }
99
100 //---------------------------------------------------------------
101 void FUN_DetectVerticesOn1Edge(const TopoDS_Shape& W,TopTools_IndexedDataMapOfShapeShape& mapVon1E)
102 {
103   // Fills the map <mapVon1edge>,with vertices of <W> of 3d connexity 1.
104   TopTools_IndexedDataMapOfShapeListOfShape mapVedges;
105   TopExp::MapShapesAndAncestors(W,TopAbs_VERTEX,TopAbs_EDGE,mapVedges);
106   Standard_Integer nV = mapVedges.Extent();
107
108   for (Standard_Integer i = 1;i <= nV;i++) {
109     const TopoDS_Shape& V = mapVedges.FindKey(i);
110     if (V.Orientation() == TopAbs_INTERNAL) continue;
111
112     const TopTools_ListOfShape& loE = mapVedges.FindFromIndex(i);
113     if (loE.Extent() < 2) {
114       // Keeping INTERNAL or EXTERNAL edges
115       const TopoDS_Shape& E = loE.First();
116       TopAbs_Orientation oriE = E.Orientation();
117       if ((oriE == TopAbs_INTERNAL) || (oriE == TopAbs_EXTERNAL)) continue;
118       mapVon1E.Add(V,E);
119     }
120   }
121
122
123 #define ISUNKNOWN -1
124 #define ISVERTEX  0
125 #define GCLOSEDW  1
126 #define UNCLOSEDW 2
127 #define CLOSEDW   10
128 Standard_Integer FUN_AnalyzemapVon1E(const TopTools_IndexedDataMapOfShapeShape& mapVon1E,
129                         TopTools_IndexedDataMapOfShapeShape& mapVV)
130 {
131 #ifdef DRAW
132   Standard_Boolean trc = TopOpeBRepBuild_GettracePURGE();
133   if (trc) cout<<endl<<"* DetectUnclosedWire :"<<endl;
134 #endif
135
136   Standard_Integer res = ISUNKNOWN;
137
138   Standard_Integer nV = mapVon1E.Extent();
139   if      (nV == 0) {
140     res = CLOSEDW;
141   }
142   else if (nV == 1) {
143     const TopoDS_Shape& E = mapVon1E.FindFromIndex(1);
144     Standard_Boolean Eclosed = BRep_Tool::IsClosed(E);
145     Standard_Boolean dgE = BRep_Tool::Degenerated(TopoDS::Edge(E));
146     if      (dgE)     res = ISVERTEX;
147     else if (Eclosed) res = CLOSEDW;
148     else              res = UNCLOSEDW;
149   } 
150   else {
151     // Finding among all vertices,couple of vertices falling on same
152     // geometry.
153     // Filling up map <mapVV>,with (vi,vj),vi and vj are on same point.
154     Standard_Real tol = Precision::Confusion();
155     for (Standard_Integer i = 1;i <= nV;i++) {
156       const TopoDS_Vertex& vi = TopoDS::Vertex(mapVon1E.FindKey(i));
157       gp_Pnt pi = BRep_Tool::Pnt(vi);
158       for (Standard_Integer j = i+1;j <= nV;j++) {
159         const TopoDS_Vertex& vj = TopoDS::Vertex(mapVon1E.FindKey(j));
160         gp_Pnt pj = BRep_Tool::Pnt(vj);
161         Standard_Boolean same = pi.IsEqual(pj,tol);
162         if (same) {
163           mapVV.Add(vi,vj);
164           mapVV.Add(vj,vi);
165           break;
166         }
167       } // j
168     } // i
169     Standard_Integer nVV = mapVV.Extent();
170 #ifdef RM_HANGING
171     // MSV Oct 4, 2001: consider GCLOSEDW even if not all vertices from mapVon1E
172     //                  hit into mapVV; reason is the left vertices may start
173     //                  useless chains of hanging edges that can be removed to
174     //                  achieve a closed wire.
175     if (nVV > 0)   res = GCLOSEDW;
176 #else
177     if (nVV == nV) res = GCLOSEDW;
178 #endif
179     else           res = UNCLOSEDW;
180   }
181   return res;
182 } // FUN_AnalyzemapVon1E
183
184 #ifdef DRAW
185 void FUN_AnalyzemapVon1EDRAW(const Standard_Integer res,
186                              const TopTools_IndexedDataMapOfShapeShape& mapVon1E,
187                              const TopTools_IndexedDataMapOfShapeShape& mapVV,
188                              const TopoDS_Shape& W,const Standard_Integer iiwi,
189                              TopTools_IndexedDataMapOfShapeShape& mapVon1EdgeDRAW,
190                              TopTools_IndexedDataMapOfShapeShape& mapVVsameGDRAW)
191 {
192   Standard_Boolean trc = TopOpeBRepBuild_GettracePURGE();
193   if (!trc) return;
194   cout<<"wire "<<iiwi;
195   if      (res == ISVERTEX) {
196     cout<<" is vertex"<<endl;
197   }
198   else if (res == CLOSEDW) {
199     cout<<" is closed"<<endl;
200   }
201   else if (res == GCLOSEDW) {
202     cout<<" is Gclosed :"<<endl;
203     TCollection_AsciiString aa("w_");FUN_tool_draw(aa,W,iiwi);
204     Standard_Integer i ;
205     for ( i = 1;i <= mapVV.Extent();i++) {
206       Standard_Integer iV = mapVVsameGDRAW.Add(mapVV.FindKey(i),mapVV.FindFromIndex(i));
207       cout<<" on vve_"<<iV; aa = "vve_";
208       FUN_tool_draw(aa,mapVVsameGDRAW.FindKey(iV),iV);
209     }
210     for (i = 1;i <= mapVon1E.Extent();i++) {
211       Standard_Integer iE = mapVon1EdgeDRAW.Add(mapVon1E.FindKey(i),mapVon1E.FindFromIndex(i));
212       cout<<" on eed_"<<iE; aa = "eed_";
213       FUN_tool_draw(aa,mapVon1EdgeDRAW.FindFromIndex(iE),iE);
214     }
215     cout<<endl;
216   }
217   else if (res == UNCLOSEDW) {
218     cout<<" is unclosed "<<endl;
219     TCollection_AsciiString aa("w_");FUN_tool_draw(aa,W,iiwi);
220   }
221   cout<<endl;
222 } // FUN_AnalyzemapVon1EDRAW
223 #endif
224
225 //=======================================================================
226 //function : DetectUnclosedWire
227 //purpose  : 
228 //=======================================================================
229 void TopOpeBRepBuild_FaceBuilder::DetectUnclosedWire(TopTools_IndexedDataMapOfShapeShape& mapVVsameG,
230                               TopTools_IndexedDataMapOfShapeShape& mapVon1Edge)
231 {
232   // wire unclosed : has vertices of connexity == 1
233   // exception : a wire of one closed edge with only one vertex describing
234   //             a face or a degenerated edge.
235
236   mapVVsameG.Clear();
237   mapVon1Edge.Clear();
238
239   // During the wire processing,
240   // * IF THE WIRE IS G-CLOSED,we fill up the maps :
241   //  - <mapVVsameG> with vertices falling on same geometry
242   //  - <mapVon1Edge> with (key = vertex,item = edge),
243   //    the vertex is connected to only one unclosed,undegenerated edge.
244   // * Else,if it is unclosed,we delete it (or it`s hanging edges).
245
246 #ifdef DRAW
247   TopTools_IndexedDataMapOfShapeShape mapVon1EdgeDRAW,mapVVsameGDRAW;
248   Standard_Boolean trc = TopOpeBRepBuild_GettracePURGE();
249   if (trc) cout<<endl<<"* DetectUnclosedWire :"<<endl<<endl;
250 #endif
251
252   Standard_Integer iiwi = 0; // DEB
253
254   InitFace();
255   for (;MoreFace();NextFace()) {
256    InitWire();
257     for (;MoreWire();NextWire()) { 
258       iiwi++;
259       Standard_Boolean isold = IsOldWire();
260 #ifdef DRAW
261       if ( trc && isold ) cout<<"wire "<<iiwi<<" is old wire => closed"<<endl;
262 #endif
263       if (isold) continue;
264       
265       TopoDS_Compound cmp;BRep_Builder BB;BB.MakeCompound(cmp);
266       InitEdge();
267       for(;MoreEdge();NextEdge()) AddEdgeWire(Edge(),cmp);
268       TopoDS_Shape W = cmp;
269
270       // <mapVon1E> binds vertices of connexity 1 attached to one non-closed,non-degenerated edge.
271       TopTools_IndexedDataMapOfShapeShape mapVon1E;
272       FUN_DetectVerticesOn1Edge(W,mapVon1E);
273
274       TopTools_IndexedDataMapOfShapeShape mapVV;
275       Standard_Integer res = FUN_AnalyzemapVon1E(mapVon1E,mapVV);
276 #ifdef DRAW
277       FUN_AnalyzemapVon1EDRAW(res,mapVon1E,mapVV,W,iiwi,mapVon1EdgeDRAW,mapVVsameGDRAW);
278 #endif
279
280       if      (res == ISVERTEX) {
281         continue;
282       }
283       else if (res == CLOSEDW) {
284         continue;
285       }
286       else if (res == GCLOSEDW) {
287         Standard_Integer i;
288         for (i = 1;i <= mapVV.Extent();i++) {
289           mapVVsameG.Add(mapVV.FindKey(i),mapVV.FindFromIndex(i));
290         }
291         for (i = 1;i <= mapVon1E.Extent();i++) {
292            mapVon1Edge.Add(mapVon1E.FindKey(i),mapVon1E.FindFromIndex(i));
293         }
294       }
295       else if (res == UNCLOSEDW) {
296 #ifdef RM_HANGING
297         // MSV Oct 4, 2001: remove hanging edges
298         TopTools_IndexedDataMapOfShapeListOfShape mapVE;
299         TopExp::MapShapesAndAncestors (W, TopAbs_VERTEX, TopAbs_EDGE, mapVE);
300         Standard_Integer nV = mapVon1E.Extent();
301         for (Standard_Integer i = 1; i <= nV; i++)
302         {
303           TopoDS_Vertex V = TopoDS::Vertex (mapVon1E.FindKey(i));
304           if (mapVV.Contains(V)) continue;  // V is in same geometry pair
305           while (1)
306           {
307             const TopTools_ListOfShape &LE = mapVE.FindFromKey(V);
308
309             // get not yet processed edge, count the number of such edges
310             Standard_Integer nEdges = 0;
311             TopoDS_Edge Edge;
312             TColStd_ListOfInteger LOI;
313             TopTools_ListIteratorOfListOfShape itE (LE);
314             for (; itE.More() && nEdges <= 1; itE.Next())
315             {
316               const TopoDS_Edge &E = TopoDS::Edge (itE.Value());
317               Standard_Integer I = myBlockBuilder.Element(E);
318               if (!BRep_Tool::IsClosed(E) && myBlockBuilder.ElementIsValid(I))
319               {
320                 TopoDS_Vertex Vf,Vl;
321                 TopExp::Vertices (E, Vf, Vl);
322                 LOI.Append(I);
323                 // consider not small edges only
324                 if (!Vf.IsSame(Vl))
325                 {
326                   Edge = E;
327                   nEdges++;
328                 }
329               }
330             }
331             if (nEdges != 1) break;  // stop this chain
332
333             // remove edges from Block Builder
334             TColStd_ListIteratorOfListOfInteger itLOI (LOI);
335             for (; itLOI.More(); itLOI.Next())
336               myBlockBuilder.SetValid (itLOI.Value(), Standard_False);
337
338             // get other vertex
339             TopoDS_Vertex aV1, aV2, otherV;
340             TopExp::Vertices (Edge, aV1, aV2);
341             if (aV1.IsSame (V))
342               otherV = aV2;
343             else if (aV2.IsSame (V))
344               otherV = aV1;
345             if (otherV.IsNull()) break;
346             V = otherV;
347           }
348         }
349 #else
350         TopExp_Explorer ex;
351         for (ex.Init(W,TopAbs_EDGE);ex.More();ex.Next()) {
352 //      for (TopExp_Explorer ex(W,TopAbs_EDGE);ex.More();ex.Next()) {
353           Standard_Integer I = myBlockBuilder.Element(ex.Current());
354           myBlockBuilder.SetValid(I,Standard_False);
355         }
356 #endif
357       }
358     } // MoreWire
359   } // MoreFace
360 } // DetectUnclosedWire
361
362 //=======================================================================
363 //function : CorrectGclosedWire
364 //purpose  :
365 //=======================================================================
366 void TopOpeBRepBuild_FaceBuilder::CorrectGclosedWire(const TopTools_IndexedDataMapOfShapeShape& mapVVref,
367                                const TopTools_IndexedDataMapOfShapeShape& mapVon1Edge)
368 {
369   // prequesitory : edges described by <mapVon1Edge> are not closed,not degenerated
370 #ifdef OCCT_DEBUG
371   if (TopOpeBRepBuild_GettracePURGE()) {
372     cout<<endl<<"* CorrectGclosedWire :"<<endl<<endl;
373   }
374 #endif
375   
376   Standard_Integer nVV = mapVVref.Extent();
377   for (Standard_Integer i = 1;i <= nVV;i++) {
378     const TopoDS_Vertex& V = TopoDS::Vertex(mapVVref.FindKey(i));
379     const TopoDS_Vertex& Vref = TopoDS::Vertex(mapVVref.FindFromIndex(i));
380     
381     if (V.IsSame(Vref)) continue;
382
383     TopoDS_Edge E = TopoDS::Edge(mapVon1Edge.FindFromKey(V));
384     Standard_Real paronE = BRep_Tool::Parameter(V,E);
385     
386     BRep_Builder BB;E.Free(Standard_True);
387     BB.Remove(E,V);
388     TopoDS_Shape aLocalShape = Vref.Oriented(V.Orientation());
389     TopoDS_Vertex newVref = TopoDS::Vertex(aLocalShape);
390 //    TopoDS_Vertex newVref = TopoDS::Vertex(Vref.Oriented(V.Orientation()));
391     BB.Add(E,newVref);
392     TopOpeBRepDS_BuildTool BT;
393     BT.Parameter(E,newVref,paronE);
394   }
395 }
396
397 //=======================================================================
398 //function : DetectPseudoInternalEdge
399 //purpose  :
400 //=======================================================================
401 void TopOpeBRepBuild_FaceBuilder::DetectPseudoInternalEdge(TopTools_IndexedMapOfShape& MapE)
402 {
403   TopoDS_Compound cmp;BRep_Builder BB;BB.MakeCompound(cmp);
404   InitFace();
405   for (;MoreFace();NextFace()) {
406     InitWire();
407     for (;MoreWire();NextWire()) {
408       Standard_Boolean isold = IsOldWire(); if (isold) continue;
409       InitEdge();
410       for(;MoreEdge();NextEdge()) AddEdgeWire(Edge(),cmp);
411     } // MoreWire
412   } // MoreFace
413
414   TopTools_IndexedDataMapOfShapeListOfShape mapVOE;
415   TopExp::MapShapesAndAncestors(cmp,TopAbs_VERTEX,TopAbs_EDGE,mapVOE);
416   Standard_Integer nv = mapVOE.Extent();
417
418   MapE.Clear();
419   for (Standard_Integer i = 1; i <= nv; i++) {
420     const TopTools_ListOfShape& le = mapVOE.FindFromIndex(i);
421     Standard_Integer ne = le.Extent();
422     if (ne == 2) {
423       TopTools_ListIteratorOfListOfShape ile(le); const TopoDS_Shape& e1 = ile.Value();
424       ile.Next();        const TopoDS_Shape& e2 = ile.Value();
425       Standard_Boolean same = e1.IsSame(e2);
426       TopAbs_Orientation o1 = e1.Orientation();
427       TopAbs_Orientation o2 = e2.Orientation();
428       Standard_Boolean o1co2 = (o1 == TopAbs::Complement(o2));
429
430       if ( same && o1co2 ) {
431         MapE.Add(e1);
432
433         Standard_Integer ie1 = myBlockBuilder.Element(e1);
434         myBlockBuilder.SetValid(ie1,Standard_False);
435
436         Standard_Integer ie2 = myBlockBuilder.Element(e2);
437         myBlockBuilder.SetValid(ie2,Standard_False);
438       }
439     }
440   }
441
442 }
443
444 //=======================================================================
445 //function : Face
446 //purpose  : 
447 //=======================================================================
448 const TopoDS_Shape& TopOpeBRepBuild_FaceBuilder::Face() const 
449 {
450   return myFace;
451 }
452
453 //=======================================================================
454 //function : InitFace
455 //purpose  : 
456 //=======================================================================
457 Standard_Integer TopOpeBRepBuild_FaceBuilder::InitFace()
458 {
459   Standard_Integer n = myFaceAreaBuilder.InitArea();
460   return n;
461 }
462
463 //=======================================================================
464 //function : MoreFace
465 //purpose  : 
466 //=======================================================================
467 Standard_Boolean TopOpeBRepBuild_FaceBuilder::MoreFace() const
468 {
469   Standard_Boolean b = myFaceAreaBuilder.MoreArea();
470   return b;
471 }
472
473 //=======================================================================
474 //function : NextFace
475 //purpose  : 
476 //=======================================================================
477 void TopOpeBRepBuild_FaceBuilder::NextFace()
478 {
479   myFaceAreaBuilder.NextArea();
480 }
481
482 //=======================================================================
483 //function : InitWire
484 //purpose  : 
485 //=======================================================================
486 Standard_Integer TopOpeBRepBuild_FaceBuilder::InitWire()
487 {
488   Standard_Integer n = myFaceAreaBuilder.InitLoop();
489   return n;
490 }
491
492 //=======================================================================
493 //function : MoreWire
494 //purpose  : 
495 //=======================================================================
496 Standard_Boolean TopOpeBRepBuild_FaceBuilder::MoreWire() const
497 {
498   Standard_Boolean b = myFaceAreaBuilder.MoreLoop();
499   return b;
500 }
501
502 //=======================================================================
503 //function : NextWire
504 //purpose  : 
505 //=======================================================================
506 void TopOpeBRepBuild_FaceBuilder::NextWire()
507 {
508   myFaceAreaBuilder.NextLoop();
509 }
510
511 //=======================================================================
512 //function : IsOldWire
513 //purpose  : 
514 //=======================================================================
515 Standard_Boolean TopOpeBRepBuild_FaceBuilder::IsOldWire() const
516 {
517   const Handle(TopOpeBRepBuild_Loop)& L = myFaceAreaBuilder.Loop();
518   Standard_Boolean b = L->IsShape();
519   return b;
520 }
521
522 //=======================================================================
523 //function : OldWire
524 //purpose  : 
525 //=======================================================================
526 const TopoDS_Shape& TopOpeBRepBuild_FaceBuilder::OldWire() const
527 {
528   const Handle(TopOpeBRepBuild_Loop)& L = myFaceAreaBuilder.Loop();
529   const TopoDS_Shape& B = L->Shape();
530   return B;
531 }
532
533 //=======================================================================
534 //function : FindNextValidElement
535 //purpose  : 
536 //=======================================================================
537 void TopOpeBRepBuild_FaceBuilder::FindNextValidElement()
538 {
539   // prerequisites : myBlockIterator.Initialize
540   myFaceAreaBuilder.Loop();
541   Standard_Boolean found = Standard_False;
542
543   while ( myBlockIterator.More()) {
544     const Standard_Integer i = myBlockIterator.Value();
545     found = myBlockBuilder.ElementIsValid(i);
546     if (found) break;
547     else myBlockIterator.Next();
548   }
549 }
550
551 //=======================================================================
552 //function : InitEdge
553 //purpose  : 
554 //=======================================================================
555 Standard_Integer TopOpeBRepBuild_FaceBuilder::InitEdge()
556 {
557   const Handle(TopOpeBRepBuild_Loop)& L = myFaceAreaBuilder.Loop();
558   if ( L->IsShape() )
559     throw Standard_DomainError("TopOpeBRepBuild_FaceBuilder:InitEdge");
560   else {
561     myBlockIterator = L->BlockIterator();
562     myBlockIterator.Initialize();
563     FindNextValidElement();
564   }
565   Standard_Integer n = myBlockIterator.Extent();
566   return n;
567 }
568
569 //=======================================================================
570 //function : MoreEdge
571 //purpose  : 
572 //=======================================================================
573 Standard_Boolean TopOpeBRepBuild_FaceBuilder::MoreEdge() const
574 {
575   Standard_Boolean b = myBlockIterator.More();
576   return b;
577 }
578
579 //=======================================================================
580 //function : NextEdge
581 //purpose  : 
582 //=======================================================================
583 void TopOpeBRepBuild_FaceBuilder::NextEdge()
584 {
585   myBlockIterator.Next();
586   FindNextValidElement();
587 }
588
589 //=======================================================================
590 //function : Edge
591 //purpose  : 
592 //=======================================================================
593 const TopoDS_Shape& TopOpeBRepBuild_FaceBuilder::Edge() const
594 {
595   if (!myBlockIterator.More()) throw Standard_Failure("OutOfRange");
596
597   const Standard_Integer i = myBlockIterator.Value();
598   Standard_Boolean isvalid = myBlockBuilder.ElementIsValid(i);
599   if (!isvalid) throw Standard_Failure("Edge not Valid");
600
601   const TopoDS_Shape& E = myBlockBuilder.Element(i);
602   return E;
603 }
604
605 //=======================================================================
606 //function : EdgeConnexity
607 //purpose  : 
608 //=======================================================================
609 Standard_Integer TopOpeBRepBuild_FaceBuilder::EdgeConnexity(const TopoDS_Shape& /*E*/) const
610 {
611 #ifdef OCCT_DEBUG
612   throw Standard_ProgramError("FaceBuilder::EdgeConnexity management disactivated");
613 #else
614   return 0;
615 #endif
616 //  Standard_Boolean inmosi = myMOSI.IsBound(E);
617 //  Standard_Integer nmosi = (inmosi) ? myMOSI.Find(E) : 0;
618 //  return nmosi;
619 }
620
621 //=======================================================================
622 //function : AddEdgeWire
623 //purpose  : 
624 //=======================================================================
625 Standard_Integer TopOpeBRepBuild_FaceBuilder::AddEdgeWire(const TopoDS_Shape& E,TopoDS_Shape& W) const
626 {
627   Standard_Integer nadd = 0;
628   BRep_Builder BB;
629   BB.Add(W,E);nadd++;
630 //  Standard_Integer nmosi = EdgeConnexity(E);
631 //  Standard_Boolean addEC = (nmosi == 1);
632 //  if (addEC) {
633 //    TopAbs_Orientation oe = E.Orientation();
634 //    TopAbs_Orientation oc = TopAbs::Complement(oe);
635 //    TopoDS_Shape EC = E.Oriented(oc);
636 //    BB.Add(W,EC);nadd++;
637 //  }
638   return nadd;
639 }
640
641 //=======================================================================
642 //function : MakeLoops
643 //purpose  : 
644 //=======================================================================
645 void TopOpeBRepBuild_FaceBuilder::MakeLoops(TopOpeBRepBuild_ShapeSet& SS)
646 {
647   TopOpeBRepBuild_BlockBuilder& BB = myBlockBuilder;
648   TopOpeBRepBuild_ListOfLoop& LL = myLoopSet.ChangeListOfLoop();
649
650   // Build blocks on elements of SS
651   BB.MakeBlock(SS);
652
653   // make list of loop (LL) of the LoopSet
654   // - on shapes of the ShapeSet (SS)
655   // - on blocks of the BlockBuilder (BB)
656
657   // Add shapes of SS as shape loops
658   LL.Clear();
659   for(SS.InitShapes();SS.MoreShapes();SS.NextShape()) {
660     const TopoDS_Shape& S = SS.Shape();
661     Handle(TopOpeBRepBuild_Loop) ShapeLoop = new TopOpeBRepBuild_Loop(S);
662     LL.Append(ShapeLoop);
663   }
664   
665   // Add blocks of BB as block loops
666   for (BB.InitBlock();BB.MoreBlock();BB.NextBlock()) {
667     TopOpeBRepBuild_BlockIterator BI = BB.BlockIterator();
668     Handle(TopOpeBRepBuild_Loop) BlockLoop = new TopOpeBRepBuild_Loop(BI);
669     LL.Append(BlockLoop);
670   }
671
672 }