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