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