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 <gp_Pnt.hxx>
20 #include <Standard_NoSuchObject.hxx>
21 #include <Standard_ProgramError.hxx>
22 #include <TCollection_AsciiString.hxx>
23 #include <TopAbs.hxx>
24 #include <TopExp.hxx>
25 #include <TopoDS.hxx>
26 #include <TopoDS_Edge.hxx>
27 #include <TopoDS_Face.hxx>
28 #include <TopoDS_Shape.hxx>
29 #include <TopoDS_Shell.hxx>
30 #include <TopoDS_Solid.hxx>
31 #include <TopoDS_Vertex.hxx>
32 #include <TopoDS_Wire.hxx>
33 #include <TopOpeBRepBuild_Builder.hxx>
34 #include <TopOpeBRepBuild_define.hxx>
35 #include <TopOpeBRepBuild_EdgeBuilder.hxx>
36 #include <TopOpeBRepBuild_FaceBuilder.hxx>
37 #include <TopOpeBRepBuild_GTopo.hxx>
38 #include <TopOpeBRepBuild_HBuilder.hxx>
39 #include <TopOpeBRepBuild_kpresu.hxx>
40 #include <TopOpeBRepBuild_PaveSet.hxx>
41 #include <TopOpeBRepBuild_ShapeSet.hxx>
42 #include <TopOpeBRepBuild_ShellFaceSet.hxx>
43 #include <TopOpeBRepBuild_SolidBuilder.hxx>
44 #include <TopOpeBRepBuild_WireEdgeSet.hxx>
45 #include <TopOpeBRepBuild_WireToFace.hxx>
46 #include <TopOpeBRepDS_BuildTool.hxx>
47 #include <TopOpeBRepDS_connex.hxx>
48 #include <TopOpeBRepDS_CurveIterator.hxx>
49 #include <TopOpeBRepDS_EXPORT.hxx>
50 #include <TopOpeBRepDS_HDataStructure.hxx>
51 #include <TopOpeBRepDS_PointIterator.hxx>
52 #include <TopOpeBRepDS_ShapeShapeInterference.hxx>
53 #include <TopOpeBRepDS_SurfaceIterator.hxx>
54 #include <TopOpeBRepTool_EXPORT.hxx>
55 #include <TopOpeBRepTool_ShapeExplorer.hxx>
56 
57 #ifdef OCCT_DEBUG
58 extern Standard_Boolean TopOpeBRepBuild_GettraceKPB();
debiskole()59 void debiskole() {}
60 #endif
61 
62 Standard_EXPORT Standard_Boolean FUNKP_KPiskolesh(const TopOpeBRepBuild_Builder& BU,const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Shape& Sarg,TopTools_ListOfShape& lShsd,TopTools_ListOfShape& lfhsd);
63 Standard_EXPORT void FUNKP_KPmakefaces(const TopOpeBRepBuild_Builder& BU, const TopoDS_Shape& Fac1, const TopTools_ListOfShape& LF2,
64 				       const TopAbs_State Stfac1, const TopAbs_State Stfac2,
65 				       const Standard_Boolean R1, const Standard_Boolean R2,TopTools_ListOfShape& Lres);
66 
67 
68 //=======================================================================
69 //function : MergeKPartiskole
70 //purpose  :
71 //=======================================================================
72 
MergeKPartiskole()73 void TopOpeBRepBuild_Builder::MergeKPartiskole()
74 {
75 #ifdef OCCT_DEBUG
76   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
77   if (TKPB) KPreturn(myIsKPart);
78   debiskole();
79 #endif
80 
81   Standard_Integer ibid;
82 
83   if ( myIsKPart != 1 ) return;
84 
85   GMapShapes(myShape1,myShape2);
86   // NYI : on doit pouvoir faire l'economie du mapping GMapShapes(...)
87   // NYI en allant chercher l'indice 1,2 retourne par GShapeRank(S)
88   // NYI dans la DS. l'index est defini pour tous les shapes HasSameDomain
89 
90   TopTools_ListOfShape& lmergesha1 = ChangeMerged(myShape1,myState1);
91   ChangeMerged(myShape2,myState2);
92 
93   TopTools_ListOfShape lShsd1,lShsd2; // liste de solides HasSameDomain
94   TopTools_ListOfShape lfhsd1,lfhsd2; // liste de faces HasSameDomain
95   KPiskolesh(myShape1,lShsd1,lfhsd1);
96   KPiskolesh(myShape2,lShsd2,lfhsd2);
97   // traitement de tous les solides NYI
98   TopoDS_Shape sol1 = lShsd1.First();
99   TopoDS_Shape sol2 = lShsd2.First();
100 
101   ChangeMerged(sol1,myState1);
102   ChangeMerged(sol2,myState2);
103 
104   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm1;
105   itm1.Initialize(myKPMAPf1f2);
106   if ( ! itm1.More() ) return;
107 
108 #ifdef OCCT_DEBUG
109   if (TKPB) {
110     std::cout<<""<<std::endl;
111     for (; itm1.More();itm1.Next()) {
112       const TopoDS_Shape& f = itm1.Key();
113       Standard_Integer fi = myDataStructure->Shape(f);
114       std::cout<<"face "<<fi<<" : ";
115       const TopTools_ListOfShape& l = itm1.Value();
116       TopTools_ListIteratorOfListOfShape it(l);
117       for(; it.More(); it.Next()) {
118 	const TopoDS_Shape& ff = it.Value();
119 	Standard_Integer ffi = myDataStructure->Shape(ff);
120 	std::cout<<ffi<<" ";
121       }
122       std::cout<<std::endl;
123     }
124     itm1.Initialize(myKPMAPf1f2);
125   }
126 #endif
127 
128   TopTools_ListOfShape  LFIN;
129   TopTools_ListOfShape* plfIN = NULL;
130   const TopoDS_Shape* pfOU = NULL;
131   const TopoDS_Shape* pfIN = NULL;
132 
133   for (; itm1.More();itm1.Next()) {
134 //    const TopoDS_Shape& f = itm1.Key();
135 //   myDataStructure->Shape(f); //DEB
136     const TopTools_ListOfShape& los = itm1.Value();
137     Standard_Boolean emp = los.IsEmpty();
138     if (!emp) {
139       if (plfIN == NULL) plfIN = (TopTools_ListOfShape*)&itm1.Value();
140       if (pfOU == NULL) pfOU = &itm1.Key();
141       if (pfIN == NULL) pfIN = &plfIN->First();
142       for (TopTools_ListIteratorOfListOfShape it(los);it.More();it.Next()) LFIN.Append(it.Value());
143     }
144   }
145 
146   if ( plfIN==NULL) return;
147   if ( pfOU==NULL) return;
148   if ( pfIN==NULL) return;
149 
150 #ifdef OCCT_DEBUG
151   Standard_Integer ifOU; Standard_Boolean tSPS = GtraceSPS(*pfOU,ifOU);
152   if(tSPS || TKPB) {
153 //    Standard_Integer iOU = myDataStructure->Shape(*pfOU);
154 //    Standard_Integer iIN = myDataStructure->Shape(*pfIN);
155     GdumpSHA(*pfOU, (char *) "MergeKPartiskole pfOU ");std::cout<<std::endl;
156     GdumpSAMDOM(LFIN, (char *) "LFIN : ");
157     debiskole();
158   }
159 #endif
160 
161   Standard_Integer rankpfOU = GShapeRank(*pfOU);
162   Standard_Integer rankpfIN = GShapeRank(*pfIN);
163   if ( rankpfOU != 1 && rankpfOU != 2 ) return;
164   if ( rankpfIN != 1 && rankpfIN != 2 ) return;
165 
166   // solfOU = solide dont la face *pfOU est OUT / faces LFIN
167   // solfIN = solide dont les faces *plfIN sont IN / face *pfOU
168   TopoDS_Shape solfOU;
169   if (rankpfOU == 1) solfOU = sol1;
170   else               solfOU = sol2;
171   TopoDS_Shape solfIN;
172   if (rankpfIN == 1) solfIN = sol1;
173   else               solfIN = sol2;
174   TopAbs_State stsolfOU = KPclasSS(solfOU,*pfOU, solfIN);
175   TopAbs_State stsolfIN = KPclasSS(solfIN,LFIN,solfOU);
176   TopAbs_State stfOU = TopAbs_OUT;
177   TopAbs_State stfIN = TopAbs_IN;
178 
179   TopAbs_State stsol1=TopAbs_UNKNOWN,stsol2=TopAbs_UNKNOWN;
180   TopAbs_State stfac1=TopAbs_UNKNOWN,stfac2=TopAbs_UNKNOWN;
181   TopoDS_Shape fac1,fac2;
182   if      (rankpfOU == 1 ) {
183     stsol1 = stsolfOU; stfac1 = stfOU; fac1 = *pfOU;
184     stsol2 = stsolfIN; stfac2 = stfIN; fac2 = *pfIN;
185   }
186   else if (rankpfOU == 2 ) {
187     stsol1 = stsolfIN; stfac1 = stfIN; fac1 = *pfIN;
188     stsol2 = stsolfOU; stfac2 = stfOU; fac2 = *pfOU;
189   }
190 
191   Standard_Integer ires,icla1,icla2;
192   KPiskoleanalyse(stfac1,stfac2,stsol1,stsol2,ires,icla1,icla2);
193   if (ires == RESUNDEF) return;
194   if (icla1 == SHEUNDEF || icla2 == SHEUNDEF) return;
195 
196   TopoDS_Shape she1; // she1 = shell accedant fac1
197   TopTools_IndexedDataMapOfShapeListOfShape Mfacshe1;
198   TopExp::MapShapesAndAncestors(sol1,TopAbs_FACE,TopAbs_SHELL,Mfacshe1);
199   const TopTools_ListOfShape& lshe1 = Mfacshe1.FindFromKey(fac1);
200   TopTools_ListIteratorOfListOfShape itlshe1(lshe1);
201   she1 = itlshe1.Value();
202 
203   TopoDS_Shape she2; // she2 = shell accedant fac2
204   TopTools_IndexedDataMapOfShapeListOfShape Mfacshe2;
205   TopExp::MapShapesAndAncestors(sol2,TopAbs_FACE,TopAbs_SHELL,Mfacshe2);
206   const TopTools_ListOfShape& lshe2 = Mfacshe2.FindFromKey(fac2);
207   TopTools_ListIteratorOfListOfShape itlshe2(lshe2);
208   she2 = itlshe2.Value();
209 
210   ChangeMerged(she1,myState1);
211   ChangeMerged(she2,myState2);
212 
213 #ifdef OCCT_DEBUG
214   if (TKPB) { std::cout<<"stsol1 ";TopAbs::Print(stsol1,std::cout); std::cout<<" "; }
215   if (TKPB) { std::cout<<"stsol2 ";TopAbs::Print(stsol2,std::cout); std::cout<<std::endl; }
216   debiskole();
217 #endif
218 
219   TopoDS_Shell newshe;
220 
221   if      ( ires == RESNULL ) {
222     return;
223   }
224 
225   else if (ires == RESSHAPE1) {
226     myBuildTool.MakeShell(newshe);
227     newshe = TopoDS::Shell(she1);
228   }
229 
230   else if (ires == RESSHAPE2) {
231     myBuildTool.MakeShell(newshe);
232     newshe = TopoDS::Shell(she2);
233   }
234 
235   else if ( ires == RESFACE1 ) {
236     if      (rankpfOU == 1) {
237       // resultat = face de rang 1 et face de rang 1 = face OUT
238       lmergesha1.Append(*pfOU);
239       ChangeMerged(fac2,myState2).Append(*pfOU);
240     }
241     else if (rankpfOU == 2) {
242       // resultat = face de rang 1 et face de rang 1 = faces IN
243       GCopyList(*plfIN,lmergesha1);
244       GCopyList(*plfIN,ChangeMerged(fac2,myState2));
245     }
246     return;
247   }
248 
249   else if ( ires == RESFACE2 ) {
250     if      (rankpfOU == 2) {
251       // resultat = face de rang 2 et face de rang 2 = face OUT
252       lmergesha1.Append(*pfOU);
253       ChangeMerged(fac1,myState1).Append(*pfOU);
254     }
255     else if (rankpfOU == 1) {
256       // resultat = face de rang 2 et face de rang 2 = faces IN
257       GCopyList(*plfIN,lmergesha1);
258       GCopyList(*plfIN,ChangeMerged(fac1,myState1));
259     }
260     return;
261   }
262 
263   else if (ires == RESNEWSHE) {
264 
265     itm1.Initialize(myKPMAPf1f2);
266     if (! itm1.More() ) return;
267 
268     TopTools_DataMapOfShapeShape addedfaces;
269     for (; itm1.More();itm1.Next()) {
270 
271       const TopoDS_Shape& f1 = itm1.Key();
272       const TopTools_ListOfShape& lf2 = itm1.Value();
273       if (lf2.IsEmpty()) continue;
274 
275       TopTools_ListIteratorOfListOfShape it2;
276       it2.Initialize(lf2);
277       const TopoDS_Shape& f2 = it2.Value();
278 
279 /*#ifdef OCCT_DEBUG
280       Standard_Integer ii1 = myDataStructure->Shape(f1);
281       Standard_Integer ii2 = myDataStructure->Shape(f2);
282 #endif*/
283       Standard_Integer rankf1 = GShapeRank(f1);
284       Standard_Integer rankf2 = GShapeRank(f2);
285       if (rankf1 == 0) continue;
286       if (rankf2 == 0) continue;
287 
288       TopAbs_State stf1,stf2; KPclassFF(f1,f2,stf1,stf2);
289       if ( rankf1 == 1 ) KPiskoleanalyse(stf1,stf2,stsol1,stsol2,ires,ibid,ibid);
290       if ( rankf1 == 2 ) KPiskoleanalyse(stf2,stf1,stsol2,stsol1,ires,ibid,ibid);
291       if (ires == RESUNDEF) continue;
292 
293       Standard_Boolean r1 = (stsol1 == TopAbs_IN);
294       Standard_Boolean r2 = (stsol2 == TopAbs_IN);
295       TopoDS_Shape fac;
296       if ( rankf1 == 1 ) fac = KPmakeface(f1,lf2,stf1,stf2,r1,r2);
297       if ( rankf1 == 2 ) fac = KPmakeface(f1,lf2,stf1,stf2,r2,r1);
298       if ( fac.IsNull() ) continue;
299       if ( ! fac.IsNull() ) addedfaces.Bind(fac,fac);
300 
301       TopAbs_State statemergef1 = (rankf1 == 1) ? myState1 : myState2;
302       TopAbs_State statemergef2 = (rankf2 == 2) ? myState2 : myState1;
303       ChangeMerged(f1,statemergef1).Append(fac);
304       it2.Initialize(lf2);
305       for (;it2.More();it2.Next())
306 	ChangeMerged(it2.Value(),statemergef2).Append(fac);
307 
308       // les faces de she1 sauf les tangentes et celles deja ajoutees
309       TopOpeBRepTool_ShapeExplorer fex1;
310       for (fex1.Init(she1,TopAbs_FACE); fex1.More(); fex1.Next()) {
311 	const TopoDS_Shape& facur = fex1.Current();
312 
313 	Standard_Boolean isfsd   = myKPMAPf1f2.IsBound(facur);
314 	Standard_Boolean isadded = addedfaces.IsBound(facur);
315 	Standard_Boolean toadd =  (!isfsd) && (!isadded) ;
316 
317 	if ( toadd ) {
318 	  TopoDS_Shape fori = facur;
319 	  if (stsol1 == TopAbs_IN) fori.Complement();
320 	  addedfaces.Bind(fori,fori);
321 	}
322       }
323 
324       // les faces de she2 sauf les tangentes et celles deja ajoutees
325       TopOpeBRepTool_ShapeExplorer fex2;
326       for (fex2.Init(she2,TopAbs_FACE); fex2.More(); fex2.Next()) {
327 	const TopoDS_Shape& facur = fex2.Current();
328 
329 	Standard_Boolean isfsd   = myKPMAPf1f2.IsBound(facur);
330 	Standard_Boolean isadded = addedfaces.IsBound(facur);
331 	Standard_Boolean toadd =  (!isfsd) && (!isadded) ;
332 
333 	if ( toadd ) {
334 	  TopoDS_Shape fori = facur;
335 	  if (stsol2 == TopAbs_IN) fori.Complement();
336 	  addedfaces.Bind(fori,fori);
337 	}
338       }
339     }  // === fin iteration fac1,fac2
340 
341     TopTools_DataMapIteratorOfDataMapOfShapeShape itadd(addedfaces);
342     Standard_Boolean yauadd = itadd.More();
343     if (yauadd) {
344       myBuildTool.MakeShell(newshe);
345       myBuildTool.Closed(newshe,Standard_True);  // NYI : check exact du caractere closed du shell
346     }
347     for (; itadd.More(); itadd.Next() ) {
348       const TopoDS_Shape& ftoadd = itadd.Key();
349       myBuildTool.AddShellFace(newshe,ftoadd);
350     }
351 
352   } // === fin RESNEWSHE
353 
354   else {
355 #ifdef OCCT_DEBUG
356     std::cout<<"MergeKPartiskole : ires = "<<ires<<std::endl;
357 #endif
358   }
359 
360   TopoDS_Solid newsol;
361   if ( !newshe.IsNull() ) {
362     myBuildTool.MakeSolid(newsol);
363     myBuildTool.AddSolidShell(newsol,newshe);
364   }
365 
366   if ( icla1 == SHECLASAUTR || icla1 == SHEGARDAUTR ) {
367     // n.b. : ne pas prendre she1 accedant f1
368     TopTools_ListOfShape loshe1;
369     TopOpeBRepTool_ShapeExplorer ex1;
370     for (ex1.Init(sol1,TopAbs_SHELL); ex1.More(); ex1.Next()) {
371       const TopoDS_Shape& shecur = ex1.Current();
372       if (she1.IsEqual(shecur)) continue;
373       if (icla1 == SHECLASAUTR) {
374 	TopAbs_State state1 = KPclasSS(shecur,fac1,sol2);
375 	if (state1 == myState1) loshe1.Append(shecur);
376       }
377       else if (icla1 == SHEGARDAUTR) {
378 	loshe1.Append(shecur);
379       }
380     }
381 #ifdef OCCT_DEBUG
382 //    Standard_Integer nshe1 = loshe1.Extent();
383 #endif
384     TopTools_ListIteratorOfListOfShape itloshe1;
385     for( itloshe1.Initialize(loshe1); itloshe1.More(); itloshe1.Next() ) {
386       const TopoDS_Shape& shecur = itloshe1.Value();
387       myBuildTool.AddSolidShell(newsol,shecur);
388     }
389   }
390 
391   if ( icla2 == SHECLASAUTR || icla2 == SHEGARDAUTR ) {
392     // n.b. : ne pas prendre she2 accedant f2
393     TopTools_ListOfShape loshe2;
394     TopOpeBRepTool_ShapeExplorer ex2;
395     for (ex2.Init(sol2,TopAbs_SHELL); ex2.More(); ex2.Next()) {
396       const TopoDS_Shape& shecur = ex2.Current();
397       if (she2.IsEqual(shecur)) continue;
398       if      (icla2 == SHECLASAUTR) {
399 	TopAbs_State state2 = KPclasSS(shecur,fac2,sol1);
400 	if (state2 == myState2) loshe2.Append(shecur);
401       }
402       else if (icla2 == SHEGARDAUTR) {
403 	loshe2.Append(shecur);
404       }
405     }
406 #ifdef OCCT_DEBUG
407 //    Standard_Integer nshe2 = loshe2.Extent();
408 #endif
409     TopTools_ListIteratorOfListOfShape itloshe2;
410     for( itloshe2.Initialize(loshe2); itloshe2.More(); itloshe2.Next() ) {
411       const TopoDS_Shape& shecur = itloshe2.Value();
412       myBuildTool.AddSolidShell(newsol,shecur);
413     }
414   }
415 
416   // le solide final
417   if ( !newsol.IsNull() ) {
418     lmergesha1.Append(newsol);
419   }
420 
421 } // MergeKPartiskole
422 
423 
424 //=======================================================================
425 //function : KPiskole
426 //purpose  : detection faces collees
427 //=======================================================================
428 
KPiskole()429 Standard_Integer TopOpeBRepBuild_Builder::KPiskole()
430 {
431 
432   TopTools_ListOfShape lShsd1,lShsd2; // liste de solides HasSameDomain
433   TopTools_ListOfShape lfhsd1,lfhsd2; // liste de faces HasSameDomain
434 
435   Standard_Boolean iskp1 = KPiskolesh(myShape1,lShsd1,lfhsd1);
436   if ( !iskp1 ) return 0;
437   Standard_Integer nfhsd1 = lfhsd1.Extent();
438   if ( nfhsd1 == 0 ) return 0;
439 
440   Standard_Boolean iskp2 = KPiskolesh(myShape2,lShsd2,lfhsd2);
441   if ( !iskp2 ) return 0;
442   Standard_Integer nfhsd2 = lfhsd2.Extent();
443   if ( nfhsd2 == 0 ) return 0;
444 
445   // Si l'un des objets est constitue de plusieur solides on passe
446   // dans le cas general , sinon on obtient
447   //** Exception ** Standard_OutOfRange: TCollection_IndexedDataMap::FindFromKey at
448   // TopOpeBRepBuild_Builder::MergeKPartiskole(this = 0xf7988),
449   // line 397 in "/adv_21/MDL/k1deb/ref/prod/TopOpeBRepBuild/src/TopOpeBRepBuild_KPart.cxx"
450   // DPF le 10/07/1997
451   Standard_Integer nshsd1 = lShsd1.Extent();
452   Standard_Integer nshsd2 = lShsd2.Extent();
453   if (nshsd1>1 || nshsd2>1) return 0;
454 
455   TopTools_ListOfShape lf1,lf2;
456   TopTools_ListOfShape les; //section
457 
458   for (TopTools_ListIteratorOfListOfShape itlf1(lfhsd1);
459        itlf1.More();itlf1.Next()) {
460 
461     const TopoDS_Shape& f1 = itlf1.Value();
462 #ifdef OCCT_DEBUG
463 //    Standard_Boolean isb1 = myKPMAPf1f2.IsBound(f1); // DEB
464 #endif
465     lf1.Clear(); lf1.Append(f1);
466     lf2.Clear(); KPSameDomain(lf1,lf2);
467 #ifdef OCCT_DEBUG
468 //    Standard_Integer n1 = lf1.Extent();
469 //    Standard_Integer n2 = lf2.Extent();
470 #endif
471 
472 #ifdef OCCT_DEBUG
473     Standard_Integer iF1; Standard_Boolean tSPS1 = GtraceSPS(f1,iF1);
474     if(tSPS1) {
475       GdumpSHA(f1, (char *) "KPiskole ");std::cout<<std::endl;
476       GdumpSAMDOM(lf2, (char *) "lf2 : ");
477     }
478 #endif
479 
480     for (TopTools_ListIteratorOfListOfShape itlf2(lf2);
481 	 itlf2.More(); itlf2.Next() ) {
482 
483       const TopoDS_Shape& f2 = itlf2.Value();
484 #ifdef OCCT_DEBUG
485 //      Standard_Boolean isb2 = myKPMAPf1f2.IsBound(f2); // DEB
486 #endif
487       TopAbs_State state1,state2;
488       Standard_Boolean classok = KPiskoleFF(f1,f2,state1,state2);
489       if ( ! classok ) return 0;
490 
491       // on va reconstuire la face OUT
492       if ( state1 == TopAbs_OUT && state2 == TopAbs_IN) {
493 	Standard_Boolean isb1 = myKPMAPf1f2.IsBound(f1);
494 	if ( ! isb1 ) { TopTools_ListOfShape los; myKPMAPf1f2.Bind(f1,los); }
495 	TopTools_ListOfShape& los = myKPMAPf1f2.ChangeFind(f1);
496 	los.Append(f2);
497 
498 	Standard_Boolean isb2 = myKPMAPf1f2.IsBound(f2);
499 	if ( ! isb2 ) { TopTools_ListOfShape los1; myKPMAPf1f2.Bind(f2,los1); }
500       }
501       else if ( state2 == TopAbs_OUT && state1 == TopAbs_IN) {
502 	Standard_Boolean isb2 = myKPMAPf1f2.IsBound(f2);
503 	if ( ! isb2 ) { TopTools_ListOfShape los; myKPMAPf1f2.Bind(f2,los); }
504 	TopTools_ListOfShape& los = myKPMAPf1f2.ChangeFind(f2);
505 	los.Append(f1);
506 
507 	Standard_Boolean isb1 = myKPMAPf1f2.IsBound(f1);
508 	if ( ! isb1 ) { TopTools_ListOfShape los1; myKPMAPf1f2.Bind(f1,los1); }
509       }
510 
511       // les aretes de la face IN sont des aretes de section
512       TopoDS_Shape fw;
513       if      (state1 == TopAbs_IN) fw = f1;
514       else if (state2 == TopAbs_IN) fw = f2;
515       if (fw.IsNull()) continue;
516 
517       TopOpeBRepTool_ShapeExplorer ex(fw,TopAbs_EDGE);
518       for (;ex.More();ex.Next()) les.Append(ex.Current());
519     }
520   }
521 
522   // aretes de section iskole
523   TopOpeBRepDS_DataStructure& DS = myDataStructure->ChangeDS();
524   DS.InitSectionEdges(); TopTools_ListIteratorOfListOfShape it(les);
525   for (;it.More();it.Next()) DS.AddSectionEdge(TopoDS::Edge(it.Value()));
526 
527   return 1;
528 } // TopOpeBRepBuild_Builder::KPiskole
529 
530 //=======================================================================
531 //function : KPiskoleanalyse
532 //purpose  :
533 //=======================================================================
534 
KPiskoleanalyse(const TopAbs_State Stfac1,const TopAbs_State Stfac2,const TopAbs_State Stsol1,const TopAbs_State Stsol2,Standard_Integer & ires,Standard_Integer & icla1,Standard_Integer & icla2) const535 void TopOpeBRepBuild_Builder::KPiskoleanalyse(const TopAbs_State Stfac1, const TopAbs_State Stfac2,
536 			   const TopAbs_State Stsol1, const TopAbs_State Stsol2,
537 			   Standard_Integer& ires,Standard_Integer& icla1,Standard_Integer& icla2) const
538 {
539   ires = RESUNDEF; icla1 = icla2 = SHEUNDEF;
540 
541   if      (Opefus())  {
542     if      (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
543       ires = RESNEWSHE; icla1 = SHEGARDAUTR; icla2 = SHEGARDAUTR;
544     }
545     else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
546       ires = RESSHAPE1; icla1 = SHECLASAUTR; icla2 = SHEAUCU;
547     }
548     else if (Stsol1 == TopAbs_IN  && Stsol2 == TopAbs_OUT) {
549       ires = RESSHAPE2; icla1 = SHEAUCU; icla2 = SHECLASAUTR;
550     }
551   }
552   else if (Opec12()) {
553     if      (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
554       ires = RESSHAPE1; icla1 = SHEGARDAUTR; icla2 = SHEAUCU;
555     }
556     else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
557       ires = RESNEWSHE; icla1 = SHECLASAUTR; icla2 = SHEAUCU;
558     }
559     else if (Stsol1 == TopAbs_IN  && Stsol2 == TopAbs_OUT) {
560       ires = RESNULL; icla1 = icla2 = SHEAUCU;
561     }
562   }
563   else if (Opec21()) {
564     if      (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
565       ires = RESSHAPE2; icla1 = SHEAUCU; icla2 = SHEGARDAUTR;
566     }
567     else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
568       ires = RESNULL; icla1 = icla2 = SHEAUCU;
569     }
570     else if (Stsol1 == TopAbs_IN  && Stsol2 == TopAbs_OUT) {
571       ires = RESNEWSHE; icla1 = SHEAUCU; icla2 = SHECLASAUTR;
572     }
573   }
574   else if (Opecom()) {
575     if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
576       if (Stfac1 == TopAbs_IN) {
577 	ires = RESFACE1; icla1 = icla2 = SHEAUCU;
578       }
579       if (Stfac2 == TopAbs_IN) {
580 	ires = RESFACE2; icla1 = icla2 = SHEAUCU;
581       }
582     }
583     else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
584       ires = RESSHAPE2; icla1 = SHECLASAUTR; icla2 = SHEGARDAUTR;
585     }
586     else if (Stsol1 == TopAbs_IN  && Stsol2 == TopAbs_OUT) {
587       ires = RESSHAPE1; icla1 = SHEGARDAUTR; icla2 = SHECLASAUTR;
588     }
589   }
590 
591 #ifdef OCCT_DEBUG
592   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
593   if (TKPB) std::cout<<"ires = "<<ires<<" icla1 "<<icla1<<" icla2 "<<icla2<<std::endl;
594 #endif
595 } // TopOpeBRepBuild_Builder::KPiskoleanalyse
596 
FUNKP_KPmakefaces(const TopOpeBRepBuild_Builder & BU,const TopoDS_Shape & Fac1,const TopTools_ListOfShape & LF2,const TopAbs_State Stfac1,const TopAbs_State,const Standard_Boolean R1,const Standard_Boolean R2,TopTools_ListOfShape & Lres)597 Standard_EXPORT void FUNKP_KPmakefaces(const TopOpeBRepBuild_Builder& BU,
598                                        const TopoDS_Shape& Fac1,
599                                        const TopTools_ListOfShape& LF2,
600 				       const TopAbs_State Stfac1,
601                                        const TopAbs_State /*Stfac2*/,
602 				       const Standard_Boolean R1,
603                                        const Standard_Boolean R2,
604                                        TopTools_ListOfShape& Lres)
605 {
606   // reconstruisons la face qui contient les autres
607   BRep_Builder BB;
608   TopoDS_Face fac; BB.MakeFace(fac);
609 
610   Standard_Integer rankIN = 0;
611   TopTools_ListOfShape LFSO,LFDO;
612 
613 #ifdef OCCT_DEBUG
614   Standard_Integer iF1; Standard_Boolean tSPS = BU.GtraceSPS(Fac1,iF1);
615   if(tSPS) { BU.GdumpSHA(Fac1, (char *) "KPmakeFace ");std::cout<<std::endl; }
616 #endif
617 
618   if (Stfac1 == TopAbs_OUT) {
619     TopoDS_Shape aLocalShape = Fac1.EmptyCopied();
620     fac = TopoDS::Face(aLocalShape);
621 //    fac = TopoDS::Face(Fac1.EmptyCopied());
622     Standard_Integer rankF = BU.GShapeRank(Fac1);
623     rankIN = (rankF) ? ( (rankF==1) ? 2 : 1) : 0;
624     BU.GFindSamDomSODO(Fac1,LFSO,LFDO);
625   }
626   else {
627     throw Standard_ProgramError("KPmakeface Stfac1 != OUT");
628   }
629 
630   if (rankIN == 0) {
631     throw Standard_ProgramError("KPmakeface rankIN = 0");
632   }
633 
634   TopTools_ListOfShape LFIN;
635   BU.GFindSameRank(LFSO,rankIN,LFIN);
636   BU.GFindSameRank(LFDO,rankIN,LFIN);
637 
638 #ifdef OCCT_DEBUG
639   if(tSPS) {
640     BU.GdumpSAMDOM(LFSO, (char *) "LESO : ");
641     BU.GdumpSAMDOM(LFDO, (char *) "LEDO : ");
642     BU.GdumpSAMDOM(LFIN, (char *) "LFIN : ");
643   }
644 #endif
645 
646   TopOpeBRepBuild_WireToFace wtof;
647 
648   TopOpeBRepTool_ShapeExplorer wex1;
649   for (wex1.Init(Fac1,TopAbs_WIRE); wex1.More(); wex1.Next()) {
650     const TopoDS_Shape& wicur = wex1.Current();
651     TopoDS_Wire wori = TopoDS::Wire(wicur);
652     if (R1) wori.Complement();
653     wtof.AddWire(wori);
654     //myBuildTool.AddFaceWire(fac,wori);
655   }
656 
657   TopOpeBRepTool_ShapeExplorer wex2;
658   for (TopTools_ListIteratorOfListOfShape it2(LF2);it2.More();it2.Next()) {
659     const TopoDS_Shape& Fac2 = it2.Value();
660     for (wex2.Init(Fac2,TopAbs_WIRE); wex2.More(); wex2.Next()) {
661       const TopoDS_Shape& wicur = wex2.Current();
662       TopoDS_Wire wori = TopoDS::Wire(wicur);
663       if (R2) wori.Complement();
664       wtof.AddWire(wori);
665       //myBuildTool.AddFaceWire(fac,wori);
666     }
667   }
668 
669   const TopoDS_Face& F1 = TopoDS::Face(Fac1);
670   wtof.MakeFaces(F1,Lres);
671 #ifdef OCCT_DEBUG
672 //  Standard_Integer nlres = Lres.Extent(); // DEB
673 #endif
674 
675   return;
676 } // FUNKP_KPmakefaces
677 
678 //=======================================================================
679 //function : KPmakeface
680 //purpose  :
681 //=======================================================================
682 
KPmakeface(const TopoDS_Shape & Fac1,const TopTools_ListOfShape & LF2,const TopAbs_State Stfac1,const TopAbs_State,const Standard_Boolean R1,const Standard_Boolean R2)683 TopoDS_Shape TopOpeBRepBuild_Builder::KPmakeface(const TopoDS_Shape& Fac1,
684                                                  const TopTools_ListOfShape& LF2,
685                                                  const TopAbs_State Stfac1,
686                                                  const TopAbs_State /*Stfac2*/,
687                                                  const Standard_Boolean R1,
688                                                  const Standard_Boolean R2)
689 {
690   // reconstruisons la face qui contient l'autre
691   BRep_Builder BB;
692   TopoDS_Face fac; BB.MakeFace(fac);
693 
694   Standard_Integer rankIN = 0;
695   TopTools_ListOfShape LFSO,LFDO;
696 
697 #ifdef OCCT_DEBUG
698   Standard_Integer iF1;
699   Standard_Boolean tSPS = GtraceSPS(Fac1,iF1);
700   if(tSPS) {
701     GdumpSHA(Fac1, (char *) "KPmakeFace ");
702     std::cout<<std::endl;
703   }
704 #endif
705 
706   if (Stfac1 == TopAbs_OUT) {
707     TopoDS_Shape aLocalShape = Fac1.EmptyCopied();
708     fac = TopoDS::Face(aLocalShape);
709 //    fac = TopoDS::Face(Fac1.EmptyCopied());
710     Standard_Integer rankF = GShapeRank(Fac1);
711     rankIN = (rankF) ? ( (rankF==1) ? 2 : 1) : 0;
712     GFindSamDomSODO(Fac1,LFSO,LFDO);
713   }
714   else {
715     throw Standard_ProgramError("KPmakeface Stfac1 != OUT");
716   }
717 
718   if (rankIN == 0) {
719     throw Standard_ProgramError("KPmakeface rankIN = 0");
720   }
721 
722   TopTools_ListOfShape LFIN;
723   GFindSameRank(LFSO,rankIN,LFIN);
724   GFindSameRank(LFDO,rankIN,LFIN);
725 
726 #ifdef OCCT_DEBUG
727   if(tSPS) {
728     GdumpSAMDOM(LFSO, (char *) "LESO : ");
729     GdumpSAMDOM(LFDO, (char *) "LEDO : ");
730     GdumpSAMDOM(LFIN, (char *) "LFIN : ");
731   }
732 #endif
733 
734 
735   TopOpeBRepTool_ShapeExplorer wex1;
736   for (wex1.Init(Fac1,TopAbs_WIRE); wex1.More(); wex1.Next()) {
737     const TopoDS_Shape& wicur = wex1.Current();
738     TopoDS_Shape wori = wicur;
739     if (R1) wori.Complement();
740     myBuildTool.AddFaceWire(fac,wori);
741   }
742 
743   TopOpeBRepTool_ShapeExplorer wex2;
744   for (TopTools_ListIteratorOfListOfShape it2(LF2);it2.More();it2.Next()) {
745     const TopoDS_Shape& Fac2 = it2.Value();
746     for (wex2.Init(Fac2,TopAbs_WIRE); wex2.More(); wex2.Next()) {
747       const TopoDS_Shape& wicur = wex2.Current();
748       TopoDS_Shape wori = wicur;
749       if (R2) wori.Complement();
750       myBuildTool.AddFaceWire(fac,wori);
751     }
752   }
753 
754   return fac;
755 } // TopOpeBRepBuild_Builder::KPmakeface
756 
FUNKP_KPiskolesh(const TopOpeBRepBuild_Builder & BU,const TopOpeBRepDS_DataStructure & BDS,const TopoDS_Shape & Sarg,TopTools_ListOfShape & lShsd,TopTools_ListOfShape &)757 Standard_EXPORT Standard_Boolean FUNKP_KPiskolesh(const TopOpeBRepBuild_Builder& BU,
758                                                   const TopOpeBRepDS_DataStructure& BDS,
759                                                   const TopoDS_Shape& Sarg,
760                                                   TopTools_ListOfShape& lShsd,
761                                                   TopTools_ListOfShape& /*lfhsd*/)
762      // <lShsd> : the list of solids same domain with <Sarg>
763      // sol is  <lShsd>'s first solid
764      // <lfhsd> : the list of <sol>'s same domain faces, none of the list carries geometric interf
765 {
766   if ( Sarg.IsNull() ) return Standard_False;
767 
768   Standard_Integer nsol = BU.KPlhsd(Sarg,TopAbs_SOLID,lShsd);
769   if ( nsol == 0 ) return Standard_False;
770   const TopoDS_Shape& sol = lShsd.First();
771 
772   TopTools_ListOfShape lfhg;
773   Standard_Integer nfhg = BU.KPlhg(sol,TopAbs_FACE,lfhg);
774   if ( nfhg != 0 ) {
775     TopTools_ListIteratorOfListOfShape its(lfhg);
776     for(; its.More(); its.Next()) {
777       TopOpeBRepDS_ListIteratorOfListOfInterference iti(BDS.ShapeInterferences(its.Value()));
778       for (;iti.More();iti.Next()) {
779 	Handle(TopOpeBRepDS_ShapeShapeInterference) ssi;
780 	ssi = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(iti.Value());
781 	if (ssi.IsNull()) {
782 	  return Standard_False;
783 	}
784       }
785     }
786   }
787   return Standard_True;
788 } // FUNKP_KPiskolesh
789 
790 //=======================================================================
791 //function : KPiskolesh
792 //purpose  :
793 // KPiskolesh :
794 // S est il un shape traite par le cas particulier du collage ?
795 // si oui : retourne un solide et une liste de faces de collage
796 //=======================================================================
797 
KPiskolesh(const TopoDS_Shape & Sarg,TopTools_ListOfShape & lShsd,TopTools_ListOfShape & lfhsd) const798 Standard_Boolean TopOpeBRepBuild_Builder::KPiskolesh(const TopoDS_Shape& Sarg,
799                                                      TopTools_ListOfShape& lShsd,
800                                                      TopTools_ListOfShape& lfhsd) const
801 {
802 #ifdef OCCT_DEBUG
803   Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
804 #endif
805   const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
806   Standard_Boolean iskolesh = FUNKP_KPiskolesh(*this,BDS,Sarg,lShsd,lfhsd);
807   if (!iskolesh) return Standard_False;
808 
809 #ifdef OCCT_DEBUG
810   Standard_Integer nfhsd =
811 #endif
812               KPlhsd(Sarg,TopAbs_FACE,lfhsd);
813   TopTools_ListIteratorOfListOfShape it(lfhsd);
814   for (; it.More(); it.Next() ) {
815     const TopoDS_Shape& fac = it.Value();
816     Standard_Boolean isplan = FUN_tool_plane(fac); //pro7993 BUG
817     if ( !isplan ) return Standard_False;
818 
819     Standard_Integer nw = KPls(fac,TopAbs_WIRE);
820     if (nw > 1) return Standard_False;
821 
822     TopTools_ListOfShape lehg;
823     Standard_Integer nehg = KPlhg(fac,TopAbs_EDGE,lehg);
824     if ( nehg != 0 ) return Standard_False;
825 
826 #ifdef OCCT_DEBUG
827     Standard_Integer isol = myDataStructure->Shape(Sarg);
828     Standard_Integer ifac = myDataStructure->Shape(fac);
829     if(TKPB){std::cout<<"isol "<<isol<<std::endl;}
830     if(TKPB){std::cout<<"nfhsd  "<<nfhsd<<std::endl;}
831     if(TKPB){std::cout<<"ifac "<<ifac<<std::endl;}
832     if(TKPB){std::cout<<"isplan "<<isplan<<std::endl;}
833     if(TKPB){std::cout<<"nehg "<<nehg<<std::endl;}
834     if(TKPB){std::cout<<std::endl;}
835 #endif
836   }
837 
838   return Standard_True;
839 } // TopOpeBRepBuild_Builder::KPiskolesh
840