0023024: Update headers of OCCT files
[occt.git] / src / BRepAlgo / BRepAlgo_DSAccess.cxx
1 // Created on: 1997-08-13
2 // Created by: Prestataire Mary FABIEN
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
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.
10 //
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.
13 //
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.
20
21
22
23 #include <BRepAlgo_DSAccess.ixx>
24 #include <BRepAlgo_EdgeConnector.hxx>
25
26 #include <TColStd_ListOfInteger.hxx>
27 #include <TColStd_MapOfInteger.hxx>
28 #include <TColStd_IndexedMapOfInteger.hxx>
29 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
30 #include <TColStd_SetIteratorOfSetOfInteger.hxx>
31
32 #include <TopTools_ListOfShape.hxx>
33 #include <TopTools_ListIteratorOfListOfShape.hxx>
34 #include <TopTools_MapOfShape.hxx>
35 #include <TColStd_ListIteratorOfListOfInteger.hxx>
36 #include <TopoDS.hxx>
37 #include <TopoDS_Compound.hxx>
38 #include <TopoDS_Wire.hxx>
39 #include <TopOpeBRepDS_PointIterator.hxx>
40 #include <TopOpeBRepDS_BuildTool.hxx>
41 #include <TopOpeBRepDS_CheckStatus.hxx>
42 #include <TopOpeBRepDS_Check.hxx>
43 #include <TopOpeBRepDS_ListOfInterference.hxx>
44 #include <TopOpeBRepDS_Interference.hxx>
45 #include <TopOpeBRepDS_InterferenceIterator.hxx>
46 #include <TopOpeBRepDS_ListIteratorOfListOfInterference.hxx>
47 #include <TopOpeBRepDS_ShapeShapeInterference.hxx>
48 #include <TopOpeBRepDS_HDataStructure.hxx>
49 #include <TopOpeBRepDS_CurveExplorer.hxx>
50 #include <TopOpeBRepDS_CurveIterator.hxx>
51 #include <TopOpeBRepDS_Filter.hxx>
52 #include <TopOpeBRepDS_Reducer.hxx>
53 #include <TopOpeBRepTool_GeomTool.hxx>
54 #include <TopOpeBRepBuild_HBuilder.hxx>
55 #include <TopOpeBRepBuild_WireEdgeSet.hxx>
56 #include <TopOpeBRepBuild_FaceBuilder.hxx>
57 #include <TopOpeBRep_DSFiller.hxx>
58
59 #ifdef DRAW
60 //#include <TestTopOpe.hxx>
61 #endif
62
63 //=======================================================================
64 //function : Create
65 //purpose  : 
66 //=======================================================================
67
68 BRepAlgo_DSAccess::BRepAlgo_DSAccess() {
69   Init();
70 }
71
72 //=======================================================================
73 //function : Init
74 //purpose  : 
75 //=======================================================================
76
77 void BRepAlgo_DSAccess::Init()
78 {
79   if(myHDS.IsNull()) 
80     myHDS = new TopOpeBRepDS_HDataStructure();
81   else
82     myHDS->ChangeDS().Init();
83   myRecomputeBuilderIsDone = Standard_False;
84   myGetSectionIsDone = Standard_False;
85   myListOfCompoundOfEdgeConnected.Clear();
86   myEC = new BRepAlgo_EdgeConnector();
87   myHB.Nullify();
88   
89   // init of the builder
90   Standard_Real tol3dAPPROX = 1e-7;
91   Standard_Real tol2dAPPROX = 1e-7;
92   // set tolerance values used by the APPROX process
93   TopOpeBRepTool_GeomTool GT;
94   GT.Define(TopOpeBRepTool_APPROX);
95   GT.SetTolerances(tol3dAPPROX,tol2dAPPROX);
96   TopOpeBRepDS_BuildTool BT(GT);
97   myHB = new TopOpeBRepBuild_HBuilder(BT);
98   myHB->ChangeBuilder().ChangeClassify(Standard_False);
99
100   myState1 = TopAbs_UNKNOWN;
101   myState2 = TopAbs_UNKNOWN;
102
103 }
104
105
106 // Filling of the DS
107
108 //=======================================================================
109 //function : Load
110 //purpose  : 
111 //=======================================================================
112
113 void BRepAlgo_DSAccess::Load(const TopoDS_Shape& S)
114 {
115   TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
116   myS1 = S;
117   DS.AddShape(S, 1);
118 }
119
120 //=======================================================================
121 //function : Load
122 //purpose  : 
123 //=======================================================================
124
125 void BRepAlgo_DSAccess::Load(TopoDS_Shape& S1, 
126                              TopoDS_Shape& S2)
127 {
128   TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
129   
130   if ( S1.Orientation() == TopAbs_REVERSED ) {
131     S1.Orientation(TopAbs_FORWARD);
132   }
133   if ( S2.Orientation() == TopAbs_REVERSED ) {
134     S2.Orientation(TopAbs_FORWARD);
135   }
136   
137   DS.AddShape(S1,1);
138   DS.AddShape(S2,2);
139
140   TopOpeBRepTool_ShapeExplorer ex1,ex2;
141   for (ex1.Init(S1,TopAbs_SOLID); ex1.More(); ex1.Next()) {
142     const TopoDS_Shape& so1 = ex1.Current();
143     for (ex2.Init(S2,TopAbs_SOLID); ex2.More(); ex2.Next()) {
144       const TopoDS_Shape& so2 = ex2.Current();
145       DS.FillShapesSameDomain(so1,so2);
146     }
147   }
148   
149   myS1 = S1;
150   myS2 = S2;
151
152 #ifdef DRAW
153 //  TestTopOpe::CurrentDS(myHDS);
154 //  TestTopOpe::Shapes(myS1,myS2);
155 #endif
156 }
157
158 //=======================================================================
159 //function : Intersect
160 //purpose  : 
161 //=======================================================================
162
163 void BRepAlgo_DSAccess::Intersect()
164 {
165   myRecomputeBuilderIsDone = Standard_False;
166   
167   if(!myS1.IsNull() && !myS2.IsNull())
168     myDSFiller.Insert(myS1, myS2, myHDS);
169 }
170
171 //=======================================================================
172 //function : Intersect
173 //purpose  : 
174 //=======================================================================
175
176 void BRepAlgo_DSAccess::Intersect
177 (const TopoDS_Shape& S1,
178  const TopoDS_Shape& S2)
179 {
180   myRecomputeBuilderIsDone = Standard_False;
181   
182   if(S1.IsNull() || S2.IsNull()) {
183     return;
184   }
185   
186   Standard_Boolean orientFORWARD = Standard_False;
187   TopExp_Explorer exp;
188   if(S1.ShapeType() != TopAbs_FACE) {
189     exp.Init(S1, TopAbs_FACE);
190     if(!exp.More())
191       return;
192   }
193   if(S2.ShapeType() != TopAbs_FACE) {
194     exp.Init(S2, TopAbs_FACE);
195     if(!exp.More())
196       return;
197   }
198   myDSFiller.Insert(S1, S2, myHDS, orientFORWARD);
199 }
200
201 //=======================================================================
202 //function : SameDomain
203 //purpose  : 
204 //=======================================================================
205
206 void BRepAlgo_DSAccess::SameDomain
207 (const TopoDS_Shape& S1,
208  const TopoDS_Shape& S2)
209 {
210   myRecomputeBuilderIsDone = Standard_False;
211   
212   if(S1.IsNull() || S2.IsNull())
213     return;
214
215   TopExp_Explorer exp1, exp2;
216     exp1.Init(S1, TopAbs_FACE);
217     if(!exp1.More())
218       return;
219     exp2.Init(S2, TopAbs_FACE);
220     if(!exp2.More())
221       return;
222   
223   myDSFiller.Insert2d(S1, S2, myHDS);
224 }
225
226
227 // Construction of Sections
228
229 #define FindKeep Standard_False
230
231 //=======================================================================
232 //function : GetSectionEdgeSet
233 //purpose  : 
234 //=======================================================================
235
236 const TopTools_ListOfShape& BRepAlgo_DSAccess::GetSectionEdgeSet
237 (const TopoDS_Shape& S1,
238  const TopoDS_Shape& S2)
239 {
240   GetSectionEdgeSet();
241
242   // Check if S1 and S2 contain faces
243   TopExp_Explorer exp1, exp2;
244   exp1.Init(S1, TopAbs_FACE);
245   if(!exp1.More())
246     return myEmptyListOfShape;
247   exp2.Init(S2, TopAbs_FACE);
248   if(!exp2.More())
249     return myEmptyListOfShape;
250   
251   for(exp1.Init(S1, TopAbs_FACE); exp1.More(); exp1.Next()) {
252     if(!myHDS->HasShape(exp1.Current(), FindKeep))
253       return myEmptyListOfShape;
254   }
255   for(exp2.Init(S2, TopAbs_FACE); exp2.More(); exp2.Next())
256     if(!myHDS->HasShape(exp2.Current(), FindKeep))
257       return myEmptyListOfShape;
258   
259   TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
260   TopOpeBRepBuild_Builder& Builder = myHB->ChangeBuilder();
261   
262   // The purpose is to find interferences associated with faces,
263   // edges that come from their Geometry (= Edge || Curve)
264   TopTools_ListOfShape LE;
265   LE.Clear();
266   TopExp_Explorer exp;
267   for(exp1.Init(S1, TopAbs_FACE); exp1.More(); exp1.Next()) {
268     const TopoDS_Shape& F1 = exp1.Current();
269     
270     TopOpeBRepDS_ListOfInterference& lof = DS.ChangeShapeInterferences(F1);
271     TopOpeBRepDS_InterferenceIterator li(lof);
272     li.SupportKind(TopOpeBRepDS_FACE);
273     for(exp2.Init(S2, TopAbs_FACE); exp2.More(); exp2.Next()) {
274       const TopoDS_Shape& F2 = exp2.Current();
275       Standard_Integer si = DS.Shape(F2, FindKeep);
276       li.Support(si);
277       
278       for(; li.More(); li.Next()) {
279         const TopOpeBRepDS_Interference& CurrInt = li.Value();
280         TopOpeBRepDS_Kind gk = CurrInt.GeometryType();
281         Standard_Integer gi = CurrInt.Geometry();
282         const TopoDS_Shape& geosha = DS.Shape(gi, FindKeep);
283         if(gk == TopOpeBRepDS_CURVE) {
284           const TopTools_ListOfShape& lEdge = myHB->NewEdges(gi);
285           LE.Append(lEdge.First());
286         } else {
287           const TopTools_ListOfShape& lEdge = Builder.Splits(geosha, TopAbs_ON);
288           TopTools_ListIteratorOfListOfShape it(lEdge);
289           for(; it.More(); it.Next()) {
290             const TopoDS_Shape& CurrEdge = it.Value();
291             Standard_Integer ipv1, ipv2;
292             TopOpeBRepDS_Kind pvk1, pvk2;
293             PntVtxOnSectEdge(CurrEdge, ipv1, pvk1, ipv2, pvk2);
294             if(pvk1 != TopOpeBRepDS_VERTEX) {
295               ipv1 = 0;
296               if(pvk2 != TopOpeBRepDS_VERTEX) continue;
297             } else {
298               if(pvk2 != TopOpeBRepDS_VERTEX)
299                 ipv2 = 0;
300             }
301             for(exp.Init(F1, TopAbs_VERTEX); exp.More(); exp.Next()) {
302               Standard_Integer iVert = DS.Shape(exp.Current());
303               if(iVert) {
304                 if((iVert == ipv1) || (iVert == ipv2)) {
305                   LE.Append(CurrEdge);
306                   break;
307                 }
308               }
309             }
310           }
311         }
312       }
313     }
314   }
315
316   // find all groups of connected Edges associated to LE
317   TopTools_ListIteratorOfListOfShape ILE;
318   myCurrentList.Clear();
319   TopTools_MapOfShape ME;
320   ME.Clear();
321   TopTools_ListIteratorOfListOfShape ILC;
322   TopExp_Explorer ECE;
323   ILE.Initialize(LE);
324   for(;ILE.More();ILE.Next()) {
325     const TopoDS_Shape& E = ILE.Value();
326     ILC.Initialize(myListOfCompoundOfEdgeConnected);
327     for(;ILC.More();ILC.Next()) {
328       const TopoDS_Shape& Com = ILC.Value();
329       ECE.Init(Com, TopAbs_EDGE);
330       for(;ECE.More();ECE.Next()) {
331         if(ECE.Current().IsSame(E)) {
332           if(!ME.Contains(Com)) {
333             myCurrentList.Append(Com);
334             ME.Add(Com);
335             break;
336           }
337         }
338       }
339     }
340   }
341   
342   return myCurrentList;
343 }
344
345 //=======================================================================
346 //function : GetSectionEdgeSet
347 //purpose  : 
348 //=======================================================================
349
350 const TopTools_ListOfShape& BRepAlgo_DSAccess::GetSectionEdgeSet()
351 {
352   if(!myRecomputeBuilderIsDone) {
353     // it is possible to call the method many times consecutively
354     myHDS->AddAncestors(myS1);
355     // start of lpa modification
356     if (!myS1.IsSame(myS2) && !myS2.IsNull()) {
357       myHDS->AddAncestors(myS2);
358       myHB->Perform(myHDS,myS1,myS2);
359     }
360     else {
361       myHB->Perform(myHDS);
362     }
363     // end of modif lpa
364     myRecomputeBuilderIsDone = Standard_True;
365     myGetSectionIsDone = Standard_False;
366   } 
367   if(myGetSectionIsDone)
368     return myListOfCompoundOfEdgeConnected;
369   myGetSectionIsDone = Standard_True;
370   
371   myListOfCompoundOfEdgeConnected.Clear();
372   
373   // EdgeConnector
374   Handle(BRepAlgo_EdgeConnector) EC = myEC;
375   EC->ClearStartElement();
376   TopTools_MapOfShape ME;
377   ME.Clear();
378   myHB->InitSection();
379   for(; myHB->MoreSection(); myHB->NextSection()) {
380     const TopoDS_Edge& ES = TopoDS::Edge(myHB->CurrentSection());
381     if(ME.Contains(ES)) continue;
382     ME.Add(ES);
383     EC->AddStart(ES);
384   }
385   TopTools_ListOfShape& LW = EC->MakeBlock();
386   
387   // the wires are tranformed into compounds.
388   myCompoundWireMap.Clear();
389   BRep_Builder BB;
390   TopTools_ListIteratorOfListOfShape ILW(LW);
391   TopExp_Explorer Explor;
392   for(;ILW.More();ILW.Next()) {
393       TopoDS_Compound Compound;
394 //POP
395       BB.MakeCompound(Compound);
396 //      BB.MakeCompound(TopoDS::Compound(Compound));
397       Explor.Init(ILW.Value(), TopAbs_EDGE);
398       for(;Explor.More(); Explor.Next()) {
399         BB.Add(Compound, Explor.Current());
400       }
401       myListOfCompoundOfEdgeConnected.Append(Compound);
402       myCompoundWireMap.Bind(Compound,ILW.Value());
403     }
404   return myListOfCompoundOfEdgeConnected;
405 }
406
407 //=======================================================================
408 //function : IsWire
409 //purpose  : 
410 //=======================================================================
411
412 Standard_Boolean BRepAlgo_DSAccess::IsWire(const TopoDS_Shape& S)
413 {
414   Standard_Boolean b = Standard_False;
415   if(myEC->IsDone()) {
416     if (myCompoundWireMap.IsBound(S))
417       b = myEC->IsWire(myCompoundWireMap(S));
418   }
419   return b;
420 }
421
422 //=======================================================================
423 //function : Wire
424 //purpose  : 
425 //=======================================================================
426
427 const TopoDS_Shape& BRepAlgo_DSAccess::Wire(const TopoDS_Shape& S)
428 {
429   if(!IsWire(S)) {
430     myWire.Nullify();
431   }
432   else {
433     BRep_Builder BB;
434     BB.MakeWire(myWire);
435     TopExp_Explorer Explor(S, TopAbs_EDGE);
436     for(;Explor.More(); Explor.Next()) BB.Add(myWire, Explor.Current());
437   }
438   return myWire;
439 }
440
441 //=======================================================================
442 //function : SectionVertex
443 //purpose  : 
444 //=======================================================================
445
446 const TopTools_ListOfShape& BRepAlgo_DSAccess::SectionVertex
447 (const TopoDS_Shape& F,
448  const TopoDS_Shape& E)
449 {
450   TopTools_ListOfShape Result;
451   Result.Clear();
452   if(F.ShapeType() != TopAbs_FACE) return myEmptyListOfShape;
453   if(E.ShapeType() != TopAbs_EDGE) return myEmptyListOfShape;
454   Standard_Integer iF = myHDS->Shape(F), iE = myHDS->Shape(E);
455   if((iF == 0) || (iE == 0)) return myEmptyListOfShape;
456
457   const TopOpeBRepDS_DataStructure& DS = myHDS->DS();
458   const TopOpeBRepDS_ListOfInterference& LI = 
459     DS.ShapeInterferences(E, Standard_False);
460   TopOpeBRepDS_InterferenceIterator II(LI);
461   Standard_Integer goodIndex = 0;
462   TopOpeBRepDS_Kind goodKind;
463   for(;II.More();II.Next()) {
464     Handle(TopOpeBRepDS_Interference)& I = II.Value();
465     const TopOpeBRepDS_Transition& T = I->Transition();
466     if((T.ONAfter() == TopAbs_FACE) &&
467        (T.IndexAfter()  == iF)) {
468       goodKind  = I->GeometryType();
469       goodIndex = I->Geometry();
470       if(goodKind == TopOpeBRepDS_VERTEX)
471         Result.Append(myHDS->Shape(goodIndex));
472       else 
473         if (goodKind == TopOpeBRepDS_POINT)
474           Result.Append(myHB->NewVertex(goodIndex));
475     }
476   }
477   myListOfVertex = Result;
478   return myListOfVertex;
479 }
480
481
482 // Editing of the DS
483
484 //=======================================================================
485 //function : SuppressEdgeSet
486 //purpose  : 
487 //=======================================================================
488
489 void BRepAlgo_DSAccess::SuppressEdgeSet
490 (const TopoDS_Shape& C)
491 {
492   // It is checked if C really is a Coumpound of connected Edges
493
494   myHB->InitExtendedSectionDS();
495 //  myGetSectionIsDone = Standard_False;
496
497   TopTools_ListIteratorOfListOfShape LLS(myListOfCompoundOfEdgeConnected);
498   for(;LLS.More(); LLS.Next())
499     if(C == LLS.Value())
500       break;
501   if(!LLS.More())
502     return;
503   
504   // Cleaning
505   TopoDS_Shape Empty;
506   Empty.Nullify();
507   Suppress(C, Empty);
508   myListOfCompoundOfEdgeConnected.Remove(LLS);
509 }
510
511 //=======================================================================
512 //function : ChangeEdgeSet
513 //purpose  : 
514 //=======================================================================
515
516 void BRepAlgo_DSAccess::ChangeEdgeSet
517 (const TopoDS_Shape& Old, const TopoDS_Shape& New)
518 {
519   // It is checked if Old is a Coumpound of connected Edges
520
521   myHB->InitExtendedSectionDS();
522
523   TopTools_ListIteratorOfListOfShape LLS(myListOfCompoundOfEdgeConnected);
524   for(;LLS.More(); LLS.Next())
525     if(Old == LLS.Value())
526       break;
527   if(!LLS.More())
528     return;
529
530   // The compound of Edges to be rotated is constructed
531   BRep_Builder B;
532   Standard_Boolean Trouve;
533   Standard_Integer iC;
534   TopoDS_Compound C;
535   TopoDS_Edge E;
536   B.MakeCompound(C);
537   TColStd_SetOfInteger RPoint; //The points to be controlled 
538   
539  TopOpeBRepDS_ListIteratorOfListOfInterference iter;
540   TopExp_Explorer exp(Old, TopAbs_EDGE);
541   TopExp_Explorer exp2;
542   for(; exp.More(); exp.Next()) {
543     const TopoDS_Shape& Edge = exp.Current(); 
544     for(exp2.Init(New, TopAbs_EDGE), Trouve=Standard_False;
545         exp2.More() && (!Trouve); exp2.Next()) {
546       E = TopoDS::Edge(exp2.Current());
547       Trouve = E.IsSame(Edge);
548     }
549
550     if (!Trouve) B.Add(C, Edge); // Edge to be removed
551     else if (!E.IsEqual(Edge)) {
552       // It is necessary to change Interferences => take the complement
553       iC = myHB->GetDSCurveFromSectEdge(Edge);
554       if (!iC) {
555 #if DEB
556         cout << "Warning DSAccess: Modifications of Edge are not implemented" << endl;
557 #endif
558       }
559       else {
560         // Complete the interferences Curve/Face
561         Standard_Integer iF;
562         Handle(TopOpeBRepDS_Interference) interf;
563
564         iF = myHB->GetDSFaceFromDSCurve(iC, 1); 
565         TopOpeBRepDS_ListOfInterference& list1 = 
566            myHDS->ChangeDS().ChangeShapeInterferences(iF);
567         for(iter.Initialize(list1); iter.More(); iter.Next()) {
568           interf = iter.Value();
569           if (interf->Geometry() == iC)
570             interf->Transition(interf->Transition().Complement());
571         }
572         iF = myHB->GetDSFaceFromDSCurve(iC, 2); 
573         TopOpeBRepDS_ListOfInterference& list2 = 
574           myHDS->ChangeDS().ChangeShapeInterferences(iF);
575         for(iter.Initialize(list2); iter.More(); iter.Next()) {
576           interf = iter.Value();
577           if (interf->Geometry() == iC)
578             interf->Transition(interf->Transition().Complement());
579         }
580         // The associated points are recorded
581         Standard_Integer ipv1, ipv2;
582         //Standard_Boolean bid; // skl
583         TopOpeBRepDS_Kind k1, k2;       
584         PntVtxOnCurve(iC, ipv1, k1, ipv2, k2);
585         if (ipv1 != 0) /*bid = */RPoint.Add(ipv1); // skl
586         if (ipv2 != 0) /*bid = */RPoint.Add(ipv2); // skl
587       }
588     }
589   }
590
591
592   // Cleaning
593   Suppress(C, New);
594
595   // Is it necessary to invert the Interferences "Edge on Fa"
596   if (!RPoint.IsEmpty()) {
597     const TopOpeBRepDS_DataStructure & DS = myHDS->DS();
598     Standard_Integer iP,iE, nbShape = DS.NbShapes();
599     Handle(TopOpeBRepDS_Interference) interf;
600     for (iE=1; iE<=nbShape; iE++) {
601       if (DS.Shape(iE,0).ShapeType() == TopAbs_EDGE) { 
602         const TopOpeBRepDS_ListOfInterference& List = 
603           myHDS->DS().ShapeInterferences(iE);
604         for(iter.Initialize(List); iter.More(); iter.Next()) {
605           interf = iter.Value();
606           if (interf->GeometryType() == TopOpeBRepDS_POINT) {
607             iP = interf->Geometry();
608             if (RPoint.Contains(iP))
609               interf->Transition(interf->Transition().Complement());
610           }
611         }
612       }
613     }
614   }
615
616   // The old is replaced by new
617   LLS.Value() = New;
618 }
619
620
621 //=======================================================================
622 //function : Remove
623 //purpose  : 
624 //=======================================================================
625
626 void BRepAlgo_DSAccess::Suppress(const TopoDS_Shape& C,
627                                  const TopoDS_Shape& Keep)
628 {
629  TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
630  TopOpeBRepBuild_Builder& Builder = myHB->ChangeBuilder();
631  Standard_Integer i, iC = 0, iF1, iF2,iE1, iE2;
632 // TopOpeBRepDS_ListIteratorOfListOfInterference;
633  TColStd_ListIteratorOfListOfInteger it1, it2;
634
635   //A group of points to be kept is constructed
636  mySetOfKeepPoint.Clear();
637  if (!Keep.IsNull()) {
638    //Standard_Boolean B; // skl
639    Standard_Integer ipv1, ipv2;
640    TopOpeBRepDS_Kind k1, k2;
641    TopExp_Explorer exp(Keep, TopAbs_EDGE);
642    for(; exp.More(); exp.Next()) {
643      const TopoDS_Shape& SectEdge = exp.Current();
644      iC = myHB->GetDSCurveFromSectEdge(SectEdge);
645      if(!iC) 
646        PntVtxOnSectEdge(SectEdge, ipv1, k1, ipv2, k2);
647      else 
648        PntVtxOnCurve(iC, ipv1, k1, ipv2, k2);
649      if (ipv1 != 0) /*B = */mySetOfKeepPoint.Add(ipv1); // skl
650      if (ipv2 != 0) /*B = */mySetOfKeepPoint.Add(ipv2); // skl
651    }
652  }
653
654   // The curves, which generated the the Edges, are found
655   // during the parsing the Edges which come from Edge are found
656   // (= MapOfInteger : ESE)
657   
658   // First, the interferences of support 1d.
659   TopExp_Explorer exp(C, TopAbs_EDGE);
660   for(; exp.More(); exp.Next()) {
661     const TopoDS_Shape& SectEdge = exp.Current();
662     iC = myHB->GetDSCurveFromSectEdge(SectEdge);
663     if(!iC) {
664       // the Edges that come from Edge are processed
665       // the interferences connected with Edges are processed :
666       iE1 = myHB->GetDSEdgeFromSectEdge(SectEdge, 1);
667       iE2 = myHB->GetDSEdgeFromSectEdge(SectEdge, 2);
668       
669       RemoveEdgeInterferences(iE1,iE2,SectEdge);
670       
671       TColStd_ListOfInteger& loi11 = myHB->GetDSFaceFromDSEdge(iE1, 1);
672       TColStd_ListOfInteger& loi12 = myHB->GetDSFaceFromDSEdge(iE1, 2);
673       for(it1.Initialize(loi11); it1.More(); it1.Next()) {
674         iF1 = it1.Value();
675         for(it2.Initialize(loi12); it2.More(); it2.Next()) {
676           iF2 = it2.Value();
677           // similar to the case of SectEdges coming from curve.
678           RemoveEdgeInterferences(iF1,iF2,SectEdge);
679         }
680       }
681       TColStd_ListOfInteger& loi21 = myHB->GetDSFaceFromDSEdge(iE2, 1);
682       TColStd_ListOfInteger& loi22 = myHB->GetDSFaceFromDSEdge(iE2, 2);
683       for(it1.Initialize(loi21); it1.More(); it1.Next()) {
684         iF1 = it1.Value();
685         for(it2.Initialize(loi22); it2.More(); it2.Next()) {
686           iF2 = it2.Value();
687           // similar to the case of  SectEdges coming from curve.
688           RemoveEdgeInterferences(iF1,iF2,SectEdge);
689         }
690       }
691       continue;
692     }    
693     // The Edges that come from Curve are processed
694     iF1 = myHB->GetDSFaceFromDSCurve(iC, 1);
695     iF2 = myHB->GetDSFaceFromDSCurve(iC, 2);
696     
697     RemoveEdgeInterferences(iF1, iF2, iC);
698     DS.ChangeKeepCurve(iC, FindKeep);
699   }
700   
701   // Secondly, the interferences of 2D support.
702   exp.Init(C, TopAbs_EDGE);
703   for(; exp.More(); exp.Next()) {
704     const TopoDS_Shape& SectEdge = exp.Current();
705     iC = myHB->GetDSCurveFromSectEdge(SectEdge);
706     if(!iC) {
707       iE1 = myHB->GetDSEdgeFromSectEdge(SectEdge, 1);
708       iE2 = myHB->GetDSEdgeFromSectEdge(SectEdge, 2);
709       TColStd_ListOfInteger& loi11 = myHB->GetDSFaceFromDSEdge(iE1, 1);
710       TColStd_ListOfInteger& loi12 = myHB->GetDSFaceFromDSEdge(iE1, 2);
711       for(it1.Initialize(loi11); it1.More(); it1.Next()) {
712         iF1 = it1.Value();
713         for(it2.Initialize(loi12); it2.More(); it2.Next()) {
714           iF2 = it2.Value();
715           if(iF1 == iF2)
716             continue;
717           RemoveFaceInterferences(iF1, iF2, iE1, iE2);
718         }
719       }
720       TColStd_ListOfInteger& loi21 = myHB->GetDSFaceFromDSEdge(iE2, 1);
721       TColStd_ListOfInteger& loi22 = myHB->GetDSFaceFromDSEdge(iE2, 2);
722       for(it1.Initialize(loi21); it1.More(); it1.Next()) {
723         iF1 = it1.Value();
724         for(it2.Initialize(loi22); it2.More(); it2.Next()) {
725           iF2 = it2.Value();
726           if(iF1 == iF2)
727             continue;
728           RemoveFaceInterferences(iF1, iF2, iE1, iE2);
729         }
730       }
731     }
732     else {
733       iF1 = myHB->GetDSFaceFromDSCurve(iC, 1);
734       iF2 = myHB->GetDSFaceFromDSCurve(iC, 2);
735       
736       RemoveFaceInterferences(iF1, iF2, iC);
737     }
738   }
739   
740   // Thirdly, RemoveSameDomain is done for the faces that contain all Edges of C,
741   // and are SameDomain and without Geometry.
742   
743   RemoveFaceSameDomain(C);
744   
745   // Fourthly, the faces, that were not concerned, are removed
746   Standard_Integer NbSh = DS.NbShapes();
747   for(i = 1; i <= NbSh; i++) {
748     const TopoDS_Shape& Face = DS.Shape(i);
749     if(Face.IsNull())
750       continue;
751     if((Face.ShapeType() != TopAbs_FACE) || DS.HasGeometry(Face) ||
752        (myHDS->HasSameDomain(Face)))
753       continue;
754     for(exp.Init(Face, TopAbs_EDGE); exp.More(); exp.Next()){
755       const TopoDS_Shape& Edge = exp.Current();
756       if(DS.HasShape(Edge))
757         break;
758     }
759     if(exp.More())
760       continue;
761     DS.ChangeKeepShape(Face, Standard_False);
762   }
763   
764   // Builder.myKPMAPf1f2 is reconstructed
765   Builder.FindIsKPart(); 
766   
767   //  The Edges of section are removed from Builder.mySplitON
768   exp.Init(C, TopAbs_EDGE);
769   for(; exp.More(); exp.Next()) {
770     const TopoDS_Shape& SectE= exp.Current();
771     TopTools_ListOfShape& losob = Builder.ChangeSplit(SectE, TopAbs_ON);
772     losob.Clear();
773   }
774 }
775
776 //=======================================================================
777 //function : SuppressSectionVertex
778 //purpose  : 
779 //=======================================================================
780
781 void BRepAlgo_DSAccess::SuppressSectionVertex
782 (const TopoDS_Vertex& /*V*/)
783 {
784   if(!myRecomputeBuilderIsDone)
785     return;
786 }
787
788
789 // Reconstruction of Shapes
790
791 //=======================================================================
792 //function : Merge
793 //purpose  : 
794 //=======================================================================
795
796 const TopoDS_Shape& BRepAlgo_DSAccess::Merge
797 (const TopAbs_State state1,
798  const TopAbs_State state2)
799 {
800   if((state1 != TopAbs_IN) &&
801      (state1 != TopAbs_OUT))
802     return myEmptyShape;
803   if((state2 != TopAbs_IN) &&
804      (state2 != TopAbs_OUT))
805     return myEmptyShape;
806   // if GetSectionEdgeSet has already been called, nothing is done 
807   // in GetSectionEdgeSet.
808   if(myState1 != TopAbs_UNKNOWN)
809     if(myState1 != state1 || myState2 != state2)
810       myGetSectionIsDone = Standard_False;
811   myState1 = state1;
812   myState2 = state2;
813   GetSectionEdgeSet();
814   
815   myHB->Clear();
816   myHB->MergeShapes(myS1,state1,myS2,state2);
817   const TopTools_ListOfShape& L1 = myHB->Merged(myS1,state1);
818   
819   BRep_Builder BB;
820   myResultShape.Nullify();
821   BB.MakeCompound(TopoDS::Compound(myResultShape));
822   TopTools_ListIteratorOfListOfShape it(L1);
823   for(;it.More(); it.Next()) {
824     BB.Add(myResultShape, it.Value());
825   }
826   return myResultShape;
827 }
828
829 //=======================================================================
830 //function : Merge
831 //purpose  : 
832 //=======================================================================
833
834 const TopoDS_Shape& BRepAlgo_DSAccess::Merge
835 (const TopAbs_State state1)
836 {
837   if((state1 != TopAbs_IN) &&
838      (state1 != TopAbs_OUT))
839     return myEmptyShape;
840   GetSectionEdgeSet();
841
842   myHB->Clear();
843   myHB->MergeSolid(myS1,state1);
844   const TopTools_ListOfShape& L1 = myHB->Merged(myS1,state1);
845   
846   BRep_Builder BB;
847   myResultShape.Nullify();
848   BB.MakeCompound(TopoDS::Compound(myResultShape));
849   TopTools_ListIteratorOfListOfShape it(L1);
850   for(;it.More(); it.Next()) {
851     BB.Add(myResultShape, it.Value());
852   }
853   return myResultShape;
854 }
855
856 //=======================================================================
857 //function : Propagate
858 //purpose  : 
859 //=======================================================================
860
861 const TopoDS_Shape& BRepAlgo_DSAccess::Propagate
862 (const TopAbs_State what,
863  const TopoDS_Shape& /*fromShape*/,
864  const TopoDS_Shape& /*LoadShape*/)
865 {
866   if((what != TopAbs_IN) &&
867      (what != TopAbs_OUT))
868     return myEmptyShape;
869   if(!myRecomputeBuilderIsDone)
870     return myEmptyShape;
871
872 //  myHB->MergeShapes(myS1,t1,myS2,t2);
873
874   //POP for NT;
875   static TopoDS_Shape bid;
876   return bid;
877 }
878
879 //=======================================================================
880 //function : PropagateFromSection
881 //purpose  : 
882 //=======================================================================
883
884 const TopoDS_Shape& BRepAlgo_DSAccess::PropagateFromSection
885 (const TopoDS_Shape& SectionShape)
886 {
887   GetSectionEdgeSet();
888   TopTools_ListIteratorOfListOfShape ils(myListOfCompoundOfEdgeConnected);
889   TopExp_Explorer exp;
890   for(; ils.More(); ils.Next()) {
891     const TopoDS_Shape& SetEdgSet = ils.Value();
892     exp.Init(SetEdgSet, TopAbs_EDGE);
893     for(; exp.More(); exp.Next()) {
894       if(SectionShape.IsSame(exp.Current()))
895         return SetEdgSet;
896     }
897   }
898   return myEmptyShape;
899 }
900
901 //=======================================================================
902 //function : Modified
903 //purpose  : 
904 //=======================================================================
905
906 const TopTools_ListOfShape& BRepAlgo_DSAccess::Modified (const TopoDS_Shape& Shape) 
907 {
908   myModified.Clear() ;
909
910 //  Handle(TopOpeBRepBuild_HBuilder)& HBuilder = myDSA.myHB ;
911   TopTools_ListIteratorOfListOfShape Iterator ;
912   
913   if (myHB->IsSplit (Shape, TopAbs_OUT)) {
914     for (Iterator.Initialize (myHB->Splits (Shape, TopAbs_OUT)) ;
915          Iterator.More() ;
916          Iterator.Next()) {
917       myModified.Append (Iterator.Value()) ;
918     }
919   }
920   if (myHB->IsSplit (Shape, TopAbs_IN)) {
921     for (Iterator.Initialize (myHB->Splits (Shape, TopAbs_IN)) ;
922          Iterator.More() ;
923          Iterator.Next()) {
924       myModified.Append (Iterator.Value()) ;
925     }
926   }
927   if (myHB->IsSplit (Shape, TopAbs_ON)) {
928     for (Iterator.Initialize (myHB->Splits (Shape, TopAbs_ON)) ;
929          Iterator.More() ;
930          Iterator.Next()) {
931       myModified.Append (Iterator.Value()) ;
932     }
933   }
934
935   if (myHB->IsMerged (Shape, TopAbs_OUT)) {
936     for (Iterator.Initialize (myHB->Merged (Shape, TopAbs_OUT)) ;
937          Iterator.More() ;
938          Iterator.Next()) {
939       myModified.Append (Iterator.Value()) ;
940     }
941   }
942   if (myHB->IsMerged(Shape, TopAbs_IN)) {
943     for (Iterator.Initialize (myHB->Merged (Shape, TopAbs_IN)) ;
944          Iterator.More() ;
945          Iterator.Next()) {
946       myModified.Append (Iterator.Value()) ;
947     }
948   }
949   if (myHB->IsMerged(Shape, TopAbs_ON)) {
950     for (Iterator.Initialize (myHB->Merged (Shape, TopAbs_ON)) ;
951          Iterator.More() ;
952          Iterator.Next()) {
953       myModified.Append (Iterator.Value()) ;
954     }
955   }
956
957   return myModified ;
958 }
959
960
961
962 //=======================================================================
963 //function : Check
964 //purpose  : 
965 //=======================================================================
966
967 BRepAlgo_CheckStatus BRepAlgo_DSAccess::Check()
968 {
969 //  TopOpeBRepDS_Check Ck(HDS);
970 // to be precised : in Ck, there is a possibility to know 
971 // exactly the n*n of shapes/points/curves/surfaces, 
972 // which are not correct in the DS.
973 //  Standard_Boolean IsOK = Ck.ChkIntgSamDom() ;
974 //  IsOK = IsOK && Ck.OneVertexOnPnt();
975 //  IsOK = IsOK && Ck.ChkIntg();
976 //  if(IsOK)
977 //    return TopOpeBRepDS_OK;
978   return BRepAlgo_NOK;
979 }
980
981 //=======================================================================
982 //function : RemoveEdgeInterferences
983 //purpose  : case of SectEdge coming from Edge(s)
984 //       
985 //     if iE1 and iE2 are Edges :
986 //     Remove interferences of DSEdge(= iE1 or iE2) of
987 //     geometry a vertex of SectEdge, and if there is nothing else, 
988 //     make unkeep on DSEdge 
989 //     if iE1 or iE2 == 0, no interference on Edges in the DS 
990 //     NYI : management of SameDomain
991 //       
992 //     if iE1 and iE2 are Faces :
993 //     for each of faces F1 and F2, explode into Edges
994 //     for each Edge :
995 //           remove the interferences of a SectEdge vertex
996 //           on geometry. If there is no other interferences attached to 
997 //           these Edges, and if these Edges are not SameDomain,
998 //           make unKeepShape.
999 //=======================================================================
1000
1001 void BRepAlgo_DSAccess::RemoveEdgeInterferences
1002 (const Standard_Integer iE1,
1003  const Standard_Integer iE2,
1004  const TopoDS_Shape& SectEdge)
1005 {
1006   if(!iE1 || !iE2)
1007     return;
1008
1009   TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
1010   TopOpeBRepDS_Kind kind1, kind2;
1011   TopExp_Explorer exp(SectEdge, TopAbs_VERTEX);
1012   Standard_Integer i = 1, ipv1, ipv2;
1013   
1014   // the Vertex/Points of SectEdge are retrieved
1015   PntVtxOnSectEdge(SectEdge, ipv1, kind1, ipv2, kind2);
1016   
1017   const TopoDS_Shape& Shape = DS.Shape(iE1, FindKeep);
1018   if(Shape.IsNull())
1019     return;
1020   if(Shape.ShapeType() == TopAbs_FACE) {
1021     Standard_Integer iF1 = iE1, iF2 = iE2;
1022     RemoveEdgeInterferencesFromFace(iF1, iF2, ipv1, kind1, ipv2, kind2);
1023     return;
1024   }
1025   else if(Shape.ShapeType() != TopAbs_EDGE)
1026     return;
1027   
1028   // the interferences are taken from the DS
1029   TopOpeBRepDS_ListIteratorOfListOfInterference lioloi;
1030   TopOpeBRepDS_Kind gk;
1031   Standard_Integer iCurrE1, iCurrE2, gi;
1032 //  Standard_Boolean RemInterf;
1033   
1034   for(i = 1; i <= 2; i++) {
1035     iCurrE1 = ((i == 1) ? iE1 : iE2);
1036     iCurrE2 = ((i == 1) ? iE2 : iE1);
1037     const TopoDS_Shape& DSEdge = DS.Shape(iCurrE1, FindKeep);
1038     if(DSEdge.IsNull())
1039       continue;
1040     TopOpeBRepDS_ListOfInterference& loi = 
1041       DS.ChangeShapeInterferences(DSEdge);
1042     //    RemInterf = Standard_True;
1043     for(lioloi.Initialize(loi); lioloi.More(); lioloi.Next()) {
1044       Handle(TopOpeBRepDS_Interference) I = lioloi.Value();
1045       if (I.IsNull()) continue;
1046       if((I->SupportType() != TopOpeBRepDS_EDGE) ||
1047          (I->Support() != iCurrE2)) {
1048         //      RemInterf = Standard_False;//debug ...
1049         continue;
1050       }
1051       gk = I->GeometryType();
1052       gi = I->Geometry();
1053       if(gk == kind1) {
1054         if(gi == ipv1) {
1055           DS.RemoveShapeInterference(DSEdge, I);
1056           if(!DS.HasGeometry(DSEdge)) {
1057             //      if(RemInterf || (!lioloi.More())) {
1058             RemoveEdgeSameDomain(iCurrE1, iCurrE2); // NYI : SameDomain
1059             DS.ChangeKeepShape(iCurrE1, FindKeep);
1060             //    } 
1061           } 
1062         }
1063       }
1064       else if(gk == kind2) {
1065         if(gi == ipv2) {
1066           DS.RemoveShapeInterference(DSEdge, I);
1067           if(!DS.HasGeometry(DSEdge)) {
1068             //      if(RemInterf || (!lioloi.More())) {//debug
1069             RemoveEdgeSameDomain(iCurrE1, iCurrE2); // NYI : SameDomain
1070             DS.ChangeKeepShape(iCurrE1, FindKeep);
1071             //    } 
1072           }
1073         }
1074       }
1075     }
1076   }
1077 }
1078
1079 //=======================================================================
1080 //function : RemoveEdgeInterferences
1081 //purpose  : case of SectEdge coming from Curve
1082 //           for each of faces F1 and F2, explode into Edges
1083 //           for each Edge :
1084 //           remove the interferences that have a vertex of SectEdge
1085 //           as a geometry. If no other interferences are attached to  
1086 //           these Edges, and if the Edges are not SameDomain,
1087 //           make unKeepShape.
1088 //=======================================================================
1089
1090 void BRepAlgo_DSAccess::RemoveEdgeInterferences
1091 (const Standard_Integer iF1,
1092  const Standard_Integer iF2,
1093  const Standard_Integer iCurve)
1094 {
1095   TopOpeBRepDS_Kind gk1, gk2;
1096   Standard_Integer gi1, gi2;
1097   
1098   PntVtxOnCurve(iCurve, gi1, gk1, gi2, gk2);
1099
1100   if (!mySetOfKeepPoint.IsEmpty()) {
1101     if (mySetOfKeepPoint.Contains(gi1)) gi1 = 0;
1102     if (mySetOfKeepPoint.Contains(gi2)) gi2 = 0;   
1103   }
1104   
1105   if (gi1 || gi2)
1106     RemoveEdgeInterferencesFromFace(iF1, iF2, gi1, gk1, gi2, gk2);
1107 }
1108
1109 //=======================================================================
1110 //function : RemoveFaceInterferences
1111 //purpose  : case of SectEdge coming from Edge(s)
1112 //        Remove interferences between F1 and F2 concerning 
1113 //        DSEdge (= E1 or E2) :
1114 //              a) if DSEdge is not SameDomain -> the edge is Removed
1115 //              b) if among other interferences of DSEdge of 
1116 //                 GeomtryType == VERTEX, there is none 
1117 //                 with Edge of DSFace(= F1 or F2)
1118 //        if DSFace has no more interferences and is not SameDomain,
1119 //        make unkeep DSFace.
1120 //=======================================================================
1121
1122 void BRepAlgo_DSAccess::RemoveFaceInterferences
1123 (const Standard_Integer iF1,
1124  const Standard_Integer iF2,
1125  const Standard_Integer iE1,
1126  const Standard_Integer iE2)
1127 {
1128   if(!iF1 || !iF2)
1129     return;
1130   TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
1131   TopOpeBRepDS_ListIteratorOfListOfInterference lioloi;//, lioloei, liolofi;
1132   TopTools_ListIteratorOfListOfShape liolos;
1133   TopOpeBRepDS_Kind gk;
1134   TopExp_Explorer exp;
1135   Standard_Integer i, iCurrF1, iCurrF2, j, iCurrE1, /*iCurrE2,*/ gi; // skl
1136   Standard_Boolean RemInterf;
1137   
1138   for(i = 1; i <= 2; i++) {
1139     iCurrF1 = ((i == 1) ? iF1 : iF2);
1140     iCurrF2 = ((i == 1) ? iF2 : iF1);
1141     const TopoDS_Shape& DSFace = DS.Shape(iCurrF1);
1142     if(DSFace.IsNull())
1143       continue;
1144     const TopOpeBRepDS_ListOfInterference& loi = DS.ShapeInterferences(DSFace);
1145     for(lioloi.Initialize(loi); lioloi.More(); lioloi.Next()) {
1146       Handle(TopOpeBRepDS_Interference) I = lioloi.Value();
1147       if (I.IsNull()) continue;
1148       if((I->SupportType() != TopOpeBRepDS_FACE) ||
1149          (I->Support() != iCurrF2)) {
1150         continue;
1151       }
1152       gk = I->GeometryType();
1153       gi = I->Geometry();
1154       if(gk != TopOpeBRepDS_EDGE) continue;
1155       for(j = 1; j <= 2; j++) {
1156         iCurrE1 = ((j == 1) ? iE1 : iE2);
1157         //iCurrE2 = ((j == 1) ? iE2 : iE1); // skl
1158         if(gi != iCurrE1) continue;
1159         // a) if DSEdge is not SameDomain -> the interference is Removed
1160         //    et DSEdge
1161         const TopoDS_Shape& DSEdge = DS.Shape(iCurrE1, FindKeep);
1162         if(DSEdge.IsNull())
1163           continue;
1164         if(!myHDS->HasSameDomain(DSEdge)) {
1165           if(!DS.HasGeometry(DSEdge)) {
1166             DS.RemoveShapeInterference(DSFace, I);
1167             DS.ChangeKeepShape(DSEdge, FindKeep);
1168           } else {
1169             // NYI : manage the case when the geometry of DSEdge 
1170             // NYI : is not connected anyhow with two faces
1171           }
1172           if(!DS.HasGeometry(DSFace)) {
1173             DS.ChangeKeepShape(DSFace, FindKeep);
1174           }
1175           continue;
1176         }
1177         // b) if no Edges of  SameDomain(DSEdge),
1178         //    belong to DSFace(= F1 or F2)
1179         //     -> the interference is removed
1180         const TopoDS_Shape& Edge = DS.Shape(iCurrE1, FindKeep);
1181         if(Edge.IsNull())
1182           continue;
1183         const TopTools_ListOfShape& loe = DS.ShapeSameDomain(Edge);
1184         RemInterf = Standard_True;
1185         for(liolos.Initialize(loe); liolos.More(); liolos.Next()) {
1186           const TopoDS_Shape& ESD = liolos.Value();
1187           for(exp.Init(DSFace, TopAbs_EDGE); exp.More(); exp.Next()) {
1188             if(ESD.IsSame(exp.Current())) {
1189               RemInterf = Standard_False;
1190               break;
1191             }
1192           }
1193           if(!RemInterf) break;
1194         }
1195         if(RemInterf) {
1196           //      RemoveSameDomain(iCurrF1, iCurrF2);
1197           
1198           if(!DS.HasGeometry(DSFace)) {
1199             if(!myHDS->HasSameDomain(DSFace))
1200               DS.ChangeKeepShape(DSFace, FindKeep);
1201           }
1202         }
1203         if(!DS.HasGeometry(DSFace) && !myHDS->HasSameDomain(DSFace))
1204           DS.ChangeKeepShape(DSFace, FindKeep);
1205       }
1206     }
1207   }
1208 }
1209
1210 //=======================================================================
1211 //function : RemoveFaceInterferences
1212 //purpose  : case of SectEdge from Curve
1213 //           remove interferences of Geometry iCurve between F1 and F2.
1214 //           if Face(= F1 or F2) has noother interference, and if Face
1215 //           is not SameDomain, make unKeepShape Face.
1216 //=======================================================================
1217
1218 void BRepAlgo_DSAccess::RemoveFaceInterferences
1219 (const Standard_Integer iF1,
1220  const Standard_Integer iF2,
1221  const Standard_Integer iCurve)
1222 {
1223   TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
1224   TopOpeBRepDS_ListIteratorOfListOfInterference lioloi;
1225   TopOpeBRepDS_Kind gk;
1226   Standard_Integer i, iCurrF1, iCurrF2, gi;
1227
1228   for(i = 1; i <= 2; i++) {
1229     iCurrF1 = ((i == 1) ? iF1 : iF2);
1230     iCurrF2 = ((i == 1) ? iF2 : iF1);
1231     const TopoDS_Shape& DSFace = DS.Shape(iCurrF1);
1232     const TopOpeBRepDS_ListOfInterference& loi = DS.ShapeInterferences(DSFace);
1233     for(lioloi.Initialize(loi); lioloi.More(); lioloi.Next()) {
1234       Handle(TopOpeBRepDS_Interference) I = lioloi.Value();
1235       if (I.IsNull()) continue;
1236       if((I->SupportType() != TopOpeBRepDS_FACE) ||
1237          (I->Support() != iCurrF2)) {
1238         break;;
1239       }
1240     }
1241     for(lioloi.Initialize(loi); lioloi.More(); lioloi.Next()) {
1242       Handle(TopOpeBRepDS_Interference) I = lioloi.Value();
1243       if (I.IsNull()) continue;
1244       if((I->SupportType() != TopOpeBRepDS_FACE) ||
1245          (I->Support() != iCurrF2)) {
1246         continue;
1247       }
1248       gk = I->GeometryType();
1249       gi = I->Geometry();
1250       if(gk != TopOpeBRepDS_CURVE) continue;
1251       if(gi != iCurve) continue;
1252       DS.RemoveShapeInterference(DSFace, I);
1253 //      const TopoDS_Shape& interferenceface = DS.Shape(iCurrF2);
1254 //      DS.RemoveShapeInterference(interferenceface, I);
1255       if(!DS.HasGeometry(DSFace)) {
1256         const TopTools_ListOfShape& los = DS.ShapeSameDomain(DSFace);
1257         if(los.IsEmpty())
1258           DS.ChangeKeepShape(DSFace, FindKeep);
1259       }
1260 //      if(!DS.HasGeometry(interferenceface)) {
1261 //      const TopTools_ListOfShape& los = DS.ShapeSameDomain(interferenceface);
1262 //      if(los.IsEmpty())
1263 //        DS.ChangeKeepShape(interferenceface, FindKeep);
1264 //      }
1265     }
1266   }
1267 }
1268
1269 //=======================================================================
1270 //function : RemoveEdgeInterferencesFromFace
1271 //purpose  : Remove interferences of Edges from iF1 or iF2
1272 //           that have GeometryType kind1/kind2 and 
1273 //           Geometry ipv1/ipv2.
1274 //           if kind1/kind2 == TopAbs_VERTEX -> RemoveEdgeFromFace
1275 //=======================================================================
1276
1277 void BRepAlgo_DSAccess::RemoveEdgeInterferencesFromFace
1278 (const Standard_Integer iF1,
1279  const Standard_Integer iF2,
1280  const Standard_Integer ipv1,
1281  const TopOpeBRepDS_Kind kind1,
1282  const Standard_Integer ipv2,
1283  const TopOpeBRepDS_Kind kind2)
1284 {
1285   TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
1286   TopOpeBRepDS_ListIteratorOfListOfInterference lioloi;
1287   TopExp_Explorer exp, exp2;
1288   TopOpeBRepDS_Kind sk, gk;
1289   Standard_Integer i, iCurrF1, iCurrF2, iE = 0, si, gi;
1290
1291   for(i = 1; i <= 2; i++) {
1292     iCurrF1 = ((i == 1) ? iF1 : iF2);
1293     iCurrF2 = ((i == 1) ? iF2 : iF1);
1294     const TopoDS_Shape& DSFace = DS.Shape(iCurrF1, FindKeep);
1295     if(DSFace.IsNull())
1296       continue;
1297     exp.Init(DSFace, TopAbs_EDGE);
1298     for(; exp.More(); exp.Next()) {
1299       const TopoDS_Shape& DSEdge = exp.Current();
1300       iE = DS.Shape(DSEdge, FindKeep);
1301       if(!iE) continue;
1302       const TopOpeBRepDS_ListOfInterference& loi =
1303         DS.ShapeInterferences(DSEdge);
1304       for(lioloi.Initialize(loi); lioloi.More(); lioloi.Next()) {
1305         Handle(TopOpeBRepDS_Interference) I = lioloi.Value();
1306         if (I.IsNull()) continue;
1307         sk = I->SupportType();
1308         si = I->Support();
1309         if((sk != TopOpeBRepDS_FACE) || (si != iCurrF2)) {
1310           if(sk != TopOpeBRepDS_EDGE)
1311             continue;
1312           const TopoDS_Shape& DSFace2 = DS.Shape(iCurrF2, FindKeep);
1313           exp2.Init(DSFace2, TopAbs_EDGE);
1314           for(; exp2.More(); exp2.Next()) {
1315             if(si == DS.Shape(exp2.Current(), FindKeep))
1316               break;
1317           }
1318           if(!exp2.More())
1319             continue;
1320         }
1321         gk = I->GeometryType();
1322         gi = I->Geometry();
1323         if(gk == kind1) {
1324           if(gi == ipv1) {
1325             DS.RemoveShapeInterference(DSEdge, I);
1326 //          if(!DS.HasGeometry(DSEdge)) {
1327 //            const TopTools_ListOfShape& los = DS.ShapeSameDomain(DSEdge);
1328 //            if(los.IsEmpty()) {
1329 //              DS.ChangeKeepShape(iE, FindKeep);
1330 //            }
1331 //          }
1332           }
1333           else if(gk == kind2) {
1334             if(gi == ipv2) {
1335               DS.RemoveShapeInterference(DSEdge, I);
1336 //            if(!DS.HasGeometry(DSEdge)) {
1337 //              const TopTools_ListOfShape& los = DS.ShapeSameDomain(DSEdge);
1338 //              if(los.IsEmpty()) {
1339 //                DS.ChangeKeepShape(iE, FindKeep);
1340 //              }
1341 //            }
1342             }
1343           }
1344           else continue;
1345         }
1346       }
1347     }
1348     if(kind1 == TopOpeBRepDS_VERTEX)
1349       RemoveEdgeFromFace(iCurrF1,ipv1);
1350     if(kind2 == TopOpeBRepDS_VERTEX)
1351       RemoveEdgeFromFace(iCurrF1,ipv2);
1352   }
1353 }
1354
1355 //=======================================================================
1356 //function : RemoveEdgeFromFace
1357 //purpose  : Remove from DS the Edges, which belong to iF
1358 //           and have iV as vertex if they do not have Geometry and
1359 //           are not SameDomain.
1360 //=======================================================================
1361
1362 void BRepAlgo_DSAccess::RemoveEdgeFromFace
1363 (const Standard_Integer iF,
1364  const Standard_Integer iV)
1365 {
1366   if(!iF || !iV)
1367     return;
1368   TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
1369   const TopoDS_Shape& DSFace = DS.Shape(iF, FindKeep);
1370   const TopoDS_Shape& Vertex = DS.Shape(iV, FindKeep);
1371   if(DSFace.IsNull() || Vertex.IsNull())
1372     return;
1373   TopExp_Explorer exp(DSFace, TopAbs_EDGE), exp2;
1374   for(; exp.More(); exp.Next()) {
1375     const TopoDS_Shape& Edge = exp.Current();
1376 #ifdef DEB
1377 //    Standard_Integer iEdge2 = DS.Shape(Edge, FindKeep);
1378 //    Standard_Integer iEdge3 = DS.Shape(Edge);
1379 #endif
1380                               
1381     if(!DS.HasShape(Edge)) 
1382       continue;
1383     exp2.Init(Edge, TopAbs_VERTEX);
1384     for(; exp2.More(); exp2.Next()) {
1385 #ifdef DEB
1386 //      Standard_Integer iEdge5 = DS.Shape(Vertex, FindKeep);
1387 //      Standard_Integer iEdge4 = DS.Shape(Vertex);
1388 //      Standard_Integer iEdge6 = DS.Shape(exp2.Current(), FindKeep);
1389 //      Standard_Integer iEdge7 = DS.Shape(exp2.Current());
1390 #endif
1391                                 
1392       if(Vertex.IsSame(exp2.Current())) {
1393         if(!DS.HasGeometry(Edge)) {
1394           const TopTools_ListOfShape& los = DS.ShapeSameDomain(Edge);
1395           if(los.IsEmpty()) {
1396 #ifdef DEB
1397 //          Standard_Integer iEdge = DS.Shape(Edge);
1398 #endif
1399             DS.ChangeKeepShape(Edge, FindKeep);
1400           }
1401         }
1402       }
1403     }
1404   }
1405 }
1406
1407 //=======================================================================
1408 //function : PntVtxOnCurve
1409 //purpose  : To find the points/vertices on curves
1410 //=======================================================================
1411
1412 void BRepAlgo_DSAccess::PntVtxOnCurve
1413 (const Standard_Integer iCurve,
1414  Standard_Integer& ipv1,
1415  TopOpeBRepDS_Kind& pvk1,
1416  Standard_Integer& ipv2,
1417  TopOpeBRepDS_Kind& pvk2)
1418 {
1419   TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
1420   
1421   const TopOpeBRepDS_Curve& C = DS.Curve(iCurve);
1422   TopOpeBRepDS_Kind pvk; 
1423   Standard_Integer ipv, iMother = C.Mother(), igoodC = iCurve, comp = 0;
1424   if(iMother) igoodC = iMother;
1425 //#ifndef DEB
1426   TopOpeBRepDS_PointIterator PII = myHDS->CurvePoints(igoodC);
1427   TopOpeBRepDS_PointIterator& PIt = PII; // skl : I change "M_PI" to "PIt"
1428 //#else
1429 //  TopOpeBRepDS_PointIterator& PIt = myHDS->CurvePoints(igoodC);
1430 //#endif
1431   for(;PIt.More(); PIt.Next()) {
1432     comp++;
1433     if(comp > 2)
1434       // Standard_Error ...
1435       return;
1436     ipv = PIt.Current();
1437     // a point or a vertex is removed from the DS
1438     if(PIt.IsPoint()) {
1439       pvk = TopOpeBRepDS_POINT;
1440       DS.ChangeKeepPoint(ipv, FindKeep);
1441     }
1442     else if(PIt.IsVertex()) {
1443       pvk = TopOpeBRepDS_VERTEX;
1444       DS.ChangeKeepShape(ipv, FindKeep);
1445     }
1446     else continue;
1447     ((comp == 1) ? ipv1 : ipv2) = ipv;
1448     ((comp == 1) ? pvk1 : pvk2) = pvk;
1449   }
1450 }
1451
1452 //=======================================================================
1453 //function : PntVtxOnSectEdge
1454 //purpose  : Points/Vertexes  on  SectEdge are found
1455 //=======================================================================
1456
1457 void BRepAlgo_DSAccess::PntVtxOnSectEdge
1458 (const TopoDS_Shape& SectEdge,
1459  Standard_Integer& ipv1,
1460  TopOpeBRepDS_Kind& pvk1,
1461  Standard_Integer& ipv2,
1462  TopOpeBRepDS_Kind& pvk2)
1463 {
1464 //  myHB->ChangeBuilder();
1465   TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
1466   TopOpeBRepDS_Kind kind = TopOpeBRepDS_POINT;
1467   TopExp_Explorer exp(SectEdge, TopAbs_VERTEX);
1468   Standard_Integer i = 1, ipv;
1469   
1470   for(; exp.More(); exp.Next(), i++) {    
1471     const TopoDS_Shape& DSVertex = exp.Current();
1472     ipv = myHB->GetDSPointFromNewVertex(DSVertex);
1473     if(!ipv) {
1474       ipv = DS.Shape(DSVertex, FindKeep);
1475       kind = TopOpeBRepDS_VERTEX;
1476       if(!ipv)
1477         // Standard_Error ...
1478         return;
1479     }
1480     
1481     if(i == 1) {
1482       ipv1 = ipv;
1483       pvk1 = kind;
1484     }    
1485     else if(i == 2) {
1486       ipv2 = ipv;
1487       pvk2 = kind;
1488     }
1489     else
1490       // Standard_Error ...
1491       return;
1492   }
1493 }
1494
1495 //=======================================================================
1496 //function : RemoveEdgeSameDomain
1497 //purpose  : 
1498 //=======================================================================
1499
1500 void BRepAlgo_DSAccess::RemoveEdgeSameDomain
1501 (const Standard_Integer /*iE1*/,
1502  const Standard_Integer /*iE2*/)
1503 {
1504   return;
1505 /*  TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
1506   const TopoDS_Shape& E1 = DS.Shape(iE1);
1507   const TopoDS_Shape& E2 = DS.Shape(iE2);
1508   TopAbs_ShapeEnum ts1, ts2;
1509   ts1 = E1.ShapeType();
1510   ts2 = E2.ShapeType();
1511   if((ts1 != TopAbs_EDGE) ||
1512      (ts2 != TopAbs_EDGE)) 
1513     return;
1514   TopTools_ListOfShape& lossd = DS.ChangeShapeSameDomain(E1);
1515   if(lossd.IsEmpty())
1516     return;
1517   Standard_Integer exte = lossd.Extent();
1518   if(exte == 1) {
1519     if(lossd.First().IsSame(E2))
1520       DS.UnfillShapesSameDomain(E1,E2);
1521     return;
1522   }*/
1523 }
1524
1525 //=======================================================================
1526 //function : RemoveFaceSameDomain
1527 //purpose  : remove SameDomain information of glued faces 
1528 //=======================================================================
1529
1530 void BRepAlgo_DSAccess::RemoveFaceSameDomain
1531 (const TopoDS_Shape& C)
1532 {
1533 //  myHB->ChangeBuilder();
1534   TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
1535
1536 //TColStd_ListIteratorOfListOfInteger it;
1537   TopExp_Explorer exp(C, TopAbs_EDGE);
1538   Standard_Integer  iE1, iE2, iE, /*NbF,*/ iF1, iF2, iCurrF1, iCurrF2,   iC =0; // skl
1539   iF1 = iF2 = iCurrF1 = iCurrF2 = 0;
1540   Standard_Boolean b;
1541   const TopoDS_Shape& SectEdge = exp.Current();
1542   
1543   for(; exp.More(); exp.Next()) {
1544     iC = myHB->GetDSCurveFromSectEdge(SectEdge);
1545     if(!iC && !SectEdge.IsNull())
1546       break;
1547 //  const TopoDS_Shape& SectEdge = exp.Current();
1548   }
1549   if(!iC && !SectEdge.IsNull()) {
1550     iE1 = myHB->GetDSEdgeFromSectEdge(SectEdge, 1);
1551     iE2 = myHB->GetDSEdgeFromSectEdge(SectEdge, 2);
1552     if(iE1 && iE2) return;
1553     iE = (iE1 ? iE1 : iE2);
1554     if(!iE) return;
1555     
1556     TColStd_ListOfInteger& loi = FindGoodFace(iE, iF1, b);
1557     if(!b) return;
1558     if(exp.More())
1559       exp.Next();
1560     //NbF = loi.Extent(); // skl
1561     for(; exp.More(); exp.Next()) {
1562       // skl : I change "SectEdge" to "SectEdg"
1563       const TopoDS_Shape& SectEdg = exp.Current();
1564       iC = myHB->GetDSCurveFromSectEdge(SectEdg);
1565       if(!iC) {
1566         iE1 = myHB->GetDSEdgeFromSectEdge(SectEdg, 1);
1567         iE2 = myHB->GetDSEdgeFromSectEdge(SectEdg, 2);
1568         if(iE1 && iE2) return;
1569         iE = (iE1 ? iE1 : iE2);
1570         if(!iE) return;
1571         
1572         TColStd_ListOfInteger& loi2 = FindGoodFace(iE, iCurrF1, b);
1573         if(!b) return;
1574         if(!iCurrF1 || !iF1) return;
1575         if(iCurrF1 != iF1) {
1576           if(loi2.Extent() == 1) iCurrF2 = loi2.First();
1577           if(iCurrF2 == iF1) continue;
1578           if(loi.Extent() == 1) iF2 = loi.First();
1579
1580           if(!iCurrF2 || !iF2) return;
1581           if((iCurrF1 == iF2) ||
1582              (iCurrF2 == iF2)) {
1583             iF1 = iF2;
1584             continue;
1585           }
1586           return;
1587         } 
1588       }
1589     }
1590     
1591     const TopoDS_Shape& FSD = DS.Shape(iF1);
1592     if(FSD.IsNull()) 
1593       return;
1594     TopTools_ListOfShape& ssd = DS.ChangeShapeSameDomain(FSD);
1595     TopTools_ListIteratorOfListOfShape itssd(ssd);
1596     TopExp_Explorer exp2;
1597     for(; itssd.More(); itssd.Next()) {
1598       exp2.Init(itssd.Value(), TopAbs_VERTEX);
1599       for(; exp2.More(); exp2.Next()) {
1600         const TopoDS_Shape& exp2Curr = exp2.Current();
1601         exp.Init(C, TopAbs_VERTEX);
1602         for(; exp.More(); exp.Next()) {
1603           if(exp2Curr.IsSame(exp.Current()))
1604             break;
1605         }
1606         if(exp.More())
1607           break;
1608       }
1609       if(exp2.More())
1610         break;
1611     }
1612     
1613     if(exp2.More()) {
1614       const TopoDS_Shape& FSD2 = itssd.Value();
1615       Standard_Integer iFSD = DS.Shape(FSD), iFSD2 = DS.Shape(FSD2);
1616       RemoveFaceSameDomain(iFSD, iFSD2);      
1617 //      DS.UnfillShapesSameDomain(FSD, FSD2);
1618     }
1619   }
1620 }
1621
1622 //=======================================================================
1623 //function : FindGoodFace
1624 //purpose  : 
1625 //=======================================================================
1626
1627 TColStd_ListOfInteger& BRepAlgo_DSAccess::FindGoodFace
1628 (const Standard_Integer iE,
1629  Standard_Integer& iF1,
1630  Standard_Boolean& b)
1631 {
1632 //  myHB->ChangeBuilder();
1633   b = Standard_False;
1634   TColStd_ListOfInteger& loi = myHB->GetDSFaceFromDSEdge(iE, 1);
1635   if(loi.Extent() == 1) {
1636     iF1 = loi.First();
1637     b = Standard_True;
1638     TColStd_ListOfInteger& loi2 = myHB->GetDSFaceFromDSEdge(iE, 2);
1639     return loi2;
1640   }
1641   else {
1642     TColStd_ListOfInteger& loi2 = myHB->GetDSFaceFromDSEdge(iE, 2);
1643     if(loi2.Extent() == 1) {
1644       b = Standard_True;
1645       iF1 = loi2.First();
1646       return loi;
1647     }
1648   }
1649   b = Standard_False;
1650   return myEmptyListOfInteger;
1651 }
1652
1653 //=======================================================================
1654 //function : RemoveFaceSameDomain
1655 //purpose  : 
1656 //=======================================================================
1657
1658 void BRepAlgo_DSAccess::RemoveFaceSameDomain
1659 (const Standard_Integer iF1,
1660  const Standard_Integer iF2)
1661 {
1662   TopOpeBRepDS_DataStructure& DS = myHDS->ChangeDS();
1663   const TopoDS_Shape& F1 = DS.Shape(iF1, FindKeep);
1664   const TopoDS_Shape& F2 = DS.Shape(iF2, FindKeep);
1665   if(F1.IsNull() || F2.IsNull())
1666     return;
1667
1668
1669   Standard_Integer iref1 = DS.SameDomainRef(F1),
1670   iref2 = DS.SameDomainRef(F2), istart, iend;
1671   if(iref1 == iF1)
1672     DS.SameDomainRef(F2,iF2);
1673   if(iref2 == iF1)
1674     DS.SameDomainRef(F1,iF1);
1675   DS.UnfillShapesSameDomain(F1,F2);
1676
1677   if(iref1 != iref2)
1678     return;
1679   Standard_Boolean iF1iF2IsConnected = Standard_False;
1680   TColStd_IndexedMapOfInteger moi;
1681   moi.Clear();
1682   if(iref2 == iF2) {
1683     istart = iF2;
1684     iend = iF1;
1685   }
1686   else {
1687     istart = iF1;
1688     iend = iF2;
1689   }
1690   moi.Add(istart);
1691   Standard_Integer NbConnect = 0, icurr;
1692   while(moi.Extent() > NbConnect) {
1693     NbConnect++;
1694     icurr = moi.FindKey(NbConnect);
1695     DS.SameDomainRef(icurr, istart);
1696     const TopTools_ListOfShape& los = DS.ShapeSameDomain(icurr);
1697     if(los.IsEmpty()) {
1698       const TopoDS_Shape& SNSD = DS.Shape(icurr);
1699       DS.SameDomainRef(SNSD, 0);
1700     }
1701     TopTools_ListIteratorOfListOfShape li(los);
1702     for(; li.More(); li.Next()) {
1703       Standard_Integer iCurrShap = DS.Shape(li.Value(), FindKeep);
1704       if(!iCurrShap)
1705         return;
1706       if(iCurrShap == iend)
1707         iF1iF2IsConnected = Standard_True;
1708       moi.Add(iCurrShap);
1709     }
1710   }
1711   if(!iF1iF2IsConnected) {
1712     moi.Clear();
1713     moi.Add(iend);
1714     NbConnect = 0;
1715     while(moi.Extent() > NbConnect) {
1716       NbConnect++;
1717       icurr = moi.FindKey(NbConnect);
1718       DS.SameDomainRef(icurr, iend);
1719       const TopTools_ListOfShape& los = DS.ShapeSameDomain(icurr);
1720       if(los.IsEmpty()) {
1721         const TopoDS_Shape& SNSD = DS.Shape(icurr);
1722         DS.SameDomainRef(SNSD, 0);
1723       }
1724       TopTools_ListIteratorOfListOfShape li(los);
1725       for(; li.More(); li.Next()) {
1726         Standard_Integer iCurrShap = DS.Shape(li.Value(), FindKeep);
1727         if(!iCurrShap)
1728           return;
1729         moi.Add(iCurrShap);
1730       }
1731     }
1732   }
1733 }
1734
1735 //=======================================================================
1736 //function : DS
1737 //purpose  : 
1738 //=======================================================================
1739
1740 const Handle(TopOpeBRepDS_HDataStructure)&
1741 BRepAlgo_DSAccess::DS() const
1742 {
1743   return myHDS;
1744 }
1745
1746 //=======================================================================
1747 //function : changeDS
1748 //purpose  : 
1749 //=======================================================================
1750 Handle(TopOpeBRepDS_HDataStructure)&
1751 BRepAlgo_DSAccess::ChangeDS()
1752 {
1753   return myHDS;
1754 }
1755
1756 //=======================================================================
1757 //function : Builder
1758 //purpose  : 
1759 //=======================================================================
1760
1761 const Handle(TopOpeBRepBuild_HBuilder)& 
1762 BRepAlgo_DSAccess::Builder() const
1763 {
1764   return myHB;
1765 }
1766
1767 //=======================================================================
1768 //function : ChangeBuilder
1769 //purpose  : 
1770 //=======================================================================
1771
1772 Handle(TopOpeBRepBuild_HBuilder)& 
1773 BRepAlgo_DSAccess::ChangeBuilder()
1774 {
1775   return myHB;
1776 }