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