0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_KPart.cxx
1 // Created on: 1994-08-30
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1994-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 <TopOpeBRepBuild_Builder.jxx>
18
19 #include <TopOpeBRepBuild_GTool.hxx>
20 #include <TopOpeBRepTool.hxx>
21 #include <TopOpeBRepTool_ShapeExplorer.hxx>
22 #include <TopOpeBRepDS_BuildTool.hxx>
23 #include <TopAbs.hxx>
24 #include <TopoDS_Solid.hxx>
25 #include <TopoDS_Shell.hxx>
26 #include <TopoDS_Wire.hxx>
27 #include <TopoDS.hxx>
28 #include <Precision.hxx>
29 #include <TopExp_Explorer.hxx>
30 #include <TopExp.hxx>
31 #include <gp_Pnt.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRep_Builder.hxx>
34 #include <BRepTools.hxx>
35 #include <BRepClass3d.hxx>
36 #include <BRepClass3d_SolidExplorer.hxx>
37 #include <TopOpeBRepTool_EXPORT.hxx>
38 #include <TopOpeBRepTool_SC.hxx>
39 #include <TopOpeBRepDS_EXPORT.hxx>
40 #include <TopOpeBRepDS_connex.hxx>
41 #include <TopOpeBRepBuild_define.hxx>
42 #include <TopOpeBRepBuild_kpresu.hxx>
43 #include <Standard_ProgramError.hxx>
44 #include <TopOpeBRepDS_ShapeShapeInterference.hxx>
45
46 #ifdef OCCT_DEBUG
47 extern Standard_Boolean TopOpeBRepBuild_GettraceKPB();
48 #endif
49
50 static void FUN_Raise() {
51 #ifdef OCCT_DEBUG
52   cout<<"******************************ERROR"<<endl;
53   Standard_ProgramError::Raise("KPart.cxx");
54 #endif
55 }
56
57 #define M_REVERSED(st) (st == TopAbs_REVERSED)
58
59 Standard_EXPORT Standard_Boolean FUNKP_KPiskolesh(const TopOpeBRepBuild_Builder& BU,const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Shape& Sarg,TopTools_ListOfShape& lShsd,TopTools_ListOfShape& lfhsd);
60
61
62 //modified by NIZHNY-MKK  Fri May 19 17:03:59 2000.BEGIN
63 enum TopOpeBRepBuild_KPart_Operation {TopOpeBRepBuild_KPart_Operation_Fuse, TopOpeBRepBuild_KPart_Operation_Common, TopOpeBRepBuild_KPart_Operation_Cut12, TopOpeBRepBuild_KPart_Operation_Cut21};
64
65 static void LocalKPisdisjanalyse(const TopAbs_State Stsol1, const TopAbs_State  Stsol2,
66                                  const TopOpeBRepBuild_KPart_Operation& theOperation,
67                                  Standard_Integer& ires, Standard_Integer& icla1, Standard_Integer& icla2);
68
69 static TopoDS_Solid BuildNewSolid(const TopoDS_Solid& sol1, 
70                                   const TopoDS_Solid& sol2, 
71                                   const TopAbs_State stsol1, 
72                                   const TopAbs_State stsol2,
73                                   const Standard_Integer ires, 
74                                   const Standard_Integer icla1, 
75                                   const Standard_Integer icla2,
76                                   const TopAbs_State theState1,
77                                   const TopAbs_State theState2);
78
79 static Standard_Boolean disjPerformFuse(const TopTools_IndexedMapOfShape& theMapOfSolid1, 
80                                         const TopTools_IndexedMapOfShape& theMapOfSolid2,                                       
81                                         TopTools_IndexedMapOfShape& theMapOfResult);
82
83 static Standard_Boolean disjPerformCommon(const TopTools_IndexedMapOfShape& theMapOfSolid1, 
84                                           const TopTools_IndexedMapOfShape& theMapOfSolid2,                                     
85                                           TopTools_IndexedMapOfShape& theMapOfResult);
86
87 static Standard_Boolean disjPerformCut(const TopTools_IndexedMapOfShape& theMapOfSolid1, 
88                                        const TopTools_IndexedMapOfShape& theMapOfSolid2,                                        
89                                        TopTools_IndexedMapOfShape& theMapOfResult);
90 //modified by NIZHNY-MKK  Fri May 19 17:04:07 2000.END
91
92
93 //=======================================================================
94 //function : FindIsKPart
95 //purpose  : 
96 //=======================================================================
97
98 Standard_Integer TopOpeBRepBuild_Builder::FindIsKPart()
99 {
100   KPClearMaps();
101   
102 #ifdef OCCT_DEBUG
103   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
104   if(TKPB){cout<<endl<<"--- IsKPart ? ---"<<endl;}
105 #endif
106   
107   Standard_Integer isfafa = KPisfafa();
108   // face,face SameDomain
109   if (isfafa) {
110     myIsKPart = 3;
111     return KPreturn(myIsKPart);
112   }
113   
114   Standard_Integer isdisj = KPisdisj();
115   // shape,shape sans aucune interference geometrique
116   if (isdisj) {
117     myIsKPart = 2;
118     return KPreturn(myIsKPart);
119   }
120   
121   Standard_Integer iskole = KPiskole();
122   // solide,solide colles par faces tangentes sans aretes tangentes
123   if (iskole) {
124     myIsKPart = 1;
125     return KPreturn(myIsKPart);
126   }
127   
128   Standard_Integer iskoletge = KPiskoletge();
129   // solide,solide par faces tangentes avec aretes tangentes
130   if (iskoletge) {
131     myIsKPart = 5;
132     return KPreturn(myIsKPart);
133   }
134   
135   Standard_Integer issoso = KPissoso();
136   // solide,solide quelconques
137   if (issoso) {
138     myIsKPart = 4;
139     return KPreturn(myIsKPart);
140   }
141   
142   myIsKPart = 0;
143   return KPreturn(myIsKPart);
144 }
145
146 //=======================================================================
147 //function : IsKPart
148 //purpose  : 
149 //=======================================================================
150
151 Standard_Integer TopOpeBRepBuild_Builder::IsKPart() const 
152 {
153   return myIsKPart;
154 }
155
156
157 //=======================================================================
158 //function : MergeKPart
159 //purpose  : 
160 //=======================================================================
161
162 void TopOpeBRepBuild_Builder::MergeKPart(const TopAbs_State TB1,
163                                          const TopAbs_State TB2)
164 {
165   myState1 = TB1;
166   myState2 = TB2;
167   MergeKPart();  
168 }
169
170 //=======================================================================
171 //function : MergeKPart
172 //purpose  : 
173 //=======================================================================
174
175 void TopOpeBRepBuild_Builder::MergeKPart()
176 {
177   if ( myIsKPart == 1 ) { // iskole
178     MergeKPartiskole();
179   }
180   else if ( myIsKPart == 5 ) { // iskoletge
181     MergeKPartiskoletge();
182   }
183   else if (myIsKPart == 2) { // isdisj
184     MergeKPartisdisj();
185   }
186   else if ( myIsKPart == 3 ) { // isfafa
187     MergeKPartisfafa();
188   }
189   else if ( myIsKPart == 4 ) { // issoso
190     MergeKPartissoso();
191   }
192   End();
193 }
194
195 static void FUN_sortplcy(const TopTools_ListOfShape& lof, TopTools_ListOfShape& lopl, TopTools_ListOfShape& locy)
196 {
197   TopTools_ListIteratorOfListOfShape it(lof);
198   for (; it.More(); it.Next()){
199     const TopoDS_Face& ff = TopoDS::Face(it.Value());
200     Standard_Boolean plane    = FUN_tool_plane(ff);
201     if (plane)   {lopl.Append(ff);}
202     Standard_Boolean cylinder = FUN_tool_cylinder(ff);
203     if (cylinder){locy.Append(ff);} 
204   }
205 }
206
207 /*static Standard_Boolean FUN_proj2(const TopOpeBRepBuild_Builder& BU, const Handle(TopOpeBRepDS_HDataStructure)& HDS, 
208                      const TopoDS_Shape& Fa2, TopTools_DataMapOfShapeListOfShape& EnewE)
209 {
210   const TopoDS_Face& F2 = TopoDS::Face(Fa2);
211   TopoDS_Wire Ow2 = BRepTools::OuterWire(TopoDS::Face(F2));
212   TopExp_Explorer exe(Ow2, TopAbs_EDGE);
213   for (; exe.More(); exe.Next()){
214     const TopoDS_Shape& ed = exe.Current();
215     Standard_Boolean issplit = BU.IsSplit(ed,TopAbs_ON);
216     if (!issplit) return Standard_False;
217     const TopTools_ListOfShape& speds = BU.Splits(ed,TopAbs_ON);
218     TopTools_ListOfShape lfcF2; // faces of shapei connexed to ed
219     FDSCNX_FaceEdgeConnexFaces(TopoDS::Face(F2),ed,HDS,lfcF2);
220     // prequesitory : ed in {edges of Ow2} 
221     //                ed's faces ancestor = {F2,fofj}
222     if (lfcF2.Extent() != 1) return Standard_False; 
223     const TopoDS_Face& fcF2 = TopoDS::Face(lfcF2.First());
224
225     // projecting sp(ed) on faces F2 and fofj
226     TopTools_ListOfShape newesp;
227     TopTools_ListIteratorOfListOfShape itspe(speds);
228     for (; itspe.More(); itspe.Next()){
229       TopoDS_Edge esp = TopoDS::Edge(itspe.Value());
230       Standard_Boolean ok = FUN_tool_pcurveonF(F2,esp);
231       if (!ok) return Standard_False; 
232       ok     = FUN_tool_pcurveonF(fcF2,esp); 
233       if (!ok) return Standard_False; 
234 //      EnewE.Add(esp,newesp);
235       newesp.Append(esp);
236     }
237     EnewE.Bind(ed,newesp);
238   }
239   return Standard_True;
240 }*/  
241
242 static void FUN_addf(const TopAbs_State sta, const TopoDS_Shape& ftoadd, TopTools_DataMapOfShapeShape& map)
243 {
244 #ifdef OCCT_DEBUG
245 //  Standard_Boolean isadded = map.IsBound(ftoadd);
246 #endif
247   TopoDS_Shape fori = ftoadd;
248   if (sta == TopAbs_IN) fori.Complement();
249   map.Bind(fori,fori);  
250 }
251
252 static Standard_Integer FUN_comparekoletgesh(TopOpeBRepTool_ShapeClassifier& SC,
253                                 const TopoDS_Shape& sh1, const TopoDS_Shape& sh2,
254                                 const TopoDS_Shape& fkole1, const TopoDS_Shape& )
255 // purpose: <sh1> and <sh2> are kpkoletge on faces <fkole1>,<fkole2>
256 //          with <fkole1> same oriented with <fkole2>
257 //          returns k=1,2 if shi is contained in shk
258 //          else returns 0
259 {
260   SC.SetReference(sh2);
261   TopExp_Explorer exf(sh1,TopAbs_FACE);
262   for (; exf.More(); exf.Next()){
263     const TopoDS_Face& f1 = TopoDS::Face(exf.Current());
264     if (f1.IsSame(fkole1)) continue;
265     gp_Pnt pnt1;
266     BRepClass3d_SolidExplorer::FindAPointInTheFace(f1,pnt1);
267     SC.StateP3DReference(pnt1);
268     TopAbs_State stpnt1 = SC.State();
269     if (stpnt1 == TopAbs_IN)  return 2;
270     if (stpnt1 == TopAbs_OUT) return 1;
271   }
272   return 0;
273 }
274
275 static Standard_Boolean FUN_changev(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Shape& v)
276 {  
277   Standard_Boolean changev = HDS->HasShape(v);
278   if (!changev) return Standard_False;
279   changev = HDS->HasSameDomain(v);
280   if (!changev) return Standard_False;
281   Standard_Boolean rankv = HDS->DS().AncestorRank(v);
282   changev = (rankv == 2);
283   return changev;
284 }
285 static Standard_Boolean FUN_updatev
286 (const Handle(TopOpeBRepDS_HDataStructure)& HDS, TopoDS_Edge& newed, 
287  const TopoDS_Vertex& v, const TopAbs_Orientation oriv, const Standard_Real parv, const Standard_Boolean changev)
288 {
289   TopOpeBRepDS_BuildTool BT;
290   BRep_Builder BB;
291   if (changev) {
292     TopoDS_Shape oov; Standard_Boolean ok = FUN_ds_getoov(v,HDS,oov);
293     if(!ok) return Standard_False;
294     oov.Orientation(oriv);
295     BB.Add(newed,oov); 
296     BT.Parameter(newed,oov,parv); 
297   }
298   else {
299     TopoDS_Shape aLocalShape = v.Oriented(oriv);
300     TopoDS_Vertex ov = TopoDS::Vertex(aLocalShape);
301 //    TopoDS_Vertex ov = TopoDS::Vertex(v.Oriented(oriv));
302     BB.Add(newed,ov); 
303     BT.Parameter(newed,ov,parv);
304   }
305   return Standard_True;
306 }
307
308 static Standard_Boolean FUN_makefaces(const TopOpeBRepBuild_Builder& BU, const Handle(TopOpeBRepDS_HDataStructure)& HDS, TopTools_DataMapOfShapeListOfShape& EnewE, 
309                          const TopoDS_Shape& f, const TopoDS_Shape& , TopTools_ListOfShape& newfaces)     
310 //prequesitory : <outerwi>=<f>'s outer wire
311 //purpose      : <outerwi>={edow}, 
312 //               edow=(vf,vl), if(rank(vj)=2 && vj sdm vj1), replace vj by vj1
313 // <f> gives <newf>  
314    
315 {  
316   TopOpeBRepDS_BuildTool BT;
317   BRep_Builder BB;
318   TopoDS_Shape aLocalShape = f.Oriented(TopAbs_FORWARD);
319   TopoDS_Face F = TopoDS::Face(aLocalShape); // working on FORWARD face
320 //  TopoDS_Face F = TopoDS::Face(f.Oriented(TopAbs_FORWARD)); // working on FORWARD face
321   TopAbs_Orientation of = f.Orientation();
322
323   //the new outer wire :
324   // -------------------
325   TopTools_ListOfShape loe;
326   // -------
327   TopoDS_Wire outerwf = BRepTools::OuterWire(F);
328   TopExp_Explorer ex(outerwf, TopAbs_EDGE);
329   for (; ex.More(); ex.Next()){
330     const TopoDS_Edge& ed = TopoDS::Edge(ex.Current());   
331     TopAbs_Orientation oe = ed.Orientation();
332     Standard_Boolean issplit = BU.IsSplit(ed,TopAbs_ON);
333     Standard_Boolean isbound = EnewE.IsBound(ed);
334
335     if (!isbound && !issplit) {
336       // new edge
337       TopoDS_Vertex vf,vl; TopExp::Vertices(ed,vf,vl);
338       Standard_Boolean changevf = ::FUN_changev(HDS,vf);
339       Standard_Boolean changevl = ::FUN_changev(HDS,vl);
340       Standard_Boolean changee = changevf || changevl;
341       if (changee) {
342         Standard_Real ff = BRep_Tool::Parameter(vf, ed); 
343         Standard_Real l  = BRep_Tool::Parameter(vl, ed);
344
345         TopoDS_Edge newed; BT.CopyEdge(ed.Oriented(TopAbs_FORWARD),newed);
346         Standard_Boolean ok = ::FUN_updatev(HDS,newed,vf,TopAbs_FORWARD,ff,changevf); 
347         if (!ok) return Standard_False;
348         ok     = ::FUN_updatev(HDS,newed,vl,TopAbs_REVERSED,l,changevl); 
349         if (!ok) return Standard_False;
350         newed.Orientation(oe);
351         TopTools_ListOfShape led; led.Append(newed); EnewE.Bind(ed,led);
352         isbound = Standard_True;
353       }      
354     }
355
356     if (issplit) {  
357       const TopTools_ListOfShape& speds = BU.Splits(ed,TopAbs_ON);      
358       if (speds.Extent() == 0) return Standard_False;
359       const TopoDS_Edge& spe = TopoDS::Edge(speds.First()); 
360       Standard_Boolean sameori = FUN_tool_SameOri(ed,spe);
361       TopAbs_Orientation orisp = spe.Orientation();
362       if (!sameori) orisp = TopAbs::Complement(orisp);
363         
364       TopTools_ListIteratorOfListOfShape it(speds);
365       for (; it.More(); it.Next()) {
366         TopoDS_Edge esp = TopoDS::Edge(it.Value());
367         Standard_Boolean ok = FUN_tool_pcurveonF(TopoDS::Face(f),esp); 
368         if (!ok) return Standard_False;
369         TopoDS_Shape ee = esp.Oriented(orisp);
370         loe.Append(ee);
371       }
372     }
373     else if (isbound) {
374       const TopTools_ListOfShape& neweds = EnewE.ChangeFind(ed);
375       TopTools_ListIteratorOfListOfShape itnes(neweds);
376       for (; itnes.More(); itnes.Next()) loe.Append(itnes.Value().Oriented(oe));
377     }
378     else
379       loe.Append(ed);    
380   }
381
382   TopoDS_Wire newW;
383   //---------------
384   BB.MakeWire(newW);
385   for (TopTools_ListIteratorOfListOfShape itee(loe); itee.More(); itee.Next()) 
386     BB.Add(newW,itee.Value());
387
388   // the new face :
389   // --------------
390   aLocalShape = F.EmptyCopied();
391   TopoDS_Face newf = TopoDS::Face(aLocalShape);
392 //  TopoDS_Face newf = TopoDS::Face(F.EmptyCopied());
393   BB.Add(newf,newW);
394   
395   // other wires of <f> :
396   TopExp_Explorer exw(F, TopAbs_WIRE);
397   for (; exw.More(); exw.Next()){
398     const TopoDS_Wire OOw = TopoDS::Wire(exw.Current());
399     if (OOw.IsSame(outerwf)) continue;
400     BB.Add(newf,OOw);    
401   }
402   
403   if (M_REVERSED(of)) newf.Orientation(TopAbs_REVERSED);  
404
405   // xpu140898 : CTS21251
406   TopoDS_Face Newf = newf;
407   Standard_Boolean ok = TopOpeBRepTool::CorrectONUVISO(TopoDS::Face(f),Newf);
408   if (ok) newfaces.Append(Newf);
409   else    newfaces.Append(newf);
410
411   return Standard_True;
412 }
413
414 static Standard_Boolean FUN_rebuildfc(const TopOpeBRepBuild_Builder& BU, const Handle(TopOpeBRepDS_HDataStructure)& HDS, 
415                          const TopAbs_State , const TopoDS_Shape& Fk,
416                          TopTools_DataMapOfShapeListOfShape& EnewE, TopTools_IndexedDataMapOfShapeListOfShape& fcnewfc)
417 //              Owk = <Fk>'s outer wire
418 //prequesitory: Owk = {edk}, Splits(edk,Stk) = spedk
419 //purpose: fills up <fcnewfc> = {(fcFk,newfcFk)}
420 //         with {fcFk} = faces of shape k connexed to Owk
421 //         fcFk has edges {edk}
422 {
423 #ifdef OCCT_DEBUG
424 //  const TopOpeBRepDS_DataStructure& BDS = HDS->DS();
425 //  Standard_Integer rFk = BDS.AncestorRank(Fk);
426 #endif
427   TopoDS_Wire Owk = BRepTools::OuterWire(TopoDS::Face(Fk));
428   TopTools_ListOfShape eds; FUN_tool_shapes(Owk,TopAbs_EDGE,eds);
429   TopTools_ListIteratorOfListOfShape ite(eds);  
430
431   ite.Initialize(eds);
432   for (; ite.More(); ite.Next()){
433     const TopoDS_Shape& ed = ite.Value();
434     TopTools_ListOfShape lfcFk; // faces of shapei connexed to ed
435     FDSCNX_FaceEdgeConnexFaces(TopoDS::Face(Fk),ed,HDS,lfcFk);
436     // prequesitory : ed in {edges of Owk} 
437     //                ed's faces ancestor = {Fk,fofj}
438     if (lfcFk.Extent() != 1) return Standard_False; 
439
440     // purpose : Building up new topologies on connexed faces
441     //           attached to outer wire's edges.
442     const TopoDS_Shape& fcFk = lfcFk.First();
443     TopTools_ListOfShape newfcFk; Standard_Boolean ok = FUN_makefaces(BU,HDS,EnewE,fcFk,Owk,newfcFk);
444     if (!ok) return Standard_False;
445     fcnewfc.Add(fcFk,newfcFk);
446   } 
447   return Standard_True;
448 } // FUN_rebuildfc
449
450 #ifdef OCCT_DEBUG
451 Standard_EXPORT void debiskoletge() {}
452 #endif
453
454 //=======================================================================
455 //function : MergeKPartiskoletge
456 //purpose  : 
457 //=======================================================================
458
459 void TopOpeBRepBuild_Builder::MergeKPartiskoletge()
460 {
461 #ifdef OCCT_DEBUG
462   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
463   if (TKPB) KPreturn(myIsKPart);
464   debiskoletge();
465 #endif
466
467   const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
468 //  Standard_Integer ibid;
469   
470   if ( myIsKPart != 5 ) {FUN_Raise(); return;}
471   
472   GMapShapes(myShape1,myShape2);
473   // NYI : on doit pouvoir faire l'economie du mapping GMapShapes(...)
474   // NYI en allant chercher l'indice 1,2 retourne par GShapeRank(S)
475   // NYI dans la DS. l'index est defini pour tous les shapes HasSameDomain
476   
477   TopTools_ListOfShape& lmergesha1 = ChangeMerged(myShape1,myState1);
478   ChangeMerged(myShape2,myState2);
479   
480   TopTools_ListOfShape lShsd1,lShsd2; // liste de solides HasSameDomain
481   TopTools_ListOfShape lfhsd1,lfhsd2; // liste de faces HasSameDomain
482   KPiskoletgesh(myShape1,lShsd1,lfhsd1);
483   KPiskoletgesh(myShape2,lShsd2,lfhsd2);
484
485   // traitement de tous les solides NYI 
486   TopoDS_Shape sol1 = lShsd1.First();
487   TopoDS_Shape sol2 = lShsd2.First(); 
488
489   ChangeMerged(sol1,myState1); 
490   ChangeMerged(sol2,myState2);
491   
492   TopTools_ListOfShape lplhsd1, lcyhsd1; ::FUN_sortplcy(lfhsd1,lplhsd1,lcyhsd1);
493   TopTools_ListOfShape lplhsd2, lcyhsd2; ::FUN_sortplcy(lfhsd2,lplhsd2,lcyhsd2);
494   const TopoDS_Face& fac1 = TopoDS::Face(lplhsd1.First());
495   const TopoDS_Face& fac2 = TopoDS::Face(lplhsd2.First()); 
496 #ifdef OCCT_DEBUG
497   Standard_Integer iF1 =
498 #endif
499             myDataStructure->Shape(fac1); //DEB
500 #ifdef OCCT_DEBUG
501   Standard_Integer iF2 =
502 #endif
503             myDataStructure->Shape(fac2); //DEB
504
505 #ifdef OCCT_DEBUG
506   if (TKPB) {cout<<""<<endl;cout<<"face "<<iF1<<" : ";cout<<iF2<<endl;}
507 #endif
508     
509   TopOpeBRepDS_Config config2 = BDS.SameDomainOri(fac2);
510
511   Standard_Boolean SameOriented = (config2 == TopOpeBRepDS_SAMEORIENTED);
512   
513   const TopoDS_Shape* pfGRE = NULL;
514   const TopoDS_Shape* pfSMA = NULL;
515
516   Standard_Integer rgre = 1;
517   if (SameOriented) {
518     // getting greater 
519     rgre = ::FUN_comparekoletgesh(myShapeClassifier,
520                                   myShape1,myShape2,fac1,fac2);
521     if (rgre == 0) rgre = FUN_tool_comparebndkole(myShape1,myShape2);    
522   }
523   if (rgre == 0) {FUN_Raise(); return;}
524
525   // ires :
526   //-------
527   Standard_Integer rsma    = (rgre == 1)? 2: 1;
528   pfSMA       = (rsma == 1)? &fac1:    &fac2;
529   pfGRE       = (rgre == 1)? &fac1:    &fac2;
530   TopAbs_State staSMA = (rsma == 1)? myState1: myState2;
531   TopAbs_State staGRE = (rgre == 1)? myState1: myState2;
532
533   TopoDS_Shape shaSMA = (rsma == 1)? myShape1: myShape2;
534   TopoDS_Shape shaGRE = (rgre == 1)? myShape1: myShape2;
535
536   Standard_Integer ires = 0; KPiskoletgeanalyse(config2,staSMA,staGRE,ires);
537   
538   // merge :
539   //-------  
540   TopoDS_Shape sheSMA; // sheSMA = shell accedant facSMA
541   TopTools_IndexedDataMapOfShapeListOfShape MfacsheSMA;
542   TopExp::MapShapesAndAncestors(shaSMA,TopAbs_FACE,TopAbs_SHELL,MfacsheSMA);
543   const TopTools_ListOfShape& lsheSMA = MfacsheSMA.FindFromKey(*pfSMA);
544   TopTools_ListIteratorOfListOfShape itlsheSMA(lsheSMA);
545   sheSMA = itlsheSMA.Value(); 
546   
547   TopoDS_Shape sheGRE; // sheGRE = shell accedant facGRE
548   TopTools_IndexedDataMapOfShapeListOfShape MfacsheGRE;
549   TopExp::MapShapesAndAncestors(shaGRE,TopAbs_FACE,TopAbs_SHELL,MfacsheGRE);
550   const TopTools_ListOfShape& lsheGRE = MfacsheGRE.FindFromKey(*pfGRE);
551   TopTools_ListIteratorOfListOfShape itlsheGRE(lsheGRE); 
552   sheGRE = itlsheGRE.Value();
553
554   ChangeMerged(sheSMA, staSMA);
555   ChangeMerged(sheGRE, staGRE);
556     
557   TopoDS_Shell newshe;
558   if      (ires == RESNULL) {
559     return;
560   }
561   else if (ires == RESSHAPE1) {
562     myBuildTool.MakeShell(newshe);
563     newshe = TopoDS::Shell(sheSMA);
564   }
565   else if (ires == RESSHAPE2) {
566     myBuildTool.MakeShell(newshe);
567     newshe = TopoDS::Shell(sheGRE);
568   }
569   else if (ires == RESNEWSOL) {
570     
571     TopTools_DataMapOfShapeShape addedfaces;
572     // As splits of outer wire's edges have 2drep only on shape1,
573     // we have to project them on the connexed faces of shape2
574     TopTools_DataMapOfShapeListOfShape EnewE; 
575 //    Standard_Boolean ok = ::FUN_proj2((*this),myDataStructure,fac2,EnewE);    
576 //    if (!ok) {FUN_Raise(); return;}
577     
578     // new topologies :
579     TopTools_IndexedDataMapOfShapeListOfShape fcnewfcSMA;// faces connexed to fSMA built up with the split of outerwSMA
580     TopTools_IndexedDataMapOfShapeListOfShape fcnewfcGRE;// faces connexed to fGRE built up with the split of outerwGRE    
581     Standard_Boolean ok = ::FUN_rebuildfc((*this),myDataStructure,staSMA,*pfSMA,EnewE,fcnewfcSMA);
582     if (!ok) {FUN_Raise(); return;}
583     Standard_Integer nfcSMA = fcnewfcSMA.Extent();
584 //    for (Standard_Integer i=1; i<=nfcSMA; i++) {
585     Standard_Integer i ;
586     for ( i=1; i<=nfcSMA; i++) {
587       const TopoDS_Shape& f = fcnewfcSMA.FindKey(i);
588       const TopTools_ListOfShape& newlf = fcnewfcSMA.FindFromIndex(i);
589
590       TopTools_ListIteratorOfListOfShape it(newlf);
591       for (; it.More(); it.Next()){
592         const TopoDS_Shape& ff = it.Value();
593         ::FUN_addf(staSMA,ff,addedfaces);
594         ChangeMerged(f,staSMA).Append(ff);
595       }
596     } // fcnewfcSMA
597     ok     = ::FUN_rebuildfc((*this),myDataStructure,staGRE,*pfGRE,EnewE,fcnewfcGRE);
598     if (!ok) {FUN_Raise(); return;}
599     Standard_Integer nfcGRE = fcnewfcGRE.Extent();
600     for (i=1; i<=nfcGRE; i++) {
601       const TopoDS_Shape& f = fcnewfcGRE.FindKey(i);
602       const TopTools_ListOfShape& newlf = fcnewfcGRE.FindFromIndex(i);
603
604       TopTools_ListIteratorOfListOfShape it(newlf);
605       for (; it.More(); it.Next()){
606         const TopoDS_Shape& ff = it.Value();
607         ::FUN_addf(staGRE,ff,addedfaces);
608         ChangeMerged(f,staGRE).Append(ff);
609       }
610     } // fcnewfcGRE
611
612     // old topologies :
613     TopTools_ListOfShape lOOfSMA; // DEB : faces of SMA non connexed to fSMA
614     TopTools_ListOfShape lOOfGRE; // DEB : faces of GRE non connexed to fGRE
615     TopExp_Explorer exSMA(shaSMA, TopAbs_FACE);
616     for (; exSMA.More(); exSMA.Next()){
617       const TopoDS_Shape& ff = exSMA.Current();
618       if (fcnewfcSMA.Contains(ff)) continue;
619       if (ff.IsSame(*pfSMA)) continue;
620       lOOfSMA.Append(ff); // DEB
621       ::FUN_addf(staSMA,ff,addedfaces);
622     }
623     TopExp_Explorer exGRE(shaGRE, TopAbs_FACE);
624     for (; exGRE.More(); exGRE.Next()){
625       const TopoDS_Shape& ff = exGRE.Current();
626       if (fcnewfcGRE.Contains(ff)) continue;
627       if (ff.IsSame(*pfGRE)) continue;
628       lOOfGRE.Append(ff); // DEB
629       ::FUN_addf(staGRE,ff,addedfaces);
630     }
631    
632     // newshell :
633     TopTools_DataMapIteratorOfDataMapOfShapeShape itadd(addedfaces);
634     Standard_Boolean yauadd = itadd.More();
635     if (yauadd) {
636       myBuildTool.MakeShell(newshe);
637       myBuildTool.Closed(newshe,Standard_True);  // NYI : check exact du caractere closed du shell
638     }
639     for (; itadd.More(); itadd.Next() ) {
640       const TopoDS_Shape& ftoadd = itadd.Key();
641       myBuildTool.AddShellFace(newshe,ftoadd);
642     }
643     
644   } // RESNEWSOL  
645
646   TopoDS_Solid newsol;
647   if ( !newshe.IsNull() ) {
648     myBuildTool.MakeSolid(newsol);
649     myBuildTool.AddSolidShell(newsol,newshe);
650   }
651   
652   // le solide final
653   if ( !newsol.IsNull() ) {
654     lmergesha1.Append(newsol);
655   }
656   
657 } // MergeKPartiskoletge
658
659 //=======================================================================
660 //function : MergeKPartisdisj
661 //purpose  : 
662 //=======================================================================
663
664 void TopOpeBRepBuild_Builder::MergeKPartisdisj()
665 {
666 #ifdef OCCT_DEBUG
667   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
668   if (TKPB) KPreturn(myIsKPart);
669 #endif
670   
671   if (myIsKPart != 2) return; // isdisj
672   
673   TopTools_ListOfShape& lmergesha1 = ChangeMerged(myShape1,myState1);
674 /*  TopTools_ListOfShape& lmergesha2 =*/ ChangeMerged(myShape2,myState2);
675   
676   Standard_Boolean soldisj = Standard_False;
677   TopOpeBRepTool_ShapeExplorer exsol1(myShape1,TopAbs_SOLID);
678   Standard_Boolean hassol1 = exsol1.More();
679   TopOpeBRepTool_ShapeExplorer exsol2(myShape2,TopAbs_SOLID);
680   Standard_Boolean hassol2 = exsol2.More();
681   soldisj = (hassol1 && hassol2);
682
683 //modified by NIZHNY-MKK  Fri May 19 16:18:12 2000.BEGIN  
684   Standard_Boolean hasnotsol1=Standard_False;
685   Standard_Boolean hasnotsol2=Standard_False;
686   TopExp_Explorer anExp(myShape1, TopAbs_SHELL, TopAbs_SOLID);
687   for(Standard_Integer i=TopAbs_SHELL; i <= TopAbs_VERTEX && !hasnotsol1 && !hasnotsol2; i++) {
688     anExp.Init(myShape1, (TopAbs_ShapeEnum)i, TopAbs_SOLID);
689     if(anExp.More())
690       hasnotsol1 = Standard_True;
691     anExp.Init(myShape2, (TopAbs_ShapeEnum)i, TopAbs_SOLID);
692     if(anExp.More())
693       hasnotsol2 = Standard_True;
694   }
695   soldisj = !(hasnotsol1 || hasnotsol2);
696 //modified by NIZHNY-MKK  Fri May 19 16:18:16 2000.END
697   
698   TopoDS_Solid sol1; TopoDS_Shell outsha1;
699   TopoDS_Solid sol2; TopoDS_Shell outsha2;
700   
701   if ( soldisj ) {
702 //modified by NIZHNY-MKK  Fri May 19 16:47:19 2000.BEGIN
703     TopTools_IndexedMapOfShape aMapOfSolid1, aMapOfSolid2;
704     TopExp::MapShapes(myShape1, TopAbs_SOLID, aMapOfSolid1);
705     TopExp::MapShapes(myShape2, TopAbs_SOLID, aMapOfSolid2);
706
707     if(aMapOfSolid1.Extent() > 1 || aMapOfSolid2.Extent() > 1) {
708       TopTools_IndexedMapOfShape aMapOfResult;
709       if(Opefus()) {
710         if(!disjPerformFuse(aMapOfSolid1, aMapOfSolid2, aMapOfResult))
711           return;
712       }
713       else if(Opec12()) {
714         if(!disjPerformCut(aMapOfSolid1, aMapOfSolid2, aMapOfResult))
715           return;
716       }
717       else if(Opec21()) {
718         if(!disjPerformCut(aMapOfSolid2, aMapOfSolid1, aMapOfResult))
719           return;
720       }
721       else if(Opecom()) {
722         if(!disjPerformCommon(aMapOfSolid1, aMapOfSolid2, aMapOfResult))
723           return;
724       }      
725       for(Standard_Integer ii=1; ii<=aMapOfResult.Extent(); ii++) {
726         lmergesha1.Append(aMapOfResult(ii));
727       }      
728       return;
729     } //end if(aMapOfSolid1.Extent() > 1 || aMapOfSolid2.Extent() > 1)
730     else {
731 //modified by NIZHNY-MKK  Fri May 19 16:47:23 2000.END
732       sol1 = TopoDS::Solid(exsol1.Current());
733       ChangeMerged(sol1,myState1);
734       outsha1 = BRepClass3d::OuterShell(sol1);
735       
736       sol2 = TopoDS::Solid(exsol2.Current());
737       ChangeMerged(sol2,myState2);
738       outsha2 = BRepClass3d::OuterShell(sol2);
739       
740       TopAbs_State stsol1 = KPclasSS(outsha1,sol2);
741       TopAbs_State stsol2 = KPclasSS(outsha2,sol1);
742       
743       Standard_Integer ires,icla1,icla2;
744       KPisdisjanalyse(stsol1,stsol2,ires,icla1,icla2);
745       
746       if      (ires == RESUNDEF)  {
747         return;
748       }
749       
750       else if (icla1 == SHEUNDEF || icla2 == SHEUNDEF) {
751         return;
752       }
753       
754       else if (ires == RESNULL) {
755         return;
756       }
757       
758       else if (ires == RESSHAPE12) {
759         lmergesha1.Append(myShape1);
760         lmergesha1.Append(myShape2);
761         return;
762       }
763       
764       else if (ires == RESSHAPE1) {
765         lmergesha1.Append(myShape1);
766         return;
767       }
768       
769       else if (ires == RESSHAPE2) {
770         lmergesha1.Append(myShape2);
771         return;
772       }
773       
774       else if (ires == RESNEWSHA1 ||
775                ires == RESNEWSHA2) {
776       //modified by NIZHNY-MKK  Tue May 23 11:36:33 2000.BEGIN
777         TopoDS_Solid newsol = BuildNewSolid(sol1, sol2, stsol1, stsol2, ires, icla1, icla2, myState1, myState2);
778       //modified by NIZHNY-MKK  Tue May 23 11:36:39 2000.END      
779         lmergesha1.Append(newsol);
780         return;
781       }    
782       else {
783 #ifdef OCCT_DEBUG
784         cout<<"TopOpeBRepBuild_MergeKPart soldisj : ires = "<<ires<<endl;
785 #endif
786         return;
787       }
788 //modified by NIZHNY-MKK  Tue May 23 11:37:15 2000
789     } //end else of if(aMapOfSolid1.Extent() > 1 || aMapOfSolid2.Extent() > 1)
790     
791   } // if (soldisj)
792   else { //
793
794     if      (Opec12()) {
795       lmergesha1.Append(myShape1);
796     }
797     else if (Opec21()) {
798       lmergesha1.Append(myShape2);
799     }
800     else if (Opecom()) {
801       lmergesha1.Clear();
802     }
803     else if (Opefus()) {
804       lmergesha1.Append(myShape1);
805       lmergesha1.Append(myShape2);
806     }
807     else return;
808
809   } // ( !soldisj )
810   
811   return;
812   
813 } // MergeKPartisdisj
814
815 //=======================================================================
816 //function : MergeKPartisfafa
817 //purpose  : 
818 //=======================================================================
819
820 void TopOpeBRepBuild_Builder::MergeKPartisfafa()
821 {
822 #ifdef OCCT_DEBUG
823   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
824   if (TKPB) KPreturn(myIsKPart);
825 #endif
826   
827   if ( myIsKPart == 3 ) { // isfafa
828     
829     TopExp_Explorer ex;
830     ex.Init(myShape1,TopAbs_FACE); if (! ex.More() ) return;
831     TopoDS_Shape F1 = ex.Current();
832     ex.Init(myShape2,TopAbs_FACE); if (! ex.More() ) return;
833     TopoDS_Shape F2 = ex.Current();
834     
835     TopTools_ListOfShape LF1,LF2;
836     GFindSamDom(F1,LF1,LF2);
837     
838     TopAbs_ShapeEnum tf = TopAbs_FACE;
839     TopOpeBRepBuild_GTopo G;
840     if      (Opec12()) G=TopOpeBRepBuild_GTool::GCutSame(tf,tf);
841     else if (Opec21()) G=TopOpeBRepBuild_GTool::GCutSame(tf,tf).CopyPermuted();
842     else if (Opecom()) G=TopOpeBRepBuild_GTool::GComSame(tf,tf);
843     else if (Opefus()) G=TopOpeBRepBuild_GTool::GFusSame(tf,tf);
844     else return;
845     
846     GMapShapes(myShape1,myShape2);
847     GMergeFaces(LF1,LF2,G);
848     
849     if (myShape1.ShapeType() == TopAbs_COMPOUND) {
850       TopTools_ListOfShape& L1 = ChangeMerged(myShape1,myState1);
851       L1 = ChangeMerged(F1,myState1);
852     }
853     
854     if (myShape2.ShapeType() == TopAbs_COMPOUND) {
855       TopTools_ListOfShape& L2 = ChangeMerged(myShape2,myState2);
856       L2 = ChangeMerged(F2,myState2);
857     }
858     
859   }
860   
861 } // MergeKPartisfafa
862
863 //=======================================================================
864 //function : MergeKPartissoso
865 //purpose  : 
866 //=======================================================================
867
868 void TopOpeBRepBuild_Builder::MergeKPartissoso()
869 {
870 #ifdef OCCT_DEBUG
871   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
872   if (TKPB) KPreturn(myIsKPart);
873 #endif
874   
875   if ( myIsKPart == 4 ) { // issoso
876     
877     TopExp_Explorer ex;
878     
879     TopoDS_Shape SO1;
880     if (!myShape1.IsNull()) {
881       ex.Init(myShape1,TopAbs_SOLID); 
882       if (! ex.More() ) return;
883       SO1 = ex.Current();
884     }
885     
886     TopoDS_Shape SO2;
887     if (!myShape2.IsNull()) {
888       ex.Init(myShape2,TopAbs_SOLID); 
889       if (! ex.More() ) return;
890       SO2 = ex.Current();
891     }
892     
893     if (SO1.IsNull()) return;
894     
895     TopTools_ListOfShape LSO1,LSO2;
896     GFindSamDom(SO1,LSO1,LSO2);
897     
898     TopAbs_ShapeEnum tf = TopAbs_FACE; // NYI TopAbs_SOLID
899     TopOpeBRepBuild_GTopo G;
900     if      (Opec12()) G=TopOpeBRepBuild_GTool::GCutSame(tf,tf);
901     else if (Opec21()) G=TopOpeBRepBuild_GTool::GCutSame(tf,tf).CopyPermuted();
902     else if (Opecom()) G=TopOpeBRepBuild_GTool::GComSame(tf,tf);
903     else if (Opefus()) G=TopOpeBRepBuild_GTool::GFusSame(tf,tf);
904     else return;
905     
906     GMapShapes(myShape1,myShape2);
907     GMergeSolids(LSO1,LSO2,G);
908     
909     if (!myShape1.IsNull()) {
910       if (myShape1.ShapeType() == TopAbs_COMPOUND) {
911         TopTools_ListOfShape& L1 = ChangeMerged(myShape1,myState1);
912         L1 = ChangeMerged(SO1,myState1);
913       }
914     }
915     
916     if (!myShape2.IsNull()) {
917       if (myShape2.ShapeType() == TopAbs_COMPOUND) {
918         TopTools_ListOfShape& L2 = ChangeMerged(myShape2,myState2);
919         L2 = ChangeMerged(SO2,myState2);
920       }
921     }
922     
923   }
924   
925 } // MergeKPartissoso
926
927 static Standard_Boolean sectionedgesON(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Shape& outerw1, 
928                           const TopTools_IndexedMapOfShape& mape2)
929 // prequesitory : all edges of <outerw1> are section edges
930 {
931   TopExp_Explorer ex1(outerw1, TopAbs_EDGE);
932   for (; ex1.More(); ex1.Next()){
933     const TopoDS_Shape& e1 = ex1.Current();
934     TopTools_ListIteratorOfListOfShape it2 = HDS->SameDomain(e1);
935     if (!it2.More()) return Standard_False; // xpu231098 : cto904C7 : e1 !hsd
936     for (; it2.More(); it2.Next()){
937       const TopoDS_Shape& e2 = it2.Value();
938       Standard_Boolean isbound = mape2.Contains(e2);
939       if (!isbound) return Standard_False;
940     }
941   }  
942   return Standard_True;
943 }
944
945 static Standard_Boolean allIonsectionedges(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Shape& f1, 
946                               const TopTools_IndexedMapOfShape& mape1, 
947                               const TopTools_IndexedMapOfShape& mape2)
948 // prequesitory : all interferences attached to <f1> are SSI
949 {  
950   TopOpeBRepDS_ListIteratorOfListOfInterference it1(HDS->DS().ShapeInterferences(f1));
951   for (; it1.More(); it1.Next()){
952     Handle(TopOpeBRepDS_ShapeShapeInterference) SSI1 (Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(it1.Value()));    
953     Standard_Integer G1 = SSI1->Geometry();
954     Standard_Boolean isgbound = SSI1->GBound();
955     const TopoDS_Shape& e1 = HDS->Shape(G1);
956     Standard_Boolean isbound = isgbound? mape1.Contains(e1): mape2.Contains(e1);
957     if (!isbound) return Standard_False;
958   }  
959   return Standard_True;  
960
961
962 //=======================================================================
963 //function : KPiskoletge
964 //purpose  : detection faces collees tangentes sur wire exterieur
965 //=======================================================================
966
967 Standard_Integer TopOpeBRepBuild_Builder::KPiskoletge()
968 {  
969 /*#ifdef OCCT_DEBUG
970   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
971 #endif*/
972   
973   TopTools_ListOfShape lShsd1,lShsd2; // liste de solides HasSameDomain
974   TopTools_ListOfShape lfhsd1,lfhsd2; // liste de faces HasSameDomain
975   
976   Standard_Boolean iskp1 = KPiskoletgesh(myShape1,lShsd1,lfhsd1);
977   if ( !iskp1 ) return 0;
978   TopTools_ListOfShape lplhsd1, lcyhsd1; ::FUN_sortplcy(lfhsd1,lplhsd1, lcyhsd1);
979   Standard_Integer nplhsd1 = lplhsd1.Extent(); Standard_Integer ncyhsd1 = lcyhsd1.Extent();
980   if ( nplhsd1 != 1 ) return 0;
981   if ( ncyhsd1 > 1 ) return 0;
982   
983   Standard_Boolean iskp2 = KPiskoletgesh(myShape2,lShsd2,lfhsd2);
984   if ( !iskp2 ) return 0;
985   TopTools_ListOfShape lplhsd2, lcyhsd2; ::FUN_sortplcy(lfhsd2,lplhsd2, lcyhsd2);
986   Standard_Integer nplhsd2 = lplhsd2.Extent(); Standard_Integer ncyhsd2 = lcyhsd2.Extent();
987   if ( nplhsd2 != 1 ) return 0;
988   
989   // Si l'un des objets est constitue de plusieurs solides on passe
990   // dans le cas general.
991   Standard_Integer nshsd1 = lShsd1.Extent();
992   Standard_Integer nshsd2 = lShsd2.Extent();
993   if ( nshsd1>1 || nshsd2>1 ) return 0;
994
995
996   // NYI : (nplhsd1 > 1) || (nplhsd2 > 1)
997   // ------------------------------------
998
999   const TopoDS_Face& f1 = TopoDS::Face(lplhsd1.First());  
1000 #ifdef OCCT_DEBUG
1001 //  Standard_Boolean isb1 = myKPMAPf1f2.IsBound(f1); // DEB
1002 #endif
1003
1004   const TopoDS_Face& f2 = TopoDS::Face(lplhsd2.First()); 
1005 #ifdef OCCT_DEBUG
1006 //  Standard_Boolean isb2 = myKPMAPf1f2.IsBound(f2); // DEB
1007 #endif
1008
1009 #ifdef OCCT_DEBUG
1010   Standard_Integer iF1,iF2; 
1011   Standard_Boolean tSPS1 = GtraceSPS(f1,iF1);
1012   Standard_Boolean tSPS2 = GtraceSPS(f2,iF2);
1013   if(tSPS1 || tSPS2) 
1014     {GdumpSHA( f1, (char *) "KPiskoletge ");
1015     cout<<endl; 
1016     GdumpSHA(  f2, (char *)"KPiskoletge ");
1017     cout<<endl;}
1018 #endif
1019
1020   TopoDS_Wire outerw1 = BRepTools::OuterWire(f1);
1021   TopoDS_Wire outerw2 = BRepTools::OuterWire(f2);
1022
1023   TopTools_IndexedMapOfShape mape1; TopExp::MapShapes(outerw1, TopAbs_EDGE, mape1);
1024   TopTools_IndexedMapOfShape mape2; TopExp::MapShapes(outerw2, TopAbs_EDGE, mape2);
1025
1026   Standard_Boolean se1ONouterw2 =  ::sectionedgesON(myDataStructure,outerw1,mape2);
1027   if (!se1ONouterw2) return 0;
1028   Standard_Boolean se2ONouterw1 =  ::sectionedgesON(myDataStructure,outerw2,mape1);
1029   if (!se2ONouterw1) return 0;
1030
1031   // NYI : <fi> interfers with faces of <Sj> on edges different from outerw's edges
1032   // ------------------------------------------------------------------------------
1033   Standard_Boolean allI1onseouterw = ::allIonsectionedges(myDataStructure,f1,mape1,mape2);
1034   if (!allI1onseouterw) return 0;
1035   Standard_Boolean allI2onseouterw = ::allIonsectionedges(myDataStructure,f2,mape2,mape1);
1036   if (!allI2onseouterw) return 0;
1037   
1038
1039   // NYI : (ncyhsd1 > 1) || (ncyhsd2 > 1)
1040   // ------------------------------------
1041   // KPcycy :
1042   if (ncyhsd1 > 0) {
1043     Standard_Boolean cycy = ( ncyhsd1 == 1 ) && ( ncyhsd2 == 1 );
1044     if (!cycy) return 0;
1045     
1046     Standard_Boolean isbound1 = FUN_tool_inS(outerw1,f1);
1047     if (!isbound1) return 0;
1048     Standard_Boolean isbound2 = FUN_tool_inS(outerw2,f2);
1049     if (!isbound2) return 0;
1050   }
1051
1052   return 1;
1053 }
1054
1055 //=======================================================================
1056 //function : KPisdisj
1057 //purpose  : detection shapes disjoints
1058 //=======================================================================
1059
1060 Standard_Integer TopOpeBRepBuild_Builder::KPisdisj()
1061 {
1062 #ifdef OCCT_DEBUG
1063   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
1064 #endif
1065   
1066   // myShape1 et myShape2 : aucune interference
1067   const TopOpeBRepDS_DataStructure& DS = myDataStructure->DS();
1068   //  Standard_Integer nsh = DS.NbShapes();
1069   //  if (nsh != 2) return 0;
1070   
1071   if (!DS.HasShape(myShape1)) return 0;
1072   if (!DS.HasShape(myShape2)) return 0;
1073   
1074   Standard_Integer isdisj1 = KPisdisjsh(myShape1);
1075   Standard_Integer isdisj2 = KPisdisjsh(myShape2);
1076   
1077 #ifdef OCCT_DEBUG
1078   if (TKPB) {
1079     cout<<"isdisj : "<<isdisj1<<" "<<isdisj2<<endl;
1080   }
1081 #endif
1082   
1083   Standard_Integer isdisj = (isdisj1 && isdisj2) ? 1 : 0;
1084   return isdisj;
1085 }
1086
1087 //=======================================================================
1088 //function : KPisfafa
1089 //purpose  : detection {face} / {face} toutes HasSameDomain 
1090 //=======================================================================
1091
1092 Standard_Integer TopOpeBRepBuild_Builder::KPisfafa()
1093 {  
1094 /*#ifdef OCCT_DEBUG
1095   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
1096 #endif*/
1097   
1098   Standard_Boolean iskp1 = KPisfafash(myShape1);
1099   if ( !iskp1 ) return 0;
1100   
1101   Standard_Boolean iskp2 = KPisfafash(myShape2);
1102   if ( !iskp2 ) return 0;
1103   
1104   return 1;
1105 }
1106
1107 //=======================================================================
1108 //function : KPissoso
1109 //purpose  : detection {solide} / {solide} tous HasSameDomain 
1110 //=======================================================================
1111
1112 Standard_Integer TopOpeBRepBuild_Builder::KPissoso()
1113 {  
1114 /*#ifdef OCCT_DEBUG
1115   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
1116 #endif*/
1117   
1118   Standard_Boolean iskp1 = KPissososh(myShape1);
1119   if ( !iskp1 ) return 0;
1120   
1121   Standard_Boolean iskp2 = KPissososh(myShape2);
1122   if ( !iskp2 ) return 0;
1123   
1124   return 1;
1125 }
1126
1127 //=======================================================================
1128 //function : KPClearMaps
1129 //purpose  : 
1130 //=======================================================================
1131
1132 void TopOpeBRepBuild_Builder::KPClearMaps()
1133
1134   myKPMAPf1f2.Clear();
1135 }
1136
1137 //=======================================================================
1138 //function : KPlhg
1139 //purpose  : --> nb des subsshapes <T> de <S> qui sont HasGeometry()
1140 //=======================================================================
1141
1142 Standard_Integer TopOpeBRepBuild_Builder::KPlhg(const TopoDS_Shape& S,const TopAbs_ShapeEnum T) const 
1143 {
1144   TopTools_ListOfShape L;
1145   Standard_Integer n = KPlhg(S,T,L);
1146   return n;
1147 }
1148
1149 //=======================================================================
1150 //function : KPlhg
1151 //purpose  : --> nb +liste des subsshapes <T> de <S> qui sont HasGeometry()
1152 //=======================================================================
1153
1154 Standard_Integer TopOpeBRepBuild_Builder::KPlhg(const TopoDS_Shape& S,const TopAbs_ShapeEnum T,TopTools_ListOfShape& L) const 
1155 {
1156   Standard_Integer n = 0;
1157   L.Clear();
1158   
1159   TopExp_Explorer ex;
1160   for (ex.Init(S,T); ex.More(); ex.Next()) {
1161 //  for (TopExp_Explorer ex(S,T); ex.More(); ex.Next()) {
1162     const TopoDS_Shape& s = ex.Current();
1163     Standard_Boolean hg = myDataStructure->HasGeometry(s);
1164     if (hg) {
1165       n++;
1166       L.Append(s);
1167     }
1168   }
1169   
1170   return n;
1171 }
1172
1173 //=======================================================================
1174 //function : KPlhsd
1175 //purpose  : 
1176 // KPlhsd --> nb des subsshapes <T> de <S> qui sont HasSameDomain()
1177 //=======================================================================
1178
1179 Standard_Integer TopOpeBRepBuild_Builder::KPlhsd(const TopoDS_Shape& S,const TopAbs_ShapeEnum T) const 
1180 {
1181   TopTools_ListOfShape L;
1182   Standard_Integer n = KPlhsd(S,T,L);
1183   return n;
1184 }
1185
1186 //=======================================================================
1187 //function : KPlhsd
1188 //purpose  : 
1189 // KPlhsd --> nb + liste des subsshapes <T> de <S> qui sont HasSameDomain()
1190 //=======================================================================
1191
1192 Standard_Integer TopOpeBRepBuild_Builder::KPlhsd(const TopoDS_Shape& S,const TopAbs_ShapeEnum T,TopTools_ListOfShape& L) const 
1193 {
1194   Standard_Integer n = 0;
1195   L.Clear();
1196   
1197   TopExp_Explorer ex;
1198   for (ex.Init(S,T); ex.More(); ex.Next()) {
1199 //  for (TopExp_Explorer ex(S,T); ex.More(); ex.Next()) {
1200     const TopoDS_Shape& s = ex.Current();
1201     Standard_Boolean hsd = myDataStructure->HasSameDomain(s);
1202     if (hsd) {
1203       n++;
1204       L.Append(s);
1205     }
1206   }
1207   
1208   return n;
1209 }
1210
1211 //=======================================================================
1212 //function : KPclasSS
1213 //purpose  : 
1214 // classifie le shape S1 par rapport a S2 en evitant de prendre
1215 // les shape exLS1 de S1 comme element de classification.
1216 // exS1 peut etre IsNull().
1217 // S1,S2 = SOLID | SHELL
1218 //=======================================================================
1219
1220 TopAbs_State TopOpeBRepBuild_Builder::KPclasSS(const TopoDS_Shape& S1,const TopTools_ListOfShape& exLS1,const TopoDS_Shape& S2)
1221 {
1222   TopAbs_State state = TopAbs_UNKNOWN;
1223   state = myShapeClassifier.StateShapeShape(S1,exLS1,S2);
1224   
1225 #ifdef OCCT_DEBUG
1226   if (TopOpeBRepBuild_GettraceKPB()) {
1227     const gp_Pnt& P1 = myShapeClassifier.P3D();
1228     cout<<"point P1 "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z();
1229     cout<<"  "; TopAbs::Print(state,cout);cout<<endl;
1230   }
1231 #endif
1232   
1233   return state;
1234 }
1235
1236 //=======================================================================
1237 //function : KPclasSS
1238 //purpose  : 
1239 // classifie le shape S1 par rapport a S2 en evitant de prendre
1240 // le shape exS1 de S1 comme element de classification.
1241 // exS1 peut etre IsNull().
1242 // S1,S2 = SOLID | SHELL
1243 //=======================================================================
1244
1245 TopAbs_State TopOpeBRepBuild_Builder::KPclasSS(const TopoDS_Shape& S1,const TopoDS_Shape& exS1,const TopoDS_Shape& S2)
1246 {
1247   TopAbs_State state = myShapeClassifier.StateShapeShape(S1,exS1,S2);
1248   
1249 #ifdef OCCT_DEBUG
1250   if (TopOpeBRepBuild_GettraceKPB()) {
1251     const gp_Pnt& P1 = myShapeClassifier.P3D();
1252     cout<<"point P1 "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z();
1253     cout<<"  "; TopAbs::Print(state,cout);cout<<endl;
1254   }
1255 #endif
1256   
1257   return state;
1258 }
1259
1260 //=======================================================================
1261 //function : KPclasSS
1262 //purpose  : classifie le shape S1 par rapport a S2 sans evitement de shape
1263 // S1,S2 = SOLID | SHELL
1264 //=======================================================================
1265
1266 TopAbs_State TopOpeBRepBuild_Builder::KPclasSS(const TopoDS_Shape& S1,const TopoDS_Shape& S2)
1267 {
1268   TopoDS_Shape Snull;
1269   TopAbs_State state = KPclasSS(S1,Snull,S2);
1270   return state;
1271 }
1272
1273 //=======================================================================
1274 //function : KPiskoletgesh
1275 //purpose  : 
1276 // KPiskoletgesh : 
1277 // S est il un shape traite par le cas particulier de koletge?
1278 // si oui : retourne un solide et une liste de faces de collage
1279 //=======================================================================
1280
1281 Standard_Boolean TopOpeBRepBuild_Builder::KPiskoletgesh(const TopoDS_Shape& Sarg,TopTools_ListOfShape& lShsd,TopTools_ListOfShape& lfhsd) const 
1282 {
1283 #ifdef OCCT_DEBUG
1284   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
1285 #endif
1286   const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
1287   Standard_Boolean iskolesh = FUNKP_KPiskolesh((*this),BDS,Sarg,lShsd,lfhsd);
1288   if (!iskolesh) return Standard_False;
1289   
1290 #ifdef OCCT_DEBUG
1291   Standard_Integer nfhsd =
1292 #endif
1293               KPlhsd(Sarg,TopAbs_FACE,lfhsd);
1294   TopTools_ListIteratorOfListOfShape it(lfhsd);
1295   for (; it.More(); it.Next() ) {
1296     const TopoDS_Face& fac = TopoDS::Face(it.Value());    
1297     Standard_Boolean isplan = FUN_tool_plane(fac);
1298     Standard_Boolean iscylinder = FUN_tool_cylinder(fac); 
1299     if (iscylinder) continue;
1300     if (!isplan) return Standard_False;
1301    
1302     TopoDS_Wire outerw = BRepTools::OuterWire(fac);
1303     if (outerw.IsNull()) return Standard_False;
1304
1305     TopExp_Explorer exe(outerw, TopAbs_EDGE);
1306 //    Standard_Integer ne = 0;
1307     for (; exe.More(); exe.Next()){
1308       const TopoDS_Edge& ed = TopoDS::Edge(exe.Current());
1309       Standard_Boolean isse = BDS.IsSectionEdge(ed);
1310       const TopTools_ListOfShape& sp = (*this).Splits(ed,TopAbs_ON);    
1311       if (sp.Extent() == 0) return Standard_False;
1312       if (!isse) return Standard_False;
1313 //      ne++;
1314     }
1315 //    if (ne > 1) return Standard_False;
1316
1317 #ifdef OCCT_DEBUG
1318     Standard_Integer isol = myDataStructure->Shape(Sarg); Standard_Integer ifac = myDataStructure->Shape(fac); 
1319     if(TKPB){cout<<"isol "<<isol<<endl;}
1320     if(TKPB){cout<<"nfhsd  "<<nfhsd<<endl;}
1321     if(TKPB){cout<<"ifac "<<ifac<<endl;}
1322     if(TKPB){cout<<"isplan "<<isplan<<endl;}
1323     if(TKPB){cout<<"iscylinder "<<iscylinder<<endl;}
1324     if(TKPB){cout<<endl;}
1325 #endif
1326   }
1327   
1328   return Standard_True;
1329 }
1330
1331 //=======================================================================
1332 //function : KPSameDomain
1333 //purpose  : complete the lists L1,L2 with the shapes of the DS
1334 //           having same domain :
1335 //           L1 = shapes sharing the same domain of L2 shapes
1336 //           L2 = shapes sharing the same domain of L1 shapes
1337 // (L1 contains a face)
1338 //=======================================================================
1339
1340 void TopOpeBRepBuild_Builder::KPSameDomain(TopTools_ListOfShape& L1, TopTools_ListOfShape& L2) const 
1341 {
1342   Standard_Integer i;
1343   Standard_Integer nl1 = L1.Extent(), nl2 = L2.Extent();
1344   
1345   while ( nl1 > 0 || nl2 > 0 )  {
1346     
1347     TopTools_ListIteratorOfListOfShape it1(L1);
1348     for (i=1 ; i<=nl1; i++) {
1349       const TopoDS_Shape& S1 = it1.Value();
1350 #ifdef OCCT_DEBUG
1351 //      Standard_Integer iS1 = myDataStructure->Shape(S1);
1352 #endif
1353       TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S1));
1354       for (; itsd.More(); itsd.Next() ) {
1355         const TopoDS_Shape& S2 = itsd.Value();
1356 #ifdef OCCT_DEBUG
1357 //      Standard_Integer iS2 = myDataStructure->Shape(S2);
1358 #endif
1359         Standard_Boolean found = KPContains(S2,L2);
1360         if ( ! found ) {
1361           L2.Prepend(S2);
1362           nl2++;
1363         }
1364       }
1365       it1.Next();
1366     }
1367     nl1 = 0;
1368     
1369     TopTools_ListIteratorOfListOfShape it2(L2);
1370     for (i=1 ; i<=nl2; i++) {
1371       const TopoDS_Shape& S2 = it2.Value();
1372 #ifdef OCCT_DEBUG
1373 //      Standard_Integer iS2 = myDataStructure->Shape(S2);
1374 #endif
1375       TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S2));
1376       for (; itsd.More(); itsd.Next() ) {
1377         const TopoDS_Shape& S1 = itsd.Value();
1378 #ifdef OCCT_DEBUG
1379 //      Standard_Integer iS1 = myDataStructure->Shape(S1);
1380 #endif
1381         Standard_Boolean found = KPContains(S1,L1);
1382         if ( ! found ) {
1383           L1.Prepend(S1);
1384           nl1++;
1385         }
1386       }
1387       it2.Next();
1388     }
1389     nl2 = 0;
1390   }
1391 }
1392
1393 //=======================================================================
1394 //function : KPisdisjsh
1395 //purpose  : S est il un shape traite par le cas particulier "disjoint" 
1396 //=======================================================================
1397
1398 Standard_Integer TopOpeBRepBuild_Builder::KPisdisjsh(const TopoDS_Shape& Sarg) const 
1399 {
1400   if ( Sarg.IsNull() ) return 0;
1401   
1402   TopExp_Explorer ex;
1403   Standard_Integer nhg;
1404   
1405   nhg = KPlhg(Sarg,TopAbs_SOLID);
1406   if ( nhg != 0 ) return 0;
1407   
1408   nhg = KPlhg(Sarg,TopAbs_FACE);
1409   if ( nhg != 0 ) return 0;
1410   
1411   nhg = KPlhg(Sarg,TopAbs_EDGE);
1412   if ( nhg != 0 ) return 0;
1413   
1414   // un seul niveau de HasSameDomain
1415   Standard_Integer n1,n2;
1416   TopTools_ListOfShape lshsd;
1417   
1418   n1 = KPlhsd(Sarg,TopAbs_SOLID,lshsd);
1419   if ( n1 ) {
1420     TopTools_ListIteratorOfListOfShape it(lshsd);
1421     for(;it.More();it.Next()) {
1422       const TopoDS_Shape& s = it.Value();
1423       n2 = KPlhsd(s,TopAbs_FACE);
1424       if (n2 != 0 ) return 0;
1425     }
1426   }
1427   
1428   n1 = KPlhsd(Sarg,TopAbs_FACE,lshsd);
1429   if ( n1 ) {
1430     TopTools_ListIteratorOfListOfShape it(lshsd);
1431     for(;it.More();it.Next()) {
1432       const TopoDS_Shape& s = it.Value();
1433       n2 = KPlhsd(s,TopAbs_EDGE);
1434       if (n2 != 0 ) return 0;
1435     }
1436   }
1437   
1438   return 1;
1439 }
1440
1441 //=======================================================================
1442 //function : KPissososh
1443 //purpose  : detection S = {solid} tous HasSameDomain
1444 //=======================================================================
1445
1446 Standard_Integer TopOpeBRepBuild_Builder::KPissososh(const TopoDS_Shape& Sarg) const 
1447 {
1448   // que des solides volants (nb total de solides = nb de solides volants)
1449   Standard_Integer nsol1 = 0; 
1450   TopExp_Explorer ex1(Sarg,TopAbs_SOLID); 
1451   for(; ex1.More(); ex1.Next()) nsol1++;
1452   
1453   Standard_Integer nsol2 = 0; 
1454   TopExp_Explorer ex2(Sarg,TopAbs_SOLID,TopAbs_COMPSOLID); 
1455   for(; ex2.More(); ex2.Next()) nsol2++;
1456   
1457   if (nsol1 && (nsol1 != nsol2)) return 0;
1458   
1459   // toutes les solides sont HasSameDomain()
1460   Standard_Integer nhsd = KPlhsd(Sarg,TopAbs_SOLID);
1461   if (nhsd != nsol1) return 0;
1462   
1463   Standard_Integer n; TopExp_Explorer ex;
1464   
1465   // pas de shell volant
1466   n = 0;
1467   for (ex.Init(Sarg,TopAbs_SHELL,TopAbs_SOLID); ex.More(); ex.Next()) n++;
1468   if (n) return 0;
1469   
1470   // pas de face volant
1471   n = 0;
1472   for (ex.Init(Sarg,TopAbs_FACE,TopAbs_SHELL); ex.More(); ex.Next()) n++;
1473   if (n) return 0;
1474   
1475   // pas d'edge volant
1476   n = 0;
1477   for (ex.Init(Sarg,TopAbs_EDGE,TopAbs_WIRE); ex.More(); ex.Next()) n++;
1478   if (n) return 0;
1479   
1480   // pas de vertex volant
1481   n = 0; 
1482   for (ex.Init(Sarg,TopAbs_VERTEX,TopAbs_EDGE); ex.More(); ex.Next()) n++;
1483   if (n) return 0;
1484   
1485   return 1;
1486 }
1487
1488 //=======================================================================
1489 //function : KPisfafash
1490 //purpose  : detection S = {face} toutes HasSameDomain
1491 //=======================================================================
1492
1493 Standard_Integer TopOpeBRepBuild_Builder::KPisfafash(const TopoDS_Shape& Sarg) const 
1494 {
1495   // il n'y a que des faces volantes (nb total de faces = nb de faces volantes)
1496   Standard_Integer nfac1 = 0; 
1497   TopExp_Explorer ex1(Sarg,TopAbs_FACE); 
1498   for(; ex1.More(); ex1.Next()) nfac1++;
1499   
1500   Standard_Integer nfac2 = 0; 
1501   TopExp_Explorer ex2(Sarg,TopAbs_FACE,TopAbs_SHELL); 
1502   for(; ex2.More(); ex2.Next()) nfac2++;
1503   
1504   if (nfac1 && (nfac1 != nfac2)) return 0;
1505   
1506   // toutes les faces sont HasSameDomain()
1507   Standard_Integer nhsd = KPlhsd(Sarg,TopAbs_FACE);
1508   if (nhsd != nfac1) return 0;
1509   
1510   Standard_Integer n; TopExp_Explorer ex;
1511   
1512   // pas de wire volant
1513   n = 0;
1514   for (ex.Init(Sarg,TopAbs_WIRE,TopAbs_FACE); ex.More(); ex.Next()) n++;
1515   if (n) return 0;
1516   
1517   // pas d'edge volant
1518   n = 0;
1519   for (ex.Init(Sarg,TopAbs_EDGE,TopAbs_WIRE); ex.More(); ex.Next()) n++;
1520   if (n) return 0;
1521   
1522   // pas de vertex volant
1523   n = 0; 
1524   for (ex.Init(Sarg,TopAbs_VERTEX,TopAbs_EDGE); ex.More(); ex.Next()) n++;
1525   if (n) return 0;
1526   
1527   return 1;
1528 }
1529
1530 //=======================================================================
1531 //function : KPiskoletgeanalyse
1532 //purpose  : 
1533 //=======================================================================
1534
1535 void TopOpeBRepBuild_Builder::KPiskoletgeanalyse(const TopOpeBRepDS_Config config2, 
1536                                                  const TopAbs_State Stsol1, const TopAbs_State Stsol2, 
1537                                                  Standard_Integer& ires) const 
1538 {
1539   // -----------------------------------------------------------------------------
1540   // prequesitory :  (nplhsd1 == 1) || (nplhsd2 == 1)
1541   // -------------   <plsdmi> has all interferences Ii = (T, G=edge of outerw1
1542   //                                                         ||edge of outerw2, S)
1543   // -----------------------------------------------------------------------------
1544
1545   ires = RESUNDEF;
1546
1547   Standard_Boolean SameOriented = (config2 == TopOpeBRepDS_SAMEORIENTED);
1548   Standard_Boolean DiffOriented = (config2 == TopOpeBRepDS_DIFFORIENTED);
1549
1550 //  Standard_Boolean com = Opecom();
1551 //  Standard_Boolean c12 = Opec12();
1552 //  Standard_Boolean c21 = Opec21();
1553 //  Standard_Boolean fus = Opefus();
1554
1555   if (DiffOriented) {
1556     if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_IN) 
1557 //      if (com) ires = RESNULL;
1558      ires = RESNULL; 
1559
1560     if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN) {
1561 //      if (c12) ires = RESSHAPE1; // rank(sol1) == 1 && rank(sol2) == 2
1562 //      if (c21) ires = RESSHAPE2; // rank(sol1) == 2 && rank(sol2) == 1
1563       ires = RESSHAPE1;
1564     }
1565
1566     if (Stsol2 == TopAbs_OUT && Stsol1 == TopAbs_IN) {
1567 //      if (c12) ires = RESSHAPE2; // rank(sol2) == 1 && rank(sol1) == 2
1568 //      if (c21) ires = RESSHAPE1; // rank(sol2) == 2 && rank(sol1) == 1
1569       ires = RESSHAPE2;
1570     }
1571
1572     if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) 
1573 //      if (fus) ires = RESNEWSOL;
1574       ires = RESNEWSOL;
1575   } // DiffOriented
1576
1577   if (SameOriented) {
1578     // ==============================
1579     // PREQUESITORY :sol1 is IN sol2
1580     // ==============================
1581
1582     if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_IN) 
1583 //      if (com) ires = RESSHAPE1;
1584       ires = RESSHAPE1;
1585
1586     if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN) {
1587 //      if (c12) ires = RESNULL; // rank(sol1) == 1 && rank(sol2) == 2
1588 //      if (c21) ires = RESNEWSOL; // rank(sol1) == 2 && rank(sol2) == 1
1589       ires = RESNULL;
1590     }
1591
1592     if (Stsol2 == TopAbs_OUT && Stsol1 == TopAbs_IN) {
1593 //      if (c12) ires = RESNULL; // rank(sol2) == 1 && rank(sol1) == 2
1594 //      if (c21) ires = RESNEWSOL; // rank(sol2) == 2 && rank(sol1) == 1
1595       ires = RESNEWSOL;
1596     }
1597
1598     if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) 
1599 //      if (fus) ires = RESSHAPE2;
1600       ires = RESSHAPE2;
1601   } // SameOriented
1602
1603 #ifdef OCCT_DEBUG
1604   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
1605   if (TKPB) cout<<"ires = "<<ires<<endl;
1606 #endif
1607 }
1608
1609
1610 //=======================================================================
1611 //function : KPisdisjanalyse
1612 //purpose  : 
1613 //=======================================================================
1614
1615 void TopOpeBRepBuild_Builder::KPisdisjanalyse(const TopAbs_State Stsol1, const TopAbs_State  Stsol2,
1616                                               Standard_Integer& ires,Standard_Integer& icla1,Standard_Integer& icla2) const 
1617 {
1618   ires = RESUNDEF; icla1 = icla2 = SHEUNDEF;
1619   
1620   if      (Opefus())  {
1621     if      (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1622       ires = RESSHAPE12; icla1 = icla2 = SHEAUCU; //--
1623     }
1624     else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1625       ires = RESNEWSHA1; icla1 = icla2 = SHECLASAUTR; //--
1626     }
1627     else if (Stsol1 == TopAbs_IN  && Stsol2 == TopAbs_OUT) {
1628       ires = RESNEWSHA2; icla1 = icla2 = SHECLASAUTR; //--
1629     }
1630   }
1631   else if (Opec12()) {
1632     if      (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1633       ires = RESSHAPE1; icla1 = SHEGARDTOUS; icla2 = SHEAUCU; //--
1634     }
1635     else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1636       ires = RESNEWSHA1; icla1 = SHECLASAUTR; icla2 = SHEGARDCOUR; //--
1637     }
1638     else if (Stsol1 == TopAbs_IN  && Stsol2 == TopAbs_OUT) {
1639       ires = RESNULL; icla1 = icla2 = SHEAUCU; //--
1640     }
1641   }
1642   else if (Opec21()) {
1643     if      (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1644       ires = RESSHAPE2; icla1 = SHEAUCU; icla2 = SHEGARDTOUS; //--
1645     }
1646     else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1647       ires = RESNULL; icla1 = icla2 = SHEAUCU; //--
1648     }
1649     else if (Stsol1 == TopAbs_IN  && Stsol2 == TopAbs_OUT) {
1650       ires = RESNEWSHA2; icla1 = SHEGARDCOUR; icla2 = SHECLASAUTR; //--
1651     }
1652   }
1653   else if (Opecom()) {
1654     if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) { 
1655       ires = RESNULL; icla1 = icla2 = SHEAUCU; //--
1656     }
1657     else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1658       ires = RESNEWSHA2; icla1 = SHECLASAUTR; icla2 = SHEGARDAUTR; //--
1659     }
1660     else if (Stsol1 == TopAbs_IN  && Stsol2 == TopAbs_OUT) {
1661       ires = RESNEWSHA1; icla1 = SHEGARDAUTR; icla2 = SHECLASAUTR; //--
1662     }
1663   }
1664   
1665 #ifdef OCCT_DEBUG
1666   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
1667   if (TKPB) cout<<"ires = "<<ires<<" icla1 "<<icla1<<" icla2 "<<icla2<<endl;
1668 #endif
1669 }
1670
1671 //=======================================================================
1672 //function : KPls (class method)
1673 //purpose  : 
1674 // KPls --> nb des subsshapes <T> de <S>
1675 //=======================================================================
1676
1677 Standard_Integer TopOpeBRepBuild_Builder::KPls(const TopoDS_Shape& S,const TopAbs_ShapeEnum T)
1678 {
1679   TopTools_ListOfShape L;
1680   Standard_Integer n = KPls(S,T,L);
1681   return n;
1682 }
1683
1684 //=======================================================================
1685 //function : KPls (class method)
1686 //purpose  : 
1687 // KPls --> nb + liste des subsshapes <T> de <S>
1688 //=======================================================================
1689
1690 Standard_Integer TopOpeBRepBuild_Builder::KPls(const TopoDS_Shape& S, const TopAbs_ShapeEnum T, TopTools_ListOfShape& L)
1691 {
1692   Standard_Integer n = 0;
1693   L.Clear();
1694   
1695   TopExp_Explorer ex;
1696   for (ex.Init(S,T); ex.More(); ex.Next()) {
1697 //  for (TopExp_Explorer ex(S,T); ex.More(); ex.Next()) {
1698     const TopoDS_Shape& s = ex.Current();
1699     n++;
1700     L.Append(s);
1701   }
1702   
1703   return n;
1704 }
1705
1706 //=======================================================================
1707 //function : KPclassF (class method)
1708 //purpose  : 
1709 // KPclassF : classification F1 par rapport a F2
1710 // F1 et F2 ne partagent aucune arete
1711 // F1 et F2 sont SameDomain
1712 //=======================================================================
1713
1714 TopAbs_State TopOpeBRepBuild_Builder::KPclassF(const TopoDS_Shape& F1,const TopoDS_Shape& F2)
1715 {
1716   if (F1.IsNull()) return TopAbs_UNKNOWN;
1717   if (F2.IsNull()) return TopAbs_UNKNOWN;
1718   
1719   TopoDS_Face F1F = TopoDS::Face(F1); F1F.Orientation(TopAbs_FORWARD);
1720   TopoDS_Face F2F = TopoDS::Face(F2); F2F.Orientation(TopAbs_FORWARD);
1721   
1722   TopTools_ListOfShape le1;
1723   Standard_Integer ne1 = KPls(F1F,TopAbs_EDGE,le1);
1724   if ( ne1 == 0 ) return TopAbs_UNKNOWN;
1725   const TopoDS_Edge& e1 = TopoDS::Edge(le1.First());
1726   
1727   Standard_Integer isamdom = 1;
1728   TopAbs_State St1 = TopAbs_UNKNOWN;
1729   St1 = myShapeClassifier.StateShapeShape(e1,F2F,isamdom);
1730   return St1;
1731 }
1732
1733 //=======================================================================
1734 //function : KPclassFF (class method)
1735 //purpose  : 
1736 // classifie F1/F2 --> etats des faces l'une par rapport a l'autre
1737 //=======================================================================
1738
1739 void TopOpeBRepBuild_Builder::KPclassFF(const TopoDS_Shape& F1,const TopoDS_Shape& F2,TopAbs_State& St1,TopAbs_State& St2)
1740 {
1741   St1 = KPclassF(F1,F2);
1742   St2 = KPclassF(F2,F1);
1743   
1744 #ifdef OCCT_DEBUG
1745   if (TopOpeBRepBuild_GettraceKPB()) { 
1746     cout<<"Stf1 ";TopAbs::Print(St1,cout); cout<<" ";
1747     cout<<"Stf2 ";TopAbs::Print(St2,cout); cout<<endl;
1748   }
1749 #endif
1750 }
1751
1752 //=======================================================================
1753 //function : KPiskoleFF
1754 //purpose  : 
1755 // classifie F1/F2 --> etats des faces l'une par rapport a l'autre
1756 // --> True si la configutration topologique correspond au cas "iskole".
1757 //=======================================================================
1758
1759 Standard_Boolean TopOpeBRepBuild_Builder::KPiskoleFF(const TopoDS_Shape& F1,const TopoDS_Shape& F2,TopAbs_State& St1,TopAbs_State& St2)
1760 {
1761 #ifdef OCCT_DEBUG
1762   Standard_Integer iF1; 
1763   Standard_Boolean tSPS1 = GtraceSPS(F1,iF1);
1764   Standard_Integer iF2; 
1765   Standard_Boolean tSPS2 = GtraceSPS(F2,iF2);
1766   if(tSPS1) { GdumpSHA(F1, (char *) "KPiskoleFF ");cout<<endl; }
1767   if(tSPS2) { GdumpSHA(F2, (char *) "KPiskoleFF ");cout<<endl; }
1768 #endif
1769   
1770   KPclassFF(F1,F2,St1,St2);
1771   Standard_Boolean st1ok = (St1 == TopAbs_OUT || St1 == TopAbs_IN);
1772   Standard_Boolean st2ok = (St2 == TopAbs_OUT || St2 == TopAbs_IN);
1773   
1774   if ( !st1ok ) return Standard_False;
1775   if ( !st2ok ) return Standard_False;
1776   Standard_Boolean stok = (St1 != St2);
1777   if ( !stok ) return Standard_False;
1778   return Standard_True;
1779 }
1780
1781 //=======================================================================
1782 //function : KPContains (class method)
1783 //purpose  : returns True if S is in the list L.
1784 //=======================================================================
1785
1786 Standard_Boolean TopOpeBRepBuild_Builder::KPContains(const TopoDS_Shape& S,const TopTools_ListOfShape& L) 
1787 {
1788   for (TopTools_ListIteratorOfListOfShape it(L); it.More(); it.Next() ) {
1789     const TopoDS_Shape& SL = it.Value();
1790     Standard_Boolean issame = SL.IsSame(S);
1791     if ( issame ) return Standard_True;
1792   }
1793   return Standard_False;
1794 } // KPContains
1795
1796 //=======================================================================
1797 //function : KPreturn (class method)
1798 //purpose  : 
1799 //=======================================================================
1800
1801 Standard_Integer TopOpeBRepBuild_Builder::KPreturn(const Standard_Integer b)
1802 {
1803 #ifdef OCCT_DEBUG
1804   if (TopOpeBRepBuild_GettraceKPB()) {
1805     cout<<"--- IsKPart "<<b;
1806     if ( b == 1 ) cout<<" iskole";
1807     if ( b == 2 ) cout<<" isdisj";
1808     if ( b == 3 ) cout<<" isfafa";
1809     cout<<" ---"<<endl;
1810   }
1811 #endif
1812   return b;
1813 }
1814
1815 //modified by NIZHNY-MKK  Tue May 23 09:48:47 2000.BEGIN
1816 //======================================================================================================
1817 // static function : LocalKPisdisjanalyse
1818 // purpose: 
1819 //======================================================================================================
1820 static void LocalKPisdisjanalyse(const TopAbs_State Stsol1, const TopAbs_State  Stsol2,
1821                                  const TopOpeBRepBuild_KPart_Operation& theOperation,
1822                                  Standard_Integer& ires, Standard_Integer& icla1, Standard_Integer& icla2) {
1823   ires = RESUNDEF; icla1 = icla2 = SHEUNDEF;
1824
1825   switch(theOperation) {
1826   case TopOpeBRepBuild_KPart_Operation_Fuse: {
1827     if      (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1828       ires = RESSHAPE12; icla1 = icla2 = SHEAUCU; //--
1829     }
1830     else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1831       ires = RESNEWSHA1; icla1 = icla2 = SHECLASAUTR; //--
1832     }
1833     else if (Stsol1 == TopAbs_IN  && Stsol2 == TopAbs_OUT) {
1834       ires = RESNEWSHA2; icla1 = icla2 = SHECLASAUTR; //--
1835     }
1836     break;
1837   }
1838   case TopOpeBRepBuild_KPart_Operation_Cut12: {
1839     if      (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1840       ires = RESSHAPE1; icla1 = SHEGARDTOUS; icla2 = SHEAUCU; //--
1841     }
1842     else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1843       ires = RESNEWSHA1; icla1 = SHECLASAUTR; icla2 = SHEGARDCOUR; //--
1844     }
1845     else if (Stsol1 == TopAbs_IN  && Stsol2 == TopAbs_OUT) {
1846       ires = RESNULL; icla1 = icla2 = SHEAUCU; //--
1847     }
1848     break;
1849   }
1850   case TopOpeBRepBuild_KPart_Operation_Cut21: {
1851     if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1852       ires = RESSHAPE2; icla1 = SHEAUCU; icla2 = SHEGARDTOUS; //--
1853     }
1854     else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1855       ires = RESNULL; icla1 = icla2 = SHEAUCU; //--
1856     }
1857     else if (Stsol1 == TopAbs_IN  && Stsol2 == TopAbs_OUT) {
1858       ires = RESNEWSHA2; icla1 = SHEGARDCOUR; icla2 = SHECLASAUTR; //--
1859     }
1860     break;
1861   }
1862   case TopOpeBRepBuild_KPart_Operation_Common: {
1863     if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) { 
1864       ires = RESNULL; icla1 = icla2 = SHEAUCU; //--
1865     }
1866     else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1867       ires = RESNEWSHA2; icla1 = SHECLASAUTR; icla2 = SHEGARDAUTR; //--
1868     }
1869     else if (Stsol1 == TopAbs_IN  && Stsol2 == TopAbs_OUT) {
1870       ires = RESNEWSHA1; icla1 = SHEGARDAUTR; icla2 = SHECLASAUTR; //--
1871     }
1872     break;
1873   }
1874   default: {
1875     cout << "Warning: given operation is unknown"   << endl;
1876     break;
1877   }
1878   } //end switch
1879   
1880 }
1881
1882 //======================================================================================================
1883 // static function : BuildNewSolid
1884 // purpose: Build new solid based on sol1 and sol2 according to the states
1885 //======================================================================================================
1886 static TopoDS_Solid BuildNewSolid(const TopoDS_Solid& sol1, 
1887                                   const TopoDS_Solid& sol2, 
1888                                   const TopAbs_State stsol1, 
1889                                   const TopAbs_State stsol2,
1890                                   const Standard_Integer ires, 
1891                                   const Standard_Integer icla1, 
1892                                   const Standard_Integer icla2,
1893                                   const TopAbs_State theState1,
1894                                   const TopAbs_State theState2) {
1895
1896   TopOpeBRepTool_ShapeClassifier aShapeClassifier;
1897   TopoDS_Shape Snull;  
1898   TopTools_MapOfShape isdisjmap;
1899   TopOpeBRepDS_BuildTool aBuildTool;
1900   TopoDS_Solid sol;
1901   TopAbs_State solstate,shastatetoadd;
1902   TopoDS_Shell outsha;
1903   Standard_Integer icla;
1904   TopoDS_Solid othersol;
1905   TopoDS_Shell outsha1 = BRepClass3d::OuterShell(sol1);
1906   TopoDS_Shell outsha2 = BRepClass3d::OuterShell(sol2);
1907
1908   
1909   TopoDS_Solid newsol;
1910   aBuildTool.MakeSolid(newsol);
1911   if (ires == RESNEWSHA1) {
1912     if ( ! isdisjmap.Contains(outsha1) ) {
1913       isdisjmap.Add(outsha1);
1914       aBuildTool.AddSolidShell(newsol,outsha1);
1915     }
1916   }
1917   else if (ires == RESNEWSHA2) {
1918     if ( ! isdisjmap.Contains(outsha2) ) {
1919       isdisjmap.Add(outsha2);
1920       aBuildTool.AddSolidShell(newsol,outsha2);
1921     }
1922   }
1923   
1924   sol = sol1;
1925   solstate = stsol1; 
1926   shastatetoadd = theState1;
1927   outsha = outsha1;
1928   icla = icla1;
1929   othersol = sol2;
1930   
1931   {
1932     TopOpeBRepTool_ShapeExplorer exsha;
1933     for (exsha.Init(sol,TopAbs_SHELL); exsha.More(); exsha.Next()) {
1934       const TopoDS_Shell& shacur = TopoDS::Shell(exsha.Current());
1935       Standard_Boolean isoutsha = shacur.IsEqual(outsha);
1936       
1937       Standard_Boolean garde = Standard_True;
1938       if      (icla==SHEAUCU) garde = Standard_False;
1939       else if (icla==SHEGARDAUTR || icla==SHECLASAUTR) garde = ! isoutsha;
1940       if (!garde) continue;
1941       
1942       Standard_Boolean add = Standard_False;
1943       if      ( icla==SHEGARDCOUR ) add = Standard_True;
1944       else if ( icla==SHEGARDAUTR ) add = Standard_True;
1945       else if ( icla==SHEGARDTOUS ) add = Standard_True;
1946       else if ( icla==SHECLASAUTR ) {
1947         TopAbs_State state = aShapeClassifier.StateShapeShape(shacur,Snull,othersol);
1948         add = (state == shastatetoadd);
1949       }
1950       if (add) {
1951         TopoDS_Shell shaori = shacur;
1952         Standard_Boolean r = (solstate == TopAbs_IN);
1953         if (r) shaori.Complement();
1954         if ( ! isdisjmap.Contains(shaori) ) {
1955           isdisjmap.Add(shaori);
1956           aBuildTool.AddSolidShell(newsol,shaori);
1957         }
1958       }
1959     }
1960   } //end block1
1961   
1962   sol = sol2; 
1963   solstate = stsol2;
1964   shastatetoadd = theState2;
1965   outsha = outsha2;
1966   icla = icla2;
1967   othersol = sol1;
1968   
1969   {
1970     TopOpeBRepTool_ShapeExplorer exsha;
1971     for (exsha.Init(sol,TopAbs_SHELL); exsha.More(); exsha.Next()) {
1972       const TopoDS_Shell& shacur = TopoDS::Shell(exsha.Current());
1973       Standard_Boolean isoutsha = shacur.IsEqual(outsha);
1974       
1975       Standard_Boolean garde = Standard_True;
1976       if      (icla==SHEAUCU) garde = Standard_False;
1977       else if (icla==SHEGARDAUTR || icla==SHECLASAUTR) garde = ! isoutsha;
1978       if (!garde) continue;
1979       
1980       Standard_Boolean add = Standard_False;
1981       if      ( icla==SHEGARDCOUR ) add = Standard_True;
1982       else if ( icla==SHEGARDAUTR ) add = Standard_True;
1983       else if ( icla==SHEGARDTOUS ) add = Standard_True;
1984       else if ( icla==SHECLASAUTR ) {
1985         TopAbs_State state = aShapeClassifier.StateShapeShape(shacur,Snull,othersol);
1986         add = (state == shastatetoadd);
1987       }
1988       if (add) {
1989         TopoDS_Shell shaori = shacur;
1990         Standard_Boolean r = (solstate == TopAbs_IN);
1991         if (r) shaori.Complement();
1992         aBuildTool.AddSolidShell(newsol,shaori);
1993       }
1994     }
1995   } //end block2
1996   return newsol;
1997 }
1998
1999
2000 //======================================================================================================
2001 // static function : disjPerformFuse
2002 // purpose: is needed in case of KPart==2
2003 // attention: theMapOfResult is cleared before computations
2004 //======================================================================================================
2005 static Standard_Boolean disjPerformFuse(const TopTools_IndexedMapOfShape& theMapOfSolid1, 
2006                                         const TopTools_IndexedMapOfShape& theMapOfSolid2,
2007                                         TopTools_IndexedMapOfShape& theMapOfResult) {
2008
2009   theMapOfResult.Clear();
2010
2011   TopTools_IndexedMapOfShape aMapOfSolid;
2012   aMapOfSolid = theMapOfSolid1;
2013   Standard_Integer i=1;
2014   for(i=1; i<=theMapOfSolid2.Extent(); i++) {
2015     aMapOfSolid.Add(theMapOfSolid2(i));
2016   }
2017   
2018   TopoDS_Solid sol1; TopoDS_Shell outsha1;
2019   TopoDS_Solid sol2; TopoDS_Shell outsha2;
2020   TopOpeBRepTool_ShapeClassifier aShapeClassifier;
2021   TopoDS_Shape Snull;
2022   TopTools_MapOfShape aMapOfUsedSolids;  
2023   TopoDS_Solid acurrentsolid;
2024   Standard_Integer aMaxNumberOfIterations = aMapOfSolid.Extent()*aMapOfSolid.Extent();
2025
2026   for(i=1; i <=aMapOfSolid.Extent(); i++) {
2027     const TopoDS_Shape& localshape1 = aMapOfSolid(i);
2028     if(localshape1.ShapeType()!=TopAbs_SOLID)
2029       return Standard_False;
2030     
2031     sol1 = TopoDS::Solid(localshape1);
2032     acurrentsolid = sol1;
2033     if(aMapOfUsedSolids.Contains(localshape1))
2034       continue;
2035     
2036     Standard_Integer j=1, acheckiterator=0;
2037     while(j<=aMapOfSolid.Extent() && (acheckiterator <= aMaxNumberOfIterations)) {
2038       acheckiterator++;
2039       if(j==i) {
2040         j++;
2041         continue;
2042       }
2043       const TopoDS_Shape& localshape2 = aMapOfSolid(j);
2044       if(localshape2.ShapeType()!=TopAbs_SOLID)
2045         return Standard_False;
2046       
2047       j++; // increase iterator
2048       
2049       if(aMapOfUsedSolids.Contains(localshape2)) {
2050         continue;
2051       }
2052       sol2 = TopoDS::Solid(localshape2);
2053       outsha2 = BRepClass3d::OuterShell(sol2);
2054       
2055       outsha1 = BRepClass3d::OuterShell(acurrentsolid);
2056       TopAbs_State stsol1 = aShapeClassifier.StateShapeShape(outsha1,Snull,sol2);
2057       TopAbs_State stsol2 = aShapeClassifier.StateShapeShape(outsha2,Snull,acurrentsolid);
2058       Standard_Integer ires=RESUNDEF, icla1=SHEUNDEF, icla2=SHEUNDEF;
2059       LocalKPisdisjanalyse(stsol1, stsol2, TopOpeBRepBuild_KPart_Operation_Fuse, ires, icla1, icla2);
2060       if (ires == RESUNDEF || icla1 == SHEUNDEF || icla2 == SHEUNDEF || ires == RESNULL) {
2061         cout << "Warning: disjPerformFuse: can not determine solid's states"  << endl;
2062         continue;
2063       }
2064       if(ires == RESSHAPE12)
2065         continue;
2066
2067       if(ires==RESNEWSHA1 || ires==RESNEWSHA2) {
2068         TopoDS_Solid newsol = BuildNewSolid(acurrentsolid, sol2, stsol1, stsol2, ires, icla1, icla2, TopAbs_OUT, TopAbs_OUT);
2069         j=1; // iterate on all solids again except already used (very dengerous method)
2070         acurrentsolid = newsol;
2071         aMapOfUsedSolids.Add(localshape2);
2072         if(acurrentsolid.IsNull())
2073           return Standard_False;
2074       }
2075     } //end while(j)
2076     if(acheckiterator > aMaxNumberOfIterations) {
2077       cout << "disjPerformFuse: programming error"  << endl;
2078       return Standard_False;
2079     }
2080     theMapOfResult.Add(acurrentsolid);
2081   } //end for(i)
2082
2083   return Standard_True;
2084 }
2085
2086 //======================================================================================================
2087 // static function : disjPerformCommon
2088 // purpose: is needed in case of KPart==2
2089 // attention: theMapOfResult is cleared before computations
2090 //======================================================================================================
2091 static Standard_Boolean disjPerformCommon(const TopTools_IndexedMapOfShape& theMapOfSolid1, 
2092                                           const TopTools_IndexedMapOfShape& theMapOfSolid2,                                     
2093                                           TopTools_IndexedMapOfShape& theMapOfResult) {
2094
2095   TopoDS_Solid sol1; TopoDS_Shell outsha1;
2096   TopoDS_Solid sol2; TopoDS_Shell outsha2;
2097   TopOpeBRepTool_ShapeClassifier aShapeClassifier;
2098   TopoDS_Shape Snull;
2099   TopTools_IndexedMapOfShape aMapOfSeparatedSolid1, aMapOfSeparatedSolid2, aMapOfCommonOfCouple;
2100   theMapOfResult.Clear();
2101
2102   disjPerformFuse(theMapOfSolid1, theMapOfSolid1, aMapOfSeparatedSolid1);
2103   disjPerformFuse(theMapOfSolid2, theMapOfSolid2, aMapOfSeparatedSolid2);
2104   //   Now common parts of all couples of solids are different
2105   for(Standard_Integer i=1; i <=aMapOfSeparatedSolid1.Extent(); i++) {
2106     const TopoDS_Shape& localshape1 = aMapOfSeparatedSolid1(i);
2107     if(localshape1.ShapeType()!=TopAbs_SOLID)
2108       return Standard_False;    
2109     sol1 = TopoDS::Solid(localshape1);
2110     outsha1 = BRepClass3d::OuterShell(sol1);
2111
2112     for(Standard_Integer j=1; j<=aMapOfSeparatedSolid2.Extent(); j++) {
2113       const TopoDS_Shape& localshape2 = aMapOfSeparatedSolid2(j);
2114       if(localshape2.ShapeType()!=TopAbs_SOLID)
2115         return Standard_False;
2116       
2117       sol2 = TopoDS::Solid(localshape2);
2118       outsha2 = BRepClass3d::OuterShell(sol2);
2119       TopAbs_State stsol1 = aShapeClassifier.StateShapeShape(outsha1,Snull,sol2);
2120       TopAbs_State stsol2 = aShapeClassifier.StateShapeShape(outsha2,Snull,sol1);
2121       Standard_Integer ires=RESUNDEF, icla1=SHEUNDEF, icla2=SHEUNDEF;
2122
2123       LocalKPisdisjanalyse(stsol1, stsol2, TopOpeBRepBuild_KPart_Operation_Common, ires, icla1, icla2);
2124       if (ires == RESUNDEF || icla1 == SHEUNDEF || icla2 == SHEUNDEF) {
2125         cout << "Warning: disjPerformCommon: can not determine solid's states"  << endl;
2126         continue;
2127       }      
2128       switch (ires) {
2129       case RESNULL: {
2130         continue;
2131       }
2132       case RESSHAPE12 : {
2133         aMapOfCommonOfCouple.Add(sol1);
2134         aMapOfCommonOfCouple.Add(sol2);
2135         continue;
2136       }
2137       case RESSHAPE1 : {
2138         aMapOfCommonOfCouple.Add(sol1);
2139         continue;
2140       }
2141       case RESSHAPE2 : {
2142         aMapOfCommonOfCouple.Add(sol2);
2143         break;
2144       }
2145       case RESNEWSHA1:
2146       case RESNEWSHA2: {
2147         TopoDS_Solid newsol = BuildNewSolid(sol1, sol2, stsol1, stsol2, ires, icla1, icla2, TopAbs_IN, TopAbs_IN);
2148         aMapOfCommonOfCouple.Add(newsol);       
2149         break;
2150       }
2151       default: continue;      
2152       }//end switch
2153     } //end for(j)
2154   } //end for(i)
2155
2156   disjPerformFuse(aMapOfCommonOfCouple, aMapOfCommonOfCouple, theMapOfResult);
2157   return Standard_True;
2158 }
2159
2160 //======================================================================================================
2161 // static function : disjPerformCut
2162 // purpose: is needed in case of KPart==2
2163 // attention: theMapOfResult is cleared before computations
2164 //======================================================================================================
2165 static Standard_Boolean disjPerformCut(const TopTools_IndexedMapOfShape& theMapOfSolid1, 
2166                                        const TopTools_IndexedMapOfShape& theMapOfSolid2,                                        
2167                                        TopTools_IndexedMapOfShape& theMapOfResult) {
2168   TopoDS_Solid sol1; TopoDS_Shell outsha1;
2169   TopoDS_Solid sol2; TopoDS_Shell outsha2;
2170   TopOpeBRepTool_ShapeClassifier aShapeClassifier;
2171   TopoDS_Shape Snull;
2172   TopoDS_Solid acurrentsolid;
2173   TopTools_IndexedMapOfShape aMapOfSeparatedSolid1, aMapOfSeparatedSolid2;
2174
2175   theMapOfResult.Clear();
2176
2177   disjPerformFuse(theMapOfSolid1, theMapOfSolid1, aMapOfSeparatedSolid1);
2178   disjPerformFuse(theMapOfSolid2, theMapOfSolid2, aMapOfSeparatedSolid2);
2179
2180   for(Standard_Integer i=1; i<= aMapOfSeparatedSolid1.Extent(); i++) {
2181     const TopoDS_Shape& localshape1 = aMapOfSeparatedSolid1(i);
2182     if(localshape1.ShapeType()!=TopAbs_SOLID)
2183       return Standard_False;    
2184     sol1 = TopoDS::Solid(localshape1);
2185     acurrentsolid = sol1;
2186
2187     Standard_Boolean NullResult = Standard_False;
2188
2189     for(Standard_Integer j=1; j<=aMapOfSeparatedSolid2.Extent() && !NullResult; j++) {
2190       const TopoDS_Shape& localshape2 = aMapOfSeparatedSolid2(j);
2191       if(localshape2.ShapeType()!=TopAbs_SOLID)
2192         return Standard_False;      
2193       sol2 = TopoDS::Solid(localshape2);
2194       outsha2 = BRepClass3d::OuterShell(sol2);
2195       outsha1 = BRepClass3d::OuterShell(acurrentsolid);
2196       TopAbs_State stsol1 = aShapeClassifier.StateShapeShape(outsha1,Snull,sol2);
2197       TopAbs_State stsol2 = aShapeClassifier.StateShapeShape(outsha2,Snull,acurrentsolid);
2198       Standard_Integer ires=RESUNDEF, icla1=SHEUNDEF, icla2=SHEUNDEF;
2199
2200       LocalKPisdisjanalyse(stsol1, stsol2, TopOpeBRepBuild_KPart_Operation_Cut12, ires, icla1, icla2);
2201       if (ires == RESUNDEF || icla1 == SHEUNDEF || icla2 == SHEUNDEF) {
2202         cout << "Warning: disjPerformCut: can not determine solid's states"  << endl;
2203         continue;
2204       }
2205       switch (ires) {
2206       case RESNULL: {
2207         NullResult=Standard_True;
2208         break;
2209       }
2210       case RESSHAPE12 : {
2211         NullResult=Standard_True;
2212         break;
2213       }
2214       case RESSHAPE1 : {
2215         NullResult=Standard_False;
2216         break;
2217       }
2218       case RESSHAPE2 : {
2219         NullResult=Standard_True;
2220         break;
2221       }
2222       case RESNEWSHA1:
2223       case RESNEWSHA2: {
2224         TopoDS_Solid newsol = BuildNewSolid(acurrentsolid, sol2, stsol1, stsol2, ires, icla1, icla2, TopAbs_OUT, TopAbs_IN);
2225         acurrentsolid = newsol;
2226         break;
2227       }
2228       default: continue;      
2229       }//end switch
2230     } //end for(j)
2231     if(!NullResult) {
2232       if(acurrentsolid.IsNull())
2233         return Standard_False;
2234       theMapOfResult.Add(acurrentsolid);
2235     }
2236   } //end for(i)
2237   return Standard_True;
2238 }
2239 //modified by NIZHNY-MKK  Tue May 23 09:49:03 2000.END