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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <TopOpeBRepBuild_Builder.jxx>
19 #include <TopOpeBRepBuild_GTool.hxx>
20 #include <TopOpeBRepTool.hxx>
21 #include <TopOpeBRepTool_ShapeExplorer.hxx>
22 #include <TopOpeBRepDS_BuildTool.hxx>
24 #include <TopoDS_Solid.hxx>
25 #include <TopoDS_Shell.hxx>
26 #include <TopoDS_Wire.hxx>
28 #include <Precision.hxx>
29 #include <TopExp_Explorer.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRep_Builder.hxx>
34 #include <BRepTools.hxx>
35 #include <BRepClass3d.hxx>
36 #include <BRepClass3d_SolidExplorer.hxx>
37 #include <TopOpeBRepTool_EXPORT.hxx>
38 #include <TopOpeBRepTool_SC.hxx>
39 #include <TopOpeBRepDS_EXPORT.hxx>
40 #include <TopOpeBRepDS_connex.hxx>
41 #include <TopOpeBRepBuild_define.hxx>
42 #include <TopOpeBRepBuild_kpresu.hxx>
43 #include <Standard_ProgramError.hxx>
44 #include <TopOpeBRepDS_ShapeShapeInterference.hxx>
47 extern Standard_Boolean TopOpeBRepBuild_GettraceKPB();
50 static void FUN_Raise() {
52 cout<<"******************************ERROR"<<endl;
53 Standard_ProgramError::Raise("KPart.cxx");
57 #define M_REVERSED(st) (st == TopAbs_REVERSED)
59 Standard_EXPORT Standard_Boolean FUNKP_KPiskolesh(const TopOpeBRepBuild_Builder& BU,const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Shape& Sarg,TopTools_ListOfShape& lShsd,TopTools_ListOfShape& lfhsd);
62 //modified by NIZHNY-MKK Fri May 19 17:03:59 2000.BEGIN
63 enum TopOpeBRepBuild_KPart_Operation {TopOpeBRepBuild_KPart_Operation_Fuse, TopOpeBRepBuild_KPart_Operation_Common, TopOpeBRepBuild_KPart_Operation_Cut12, TopOpeBRepBuild_KPart_Operation_Cut21};
65 static void LocalKPisdisjanalyse(const TopAbs_State Stsol1, const TopAbs_State Stsol2,
66 const TopOpeBRepBuild_KPart_Operation& theOperation,
67 Standard_Integer& ires, Standard_Integer& icla1, Standard_Integer& icla2);
69 static TopoDS_Solid BuildNewSolid(const TopoDS_Solid& sol1,
70 const TopoDS_Solid& sol2,
71 const TopAbs_State stsol1,
72 const TopAbs_State stsol2,
73 const Standard_Integer ires,
74 const Standard_Integer icla1,
75 const Standard_Integer icla2,
76 const TopAbs_State theState1,
77 const TopAbs_State theState2);
79 static Standard_Boolean disjPerformFuse(const TopTools_IndexedMapOfShape& theMapOfSolid1,
80 const TopTools_IndexedMapOfShape& theMapOfSolid2,
81 TopTools_IndexedMapOfShape& theMapOfResult);
83 static Standard_Boolean disjPerformCommon(const TopTools_IndexedMapOfShape& theMapOfSolid1,
84 const TopTools_IndexedMapOfShape& theMapOfSolid2,
85 TopTools_IndexedMapOfShape& theMapOfResult);
87 static Standard_Boolean disjPerformCut(const TopTools_IndexedMapOfShape& theMapOfSolid1,
88 const TopTools_IndexedMapOfShape& theMapOfSolid2,
89 TopTools_IndexedMapOfShape& theMapOfResult);
90 //modified by NIZHNY-MKK Fri May 19 17:04:07 2000.END
93 //=======================================================================
94 //function : FindIsKPart
96 //=======================================================================
98 Standard_Integer TopOpeBRepBuild_Builder::FindIsKPart()
103 Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
104 if(TKPB){cout<<endl<<"--- IsKPart ? ---"<<endl;}
107 Standard_Integer isfafa = KPisfafa();
108 // face,face SameDomain
111 return KPreturn(myIsKPart);
114 Standard_Integer isdisj = KPisdisj();
115 // shape,shape sans aucune interference geometrique
118 return KPreturn(myIsKPart);
121 Standard_Integer iskole = KPiskole();
122 // solide,solide colles par faces tangentes sans aretes tangentes
125 return KPreturn(myIsKPart);
128 Standard_Integer iskoletge = KPiskoletge();
129 // solide,solide par faces tangentes avec aretes tangentes
132 return KPreturn(myIsKPart);
135 Standard_Integer issoso = KPissoso();
136 // solide,solide quelconques
139 return KPreturn(myIsKPart);
143 return KPreturn(myIsKPart);
146 //=======================================================================
149 //=======================================================================
151 Standard_Integer TopOpeBRepBuild_Builder::IsKPart() const
157 //=======================================================================
158 //function : MergeKPart
160 //=======================================================================
162 void TopOpeBRepBuild_Builder::MergeKPart(const TopAbs_State TB1,
163 const TopAbs_State TB2)
170 //=======================================================================
171 //function : MergeKPart
173 //=======================================================================
175 void TopOpeBRepBuild_Builder::MergeKPart()
177 if ( myIsKPart == 1 ) { // iskole
180 else if ( myIsKPart == 5 ) { // iskoletge
181 MergeKPartiskoletge();
183 else if (myIsKPart == 2) { // isdisj
186 else if ( myIsKPart == 3 ) { // isfafa
189 else if ( myIsKPart == 4 ) { // issoso
195 static void FUN_sortplcy(const TopTools_ListOfShape& lof, TopTools_ListOfShape& lopl, TopTools_ListOfShape& locy)
197 TopTools_ListIteratorOfListOfShape it(lof);
198 for (; it.More(); it.Next()){
199 const TopoDS_Face& ff = TopoDS::Face(it.Value());
200 Standard_Boolean plane = FUN_tool_plane(ff);
201 if (plane) {lopl.Append(ff);}
202 Standard_Boolean cylinder = FUN_tool_cylinder(ff);
203 if (cylinder){locy.Append(ff);}
207 /*static Standard_Boolean FUN_proj2(const TopOpeBRepBuild_Builder& BU, const Handle(TopOpeBRepDS_HDataStructure)& HDS,
208 const TopoDS_Shape& Fa2, TopTools_DataMapOfShapeListOfShape& EnewE)
210 const TopoDS_Face& F2 = TopoDS::Face(Fa2);
211 TopoDS_Wire Ow2 = BRepTools::OuterWire(TopoDS::Face(F2));
212 TopExp_Explorer exe(Ow2, TopAbs_EDGE);
213 for (; exe.More(); exe.Next()){
214 const TopoDS_Shape& ed = exe.Current();
215 Standard_Boolean issplit = BU.IsSplit(ed,TopAbs_ON);
216 if (!issplit) return Standard_False;
217 const TopTools_ListOfShape& speds = BU.Splits(ed,TopAbs_ON);
218 TopTools_ListOfShape lfcF2; // faces of shapei connexed to ed
219 FDSCNX_FaceEdgeConnexFaces(TopoDS::Face(F2),ed,HDS,lfcF2);
220 // prequesitory : ed in {edges of Ow2}
221 // ed's faces ancestor = {F2,fofj}
222 if (lfcF2.Extent() != 1) return Standard_False;
223 const TopoDS_Face& fcF2 = TopoDS::Face(lfcF2.First());
225 // projecting sp(ed) on faces F2 and fofj
226 TopTools_ListOfShape newesp;
227 TopTools_ListIteratorOfListOfShape itspe(speds);
228 for (; itspe.More(); itspe.Next()){
229 TopoDS_Edge esp = TopoDS::Edge(itspe.Value());
230 Standard_Boolean ok = FUN_tool_pcurveonF(F2,esp);
231 if (!ok) return Standard_False;
232 ok = FUN_tool_pcurveonF(fcF2,esp);
233 if (!ok) return Standard_False;
234 // EnewE.Add(esp,newesp);
237 EnewE.Bind(ed,newesp);
239 return Standard_True;
242 static void FUN_addf(const TopAbs_State sta, const TopoDS_Shape& ftoadd, TopTools_DataMapOfShapeShape& map)
245 // Standard_Boolean isadded = map.IsBound(ftoadd);
247 TopoDS_Shape fori = ftoadd;
248 if (sta == TopAbs_IN) fori.Complement();
252 static Standard_Integer FUN_comparekoletgesh(TopOpeBRepTool_ShapeClassifier& SC,
253 const TopoDS_Shape& sh1, const TopoDS_Shape& sh2,
254 const TopoDS_Shape& fkole1, const TopoDS_Shape& )
255 // purpose: <sh1> and <sh2> are kpkoletge on faces <fkole1>,<fkole2>
256 // with <fkole1> same oriented with <fkole2>
257 // returns k=1,2 if shi is contained in shk
260 SC.SetReference(sh2);
261 TopExp_Explorer exf(sh1,TopAbs_FACE);
262 for (; exf.More(); exf.Next()){
263 const TopoDS_Face& f1 = TopoDS::Face(exf.Current());
264 if (f1.IsSame(fkole1)) continue;
266 BRepClass3d_SolidExplorer::FindAPointInTheFace(f1,pnt1);
267 SC.StateP3DReference(pnt1);
268 TopAbs_State stpnt1 = SC.State();
269 if (stpnt1 == TopAbs_IN) return 2;
270 if (stpnt1 == TopAbs_OUT) return 1;
275 static Standard_Boolean FUN_changev(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Shape& v)
277 Standard_Boolean changev = HDS->HasShape(v);
278 if (!changev) return Standard_False;
279 changev = HDS->HasSameDomain(v);
280 if (!changev) return Standard_False;
281 Standard_Boolean rankv = HDS->DS().AncestorRank(v);
282 changev = (rankv == 2);
285 static Standard_Boolean FUN_updatev
286 (const Handle(TopOpeBRepDS_HDataStructure)& HDS, TopoDS_Edge& newed,
287 const TopoDS_Vertex& v, const TopAbs_Orientation oriv, const Standard_Real parv, const Standard_Boolean changev)
289 TopOpeBRepDS_BuildTool BT;
292 TopoDS_Shape oov; Standard_Boolean ok = FUN_ds_getoov(v,HDS,oov);
293 if(!ok) return Standard_False;
294 oov.Orientation(oriv);
296 BT.Parameter(newed,oov,parv);
299 TopoDS_Shape aLocalShape = v.Oriented(oriv);
300 TopoDS_Vertex ov = TopoDS::Vertex(aLocalShape);
301 // TopoDS_Vertex ov = TopoDS::Vertex(v.Oriented(oriv));
303 BT.Parameter(newed,ov,parv);
305 return Standard_True;
308 static Standard_Boolean FUN_makefaces(const TopOpeBRepBuild_Builder& BU, const Handle(TopOpeBRepDS_HDataStructure)& HDS, TopTools_DataMapOfShapeListOfShape& EnewE,
309 const TopoDS_Shape& f, const TopoDS_Shape& , TopTools_ListOfShape& newfaces)
310 //prequesitory : <outerwi>=<f>'s outer wire
311 //purpose : <outerwi>={edow},
312 // edow=(vf,vl), if(rank(vj)=2 && vj sdm vj1), replace vj by vj1
316 TopOpeBRepDS_BuildTool BT;
318 TopoDS_Shape aLocalShape = f.Oriented(TopAbs_FORWARD);
319 TopoDS_Face F = TopoDS::Face(aLocalShape); // working on FORWARD face
320 // TopoDS_Face F = TopoDS::Face(f.Oriented(TopAbs_FORWARD)); // working on FORWARD face
321 TopAbs_Orientation of = f.Orientation();
323 //the new outer wire :
324 // -------------------
325 TopTools_ListOfShape loe;
327 TopoDS_Wire outerwf = BRepTools::OuterWire(F);
328 TopExp_Explorer ex(outerwf, TopAbs_EDGE);
329 for (; ex.More(); ex.Next()){
330 const TopoDS_Edge& ed = TopoDS::Edge(ex.Current());
331 TopAbs_Orientation oe = ed.Orientation();
332 Standard_Boolean issplit = BU.IsSplit(ed,TopAbs_ON);
333 Standard_Boolean isbound = EnewE.IsBound(ed);
335 if (!isbound && !issplit) {
337 TopoDS_Vertex vf,vl; TopExp::Vertices(ed,vf,vl);
338 Standard_Boolean changevf = ::FUN_changev(HDS,vf);
339 Standard_Boolean changevl = ::FUN_changev(HDS,vl);
340 Standard_Boolean changee = changevf || changevl;
342 Standard_Real ff = BRep_Tool::Parameter(vf, ed);
343 Standard_Real l = BRep_Tool::Parameter(vl, ed);
345 TopoDS_Edge newed; BT.CopyEdge(ed.Oriented(TopAbs_FORWARD),newed);
346 Standard_Boolean ok = ::FUN_updatev(HDS,newed,vf,TopAbs_FORWARD,ff,changevf);
347 if (!ok) return Standard_False;
348 ok = ::FUN_updatev(HDS,newed,vl,TopAbs_REVERSED,l,changevl);
349 if (!ok) return Standard_False;
350 newed.Orientation(oe);
351 TopTools_ListOfShape led; led.Append(newed); EnewE.Bind(ed,led);
352 isbound = Standard_True;
357 const TopTools_ListOfShape& speds = BU.Splits(ed,TopAbs_ON);
358 if (speds.Extent() == 0) return Standard_False;
359 const TopoDS_Edge& spe = TopoDS::Edge(speds.First());
360 Standard_Boolean sameori = FUN_tool_SameOri(ed,spe);
361 TopAbs_Orientation orisp = spe.Orientation();
362 if (!sameori) orisp = TopAbs::Complement(orisp);
364 TopTools_ListIteratorOfListOfShape it(speds);
365 for (; it.More(); it.Next()) {
366 TopoDS_Edge esp = TopoDS::Edge(it.Value());
367 Standard_Boolean ok = FUN_tool_pcurveonF(TopoDS::Face(f),esp);
368 if (!ok) return Standard_False;
369 TopoDS_Shape ee = esp.Oriented(orisp);
374 const TopTools_ListOfShape& neweds = EnewE.ChangeFind(ed);
375 TopTools_ListIteratorOfListOfShape itnes(neweds);
376 for (; itnes.More(); itnes.Next()) loe.Append(itnes.Value().Oriented(oe));
385 for (TopTools_ListIteratorOfListOfShape itee(loe); itee.More(); itee.Next())
386 BB.Add(newW,itee.Value());
390 aLocalShape = F.EmptyCopied();
391 TopoDS_Face newf = TopoDS::Face(aLocalShape);
392 // TopoDS_Face newf = TopoDS::Face(F.EmptyCopied());
395 // other wires of <f> :
396 TopExp_Explorer exw(F, TopAbs_WIRE);
397 for (; exw.More(); exw.Next()){
398 const TopoDS_Wire OOw = TopoDS::Wire(exw.Current());
399 if (OOw.IsSame(outerwf)) continue;
403 if (M_REVERSED(of)) newf.Orientation(TopAbs_REVERSED);
405 // xpu140898 : CTS21251
406 TopoDS_Face Newf = newf;
407 Standard_Boolean ok = TopOpeBRepTool::CorrectONUVISO(TopoDS::Face(f),Newf);
408 if (ok) newfaces.Append(Newf);
409 else newfaces.Append(newf);
411 return Standard_True;
414 static Standard_Boolean FUN_rebuildfc(const TopOpeBRepBuild_Builder& BU, const Handle(TopOpeBRepDS_HDataStructure)& HDS,
415 const TopAbs_State , const TopoDS_Shape& Fk,
416 TopTools_DataMapOfShapeListOfShape& EnewE, TopTools_IndexedDataMapOfShapeListOfShape& fcnewfc)
417 // Owk = <Fk>'s outer wire
418 //prequesitory: Owk = {edk}, Splits(edk,Stk) = spedk
419 //purpose: fills up <fcnewfc> = {(fcFk,newfcFk)}
420 // with {fcFk} = faces of shape k connexed to Owk
421 // fcFk has edges {edk}
424 // const TopOpeBRepDS_DataStructure& BDS = HDS->DS();
425 // Standard_Integer rFk = BDS.AncestorRank(Fk);
427 TopoDS_Wire Owk = BRepTools::OuterWire(TopoDS::Face(Fk));
428 TopTools_ListOfShape eds; FUN_tool_shapes(Owk,TopAbs_EDGE,eds);
429 TopTools_ListIteratorOfListOfShape ite(eds);
432 for (; ite.More(); ite.Next()){
433 const TopoDS_Shape& ed = ite.Value();
434 TopTools_ListOfShape lfcFk; // faces of shapei connexed to ed
435 FDSCNX_FaceEdgeConnexFaces(TopoDS::Face(Fk),ed,HDS,lfcFk);
436 // prequesitory : ed in {edges of Owk}
437 // ed's faces ancestor = {Fk,fofj}
438 if (lfcFk.Extent() != 1) return Standard_False;
440 // purpose : Building up new topologies on connexed faces
441 // attached to outer wire's edges.
442 const TopoDS_Shape& fcFk = lfcFk.First();
443 TopTools_ListOfShape newfcFk; Standard_Boolean ok = FUN_makefaces(BU,HDS,EnewE,fcFk,Owk,newfcFk);
444 if (!ok) return Standard_False;
445 fcnewfc.Add(fcFk,newfcFk);
447 return Standard_True;
451 Standard_EXPORT void debiskoletge() {}
454 //=======================================================================
455 //function : MergeKPartiskoletge
457 //=======================================================================
459 void TopOpeBRepBuild_Builder::MergeKPartiskoletge()
462 Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
463 if (TKPB) KPreturn(myIsKPart);
467 const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
468 // Standard_Integer ibid;
470 if ( myIsKPart != 5 ) {FUN_Raise(); return;}
472 GMapShapes(myShape1,myShape2);
473 // NYI : on doit pouvoir faire l'economie du mapping GMapShapes(...)
474 // NYI en allant chercher l'indice 1,2 retourne par GShapeRank(S)
475 // NYI dans la DS. l'index est defini pour tous les shapes HasSameDomain
477 TopTools_ListOfShape& lmergesha1 = ChangeMerged(myShape1,myState1);
478 ChangeMerged(myShape2,myState2);
480 TopTools_ListOfShape lShsd1,lShsd2; // liste de solides HasSameDomain
481 TopTools_ListOfShape lfhsd1,lfhsd2; // liste de faces HasSameDomain
482 KPiskoletgesh(myShape1,lShsd1,lfhsd1);
483 KPiskoletgesh(myShape2,lShsd2,lfhsd2);
485 // traitement de tous les solides NYI
486 TopoDS_Shape sol1 = lShsd1.First();
487 TopoDS_Shape sol2 = lShsd2.First();
489 ChangeMerged(sol1,myState1);
490 ChangeMerged(sol2,myState2);
492 TopTools_ListOfShape lplhsd1, lcyhsd1; ::FUN_sortplcy(lfhsd1,lplhsd1,lcyhsd1);
493 TopTools_ListOfShape lplhsd2, lcyhsd2; ::FUN_sortplcy(lfhsd2,lplhsd2,lcyhsd2);
494 const TopoDS_Face& fac1 = TopoDS::Face(lplhsd1.First());
495 const TopoDS_Face& fac2 = TopoDS::Face(lplhsd2.First());
497 Standard_Integer iF1 =
499 myDataStructure->Shape(fac1); //DEB
501 Standard_Integer iF2 =
503 myDataStructure->Shape(fac2); //DEB
506 if (TKPB) {cout<<""<<endl;cout<<"face "<<iF1<<" : ";cout<<iF2<<endl;}
509 TopOpeBRepDS_Config config2 = BDS.SameDomainOri(fac2);
511 Standard_Boolean SameOriented = (config2 == TopOpeBRepDS_SAMEORIENTED);
513 const TopoDS_Shape* pfGRE = NULL;
514 const TopoDS_Shape* pfSMA = NULL;
516 Standard_Integer rgre = 1;
519 rgre = ::FUN_comparekoletgesh(myShapeClassifier,
520 myShape1,myShape2,fac1,fac2);
521 if (rgre == 0) rgre = FUN_tool_comparebndkole(myShape1,myShape2);
523 if (rgre == 0) {FUN_Raise(); return;}
527 Standard_Integer rsma = (rgre == 1)? 2: 1;
528 pfSMA = (rsma == 1)? &fac1: &fac2;
529 pfGRE = (rgre == 1)? &fac1: &fac2;
530 TopAbs_State staSMA = (rsma == 1)? myState1: myState2;
531 TopAbs_State staGRE = (rgre == 1)? myState1: myState2;
533 TopoDS_Shape shaSMA = (rsma == 1)? myShape1: myShape2;
534 TopoDS_Shape shaGRE = (rgre == 1)? myShape1: myShape2;
536 Standard_Integer ires = 0; KPiskoletgeanalyse(config2,staSMA,staGRE,ires);
540 TopoDS_Shape sheSMA; // sheSMA = shell accedant facSMA
541 TopTools_IndexedDataMapOfShapeListOfShape MfacsheSMA;
542 TopExp::MapShapesAndAncestors(shaSMA,TopAbs_FACE,TopAbs_SHELL,MfacsheSMA);
543 const TopTools_ListOfShape& lsheSMA = MfacsheSMA.FindFromKey(*pfSMA);
544 TopTools_ListIteratorOfListOfShape itlsheSMA(lsheSMA);
545 sheSMA = itlsheSMA.Value();
547 TopoDS_Shape sheGRE; // sheGRE = shell accedant facGRE
548 TopTools_IndexedDataMapOfShapeListOfShape MfacsheGRE;
549 TopExp::MapShapesAndAncestors(shaGRE,TopAbs_FACE,TopAbs_SHELL,MfacsheGRE);
550 const TopTools_ListOfShape& lsheGRE = MfacsheGRE.FindFromKey(*pfGRE);
551 TopTools_ListIteratorOfListOfShape itlsheGRE(lsheGRE);
552 sheGRE = itlsheGRE.Value();
554 ChangeMerged(sheSMA, staSMA);
555 ChangeMerged(sheGRE, staGRE);
558 if (ires == RESNULL) {
561 else if (ires == RESSHAPE1) {
562 myBuildTool.MakeShell(newshe);
563 newshe = TopoDS::Shell(sheSMA);
565 else if (ires == RESSHAPE2) {
566 myBuildTool.MakeShell(newshe);
567 newshe = TopoDS::Shell(sheGRE);
569 else if (ires == RESNEWSOL) {
571 TopTools_DataMapOfShapeShape addedfaces;
572 // As splits of outer wire's edges have 2drep only on shape1,
573 // we have to project them on the connexed faces of shape2
574 TopTools_DataMapOfShapeListOfShape EnewE;
575 // Standard_Boolean ok = ::FUN_proj2((*this),myDataStructure,fac2,EnewE);
576 // if (!ok) {FUN_Raise(); return;}
579 TopTools_IndexedDataMapOfShapeListOfShape fcnewfcSMA;// faces connexed to fSMA built up with the split of outerwSMA
580 TopTools_IndexedDataMapOfShapeListOfShape fcnewfcGRE;// faces connexed to fGRE built up with the split of outerwGRE
581 Standard_Boolean ok = ::FUN_rebuildfc((*this),myDataStructure,staSMA,*pfSMA,EnewE,fcnewfcSMA);
582 if (!ok) {FUN_Raise(); return;}
583 Standard_Integer nfcSMA = fcnewfcSMA.Extent();
584 // for (Standard_Integer i=1; i<=nfcSMA; i++) {
586 for ( i=1; i<=nfcSMA; i++) {
587 const TopoDS_Shape& f = fcnewfcSMA.FindKey(i);
588 const TopTools_ListOfShape& newlf = fcnewfcSMA.FindFromIndex(i);
590 TopTools_ListIteratorOfListOfShape it(newlf);
591 for (; it.More(); it.Next()){
592 const TopoDS_Shape& ff = it.Value();
593 ::FUN_addf(staSMA,ff,addedfaces);
594 ChangeMerged(f,staSMA).Append(ff);
597 ok = ::FUN_rebuildfc((*this),myDataStructure,staGRE,*pfGRE,EnewE,fcnewfcGRE);
598 if (!ok) {FUN_Raise(); return;}
599 Standard_Integer nfcGRE = fcnewfcGRE.Extent();
600 for (i=1; i<=nfcGRE; i++) {
601 const TopoDS_Shape& f = fcnewfcGRE.FindKey(i);
602 const TopTools_ListOfShape& newlf = fcnewfcGRE.FindFromIndex(i);
604 TopTools_ListIteratorOfListOfShape it(newlf);
605 for (; it.More(); it.Next()){
606 const TopoDS_Shape& ff = it.Value();
607 ::FUN_addf(staGRE,ff,addedfaces);
608 ChangeMerged(f,staGRE).Append(ff);
613 TopTools_ListOfShape lOOfSMA; // DEB : faces of SMA non connexed to fSMA
614 TopTools_ListOfShape lOOfGRE; // DEB : faces of GRE non connexed to fGRE
615 TopExp_Explorer exSMA(shaSMA, TopAbs_FACE);
616 for (; exSMA.More(); exSMA.Next()){
617 const TopoDS_Shape& ff = exSMA.Current();
618 if (fcnewfcSMA.Contains(ff)) continue;
619 if (ff.IsSame(*pfSMA)) continue;
620 lOOfSMA.Append(ff); // DEB
621 ::FUN_addf(staSMA,ff,addedfaces);
623 TopExp_Explorer exGRE(shaGRE, TopAbs_FACE);
624 for (; exGRE.More(); exGRE.Next()){
625 const TopoDS_Shape& ff = exGRE.Current();
626 if (fcnewfcGRE.Contains(ff)) continue;
627 if (ff.IsSame(*pfGRE)) continue;
628 lOOfGRE.Append(ff); // DEB
629 ::FUN_addf(staGRE,ff,addedfaces);
633 TopTools_DataMapIteratorOfDataMapOfShapeShape itadd(addedfaces);
634 Standard_Boolean yauadd = itadd.More();
636 myBuildTool.MakeShell(newshe);
637 myBuildTool.Closed(newshe,Standard_True); // NYI : check exact du caractere closed du shell
639 for (; itadd.More(); itadd.Next() ) {
640 const TopoDS_Shape& ftoadd = itadd.Key();
641 myBuildTool.AddShellFace(newshe,ftoadd);
647 if ( !newshe.IsNull() ) {
648 myBuildTool.MakeSolid(newsol);
649 myBuildTool.AddSolidShell(newsol,newshe);
653 if ( !newsol.IsNull() ) {
654 lmergesha1.Append(newsol);
657 } // MergeKPartiskoletge
659 //=======================================================================
660 //function : MergeKPartisdisj
662 //=======================================================================
664 void TopOpeBRepBuild_Builder::MergeKPartisdisj()
667 Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
668 if (TKPB) KPreturn(myIsKPart);
671 if (myIsKPart != 2) return; // isdisj
673 TopTools_ListOfShape& lmergesha1 = ChangeMerged(myShape1,myState1);
674 /* TopTools_ListOfShape& lmergesha2 =*/ ChangeMerged(myShape2,myState2);
676 Standard_Boolean soldisj = Standard_False;
677 TopOpeBRepTool_ShapeExplorer exsol1(myShape1,TopAbs_SOLID);
678 Standard_Boolean hassol1 = exsol1.More();
679 TopOpeBRepTool_ShapeExplorer exsol2(myShape2,TopAbs_SOLID);
680 Standard_Boolean hassol2 = exsol2.More();
681 soldisj = (hassol1 && hassol2);
683 //modified by NIZHNY-MKK Fri May 19 16:18:12 2000.BEGIN
684 Standard_Boolean hasnotsol1=Standard_False;
685 Standard_Boolean hasnotsol2=Standard_False;
686 TopExp_Explorer anExp(myShape1, TopAbs_SHELL, TopAbs_SOLID);
687 for(Standard_Integer i=TopAbs_SHELL; i <= TopAbs_VERTEX && !hasnotsol1 && !hasnotsol2; i++) {
688 anExp.Init(myShape1, (TopAbs_ShapeEnum)i, TopAbs_SOLID);
690 hasnotsol1 = Standard_True;
691 anExp.Init(myShape2, (TopAbs_ShapeEnum)i, TopAbs_SOLID);
693 hasnotsol2 = Standard_True;
695 soldisj = !(hasnotsol1 || hasnotsol2);
696 //modified by NIZHNY-MKK Fri May 19 16:18:16 2000.END
698 TopoDS_Solid sol1; TopoDS_Shell outsha1;
699 TopoDS_Solid sol2; TopoDS_Shell outsha2;
702 //modified by NIZHNY-MKK Fri May 19 16:47:19 2000.BEGIN
703 TopTools_IndexedMapOfShape aMapOfSolid1, aMapOfSolid2;
704 TopExp::MapShapes(myShape1, TopAbs_SOLID, aMapOfSolid1);
705 TopExp::MapShapes(myShape2, TopAbs_SOLID, aMapOfSolid2);
707 if(aMapOfSolid1.Extent() > 1 || aMapOfSolid2.Extent() > 1) {
708 TopTools_IndexedMapOfShape aMapOfResult;
710 if(!disjPerformFuse(aMapOfSolid1, aMapOfSolid2, aMapOfResult))
714 if(!disjPerformCut(aMapOfSolid1, aMapOfSolid2, aMapOfResult))
718 if(!disjPerformCut(aMapOfSolid2, aMapOfSolid1, aMapOfResult))
722 if(!disjPerformCommon(aMapOfSolid1, aMapOfSolid2, aMapOfResult))
725 for(Standard_Integer ii=1; ii<=aMapOfResult.Extent(); ii++) {
726 lmergesha1.Append(aMapOfResult(ii));
729 } //end if(aMapOfSolid1.Extent() > 1 || aMapOfSolid2.Extent() > 1)
731 //modified by NIZHNY-MKK Fri May 19 16:47:23 2000.END
732 sol1 = TopoDS::Solid(exsol1.Current());
733 ChangeMerged(sol1,myState1);
734 outsha1 = BRepClass3d::OuterShell(sol1);
736 sol2 = TopoDS::Solid(exsol2.Current());
737 ChangeMerged(sol2,myState2);
738 outsha2 = BRepClass3d::OuterShell(sol2);
740 TopAbs_State stsol1 = KPclasSS(outsha1,sol2);
741 TopAbs_State stsol2 = KPclasSS(outsha2,sol1);
743 Standard_Integer ires,icla1,icla2;
744 KPisdisjanalyse(stsol1,stsol2,ires,icla1,icla2);
746 if (ires == RESUNDEF) {
750 else if (icla1 == SHEUNDEF || icla2 == SHEUNDEF) {
754 else if (ires == RESNULL) {
758 else if (ires == RESSHAPE12) {
759 lmergesha1.Append(myShape1);
760 lmergesha1.Append(myShape2);
764 else if (ires == RESSHAPE1) {
765 lmergesha1.Append(myShape1);
769 else if (ires == RESSHAPE2) {
770 lmergesha1.Append(myShape2);
774 else if (ires == RESNEWSHA1 ||
775 ires == RESNEWSHA2) {
776 //modified by NIZHNY-MKK Tue May 23 11:36:33 2000.BEGIN
777 TopoDS_Solid newsol = BuildNewSolid(sol1, sol2, stsol1, stsol2, ires, icla1, icla2, myState1, myState2);
778 //modified by NIZHNY-MKK Tue May 23 11:36:39 2000.END
779 lmergesha1.Append(newsol);
784 cout<<"TopOpeBRepBuild_MergeKPart soldisj : ires = "<<ires<<endl;
788 //modified by NIZHNY-MKK Tue May 23 11:37:15 2000
789 } //end else of if(aMapOfSolid1.Extent() > 1 || aMapOfSolid2.Extent() > 1)
795 lmergesha1.Append(myShape1);
798 lmergesha1.Append(myShape2);
804 lmergesha1.Append(myShape1);
805 lmergesha1.Append(myShape2);
813 } // MergeKPartisdisj
815 //=======================================================================
816 //function : MergeKPartisfafa
818 //=======================================================================
820 void TopOpeBRepBuild_Builder::MergeKPartisfafa()
823 Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
824 if (TKPB) KPreturn(myIsKPart);
827 if ( myIsKPart == 3 ) { // isfafa
830 ex.Init(myShape1,TopAbs_FACE); if (! ex.More() ) return;
831 TopoDS_Shape F1 = ex.Current();
832 ex.Init(myShape2,TopAbs_FACE); if (! ex.More() ) return;
833 TopoDS_Shape F2 = ex.Current();
835 TopTools_ListOfShape LF1,LF2;
836 GFindSamDom(F1,LF1,LF2);
838 TopAbs_ShapeEnum tf = TopAbs_FACE;
839 TopOpeBRepBuild_GTopo G;
840 if (Opec12()) G=TopOpeBRepBuild_GTool::GCutSame(tf,tf);
841 else if (Opec21()) G=TopOpeBRepBuild_GTool::GCutSame(tf,tf).CopyPermuted();
842 else if (Opecom()) G=TopOpeBRepBuild_GTool::GComSame(tf,tf);
843 else if (Opefus()) G=TopOpeBRepBuild_GTool::GFusSame(tf,tf);
846 GMapShapes(myShape1,myShape2);
847 GMergeFaces(LF1,LF2,G);
849 if (myShape1.ShapeType() == TopAbs_COMPOUND) {
850 TopTools_ListOfShape& L1 = ChangeMerged(myShape1,myState1);
851 L1 = ChangeMerged(F1,myState1);
854 if (myShape2.ShapeType() == TopAbs_COMPOUND) {
855 TopTools_ListOfShape& L2 = ChangeMerged(myShape2,myState2);
856 L2 = ChangeMerged(F2,myState2);
861 } // MergeKPartisfafa
863 //=======================================================================
864 //function : MergeKPartissoso
866 //=======================================================================
868 void TopOpeBRepBuild_Builder::MergeKPartissoso()
871 Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
872 if (TKPB) KPreturn(myIsKPart);
875 if ( myIsKPart == 4 ) { // issoso
880 if (!myShape1.IsNull()) {
881 ex.Init(myShape1,TopAbs_SOLID);
882 if (! ex.More() ) return;
887 if (!myShape2.IsNull()) {
888 ex.Init(myShape2,TopAbs_SOLID);
889 if (! ex.More() ) return;
893 if (SO1.IsNull()) return;
895 TopTools_ListOfShape LSO1,LSO2;
896 GFindSamDom(SO1,LSO1,LSO2);
898 TopAbs_ShapeEnum tf = TopAbs_FACE; // NYI TopAbs_SOLID
899 TopOpeBRepBuild_GTopo G;
900 if (Opec12()) G=TopOpeBRepBuild_GTool::GCutSame(tf,tf);
901 else if (Opec21()) G=TopOpeBRepBuild_GTool::GCutSame(tf,tf).CopyPermuted();
902 else if (Opecom()) G=TopOpeBRepBuild_GTool::GComSame(tf,tf);
903 else if (Opefus()) G=TopOpeBRepBuild_GTool::GFusSame(tf,tf);
906 GMapShapes(myShape1,myShape2);
907 GMergeSolids(LSO1,LSO2,G);
909 if (!myShape1.IsNull()) {
910 if (myShape1.ShapeType() == TopAbs_COMPOUND) {
911 TopTools_ListOfShape& L1 = ChangeMerged(myShape1,myState1);
912 L1 = ChangeMerged(SO1,myState1);
916 if (!myShape2.IsNull()) {
917 if (myShape2.ShapeType() == TopAbs_COMPOUND) {
918 TopTools_ListOfShape& L2 = ChangeMerged(myShape2,myState2);
919 L2 = ChangeMerged(SO2,myState2);
925 } // MergeKPartissoso
927 static Standard_Boolean sectionedgesON(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Shape& outerw1,
928 const TopTools_IndexedMapOfShape& mape2)
929 // prequesitory : all edges of <outerw1> are section edges
931 TopExp_Explorer ex1(outerw1, TopAbs_EDGE);
932 for (; ex1.More(); ex1.Next()){
933 const TopoDS_Shape& e1 = ex1.Current();
934 TopTools_ListIteratorOfListOfShape it2 = HDS->SameDomain(e1);
935 if (!it2.More()) return Standard_False; // xpu231098 : cto904C7 : e1 !hsd
936 for (; it2.More(); it2.Next()){
937 const TopoDS_Shape& e2 = it2.Value();
938 Standard_Boolean isbound = mape2.Contains(e2);
939 if (!isbound) return Standard_False;
942 return Standard_True;
945 static Standard_Boolean allIonsectionedges(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Shape& f1,
946 const TopTools_IndexedMapOfShape& mape1,
947 const TopTools_IndexedMapOfShape& mape2)
948 // prequesitory : all interferences attached to <f1> are SSI
950 TopOpeBRepDS_ListIteratorOfListOfInterference it1(HDS->DS().ShapeInterferences(f1));
951 for (; it1.More(); it1.Next()){
952 Handle(TopOpeBRepDS_ShapeShapeInterference) SSI1 (Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(it1.Value()));
953 Standard_Integer G1 = SSI1->Geometry();
954 Standard_Boolean isgbound = SSI1->GBound();
955 const TopoDS_Shape& e1 = HDS->Shape(G1);
956 Standard_Boolean isbound = isgbound? mape1.Contains(e1): mape2.Contains(e1);
957 if (!isbound) return Standard_False;
959 return Standard_True;
962 //=======================================================================
963 //function : KPiskoletge
964 //purpose : detection faces collees tangentes sur wire exterieur
965 //=======================================================================
967 Standard_Integer TopOpeBRepBuild_Builder::KPiskoletge()
970 Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
973 TopTools_ListOfShape lShsd1,lShsd2; // liste de solides HasSameDomain
974 TopTools_ListOfShape lfhsd1,lfhsd2; // liste de faces HasSameDomain
976 Standard_Boolean iskp1 = KPiskoletgesh(myShape1,lShsd1,lfhsd1);
977 if ( !iskp1 ) return 0;
978 TopTools_ListOfShape lplhsd1, lcyhsd1; ::FUN_sortplcy(lfhsd1,lplhsd1, lcyhsd1);
979 Standard_Integer nplhsd1 = lplhsd1.Extent(); Standard_Integer ncyhsd1 = lcyhsd1.Extent();
980 if ( nplhsd1 != 1 ) return 0;
981 if ( ncyhsd1 > 1 ) return 0;
983 Standard_Boolean iskp2 = KPiskoletgesh(myShape2,lShsd2,lfhsd2);
984 if ( !iskp2 ) return 0;
985 TopTools_ListOfShape lplhsd2, lcyhsd2; ::FUN_sortplcy(lfhsd2,lplhsd2, lcyhsd2);
986 Standard_Integer nplhsd2 = lplhsd2.Extent(); Standard_Integer ncyhsd2 = lcyhsd2.Extent();
987 if ( nplhsd2 != 1 ) return 0;
989 // Si l'un des objets est constitue de plusieurs solides on passe
990 // dans le cas general.
991 Standard_Integer nshsd1 = lShsd1.Extent();
992 Standard_Integer nshsd2 = lShsd2.Extent();
993 if ( nshsd1>1 || nshsd2>1 ) return 0;
996 // NYI : (nplhsd1 > 1) || (nplhsd2 > 1)
997 // ------------------------------------
999 const TopoDS_Face& f1 = TopoDS::Face(lplhsd1.First());
1001 // Standard_Boolean isb1 = myKPMAPf1f2.IsBound(f1); // DEB
1004 const TopoDS_Face& f2 = TopoDS::Face(lplhsd2.First());
1006 // Standard_Boolean isb2 = myKPMAPf1f2.IsBound(f2); // DEB
1010 Standard_Integer iF1,iF2;
1011 Standard_Boolean tSPS1 = GtraceSPS(f1,iF1);
1012 Standard_Boolean tSPS2 = GtraceSPS(f2,iF2);
1014 {GdumpSHA( f1, (char *) "KPiskoletge ");
1016 GdumpSHA( f2, (char *)"KPiskoletge ");
1020 TopoDS_Wire outerw1 = BRepTools::OuterWire(f1);
1021 TopoDS_Wire outerw2 = BRepTools::OuterWire(f2);
1023 TopTools_IndexedMapOfShape mape1; TopExp::MapShapes(outerw1, TopAbs_EDGE, mape1);
1024 TopTools_IndexedMapOfShape mape2; TopExp::MapShapes(outerw2, TopAbs_EDGE, mape2);
1026 Standard_Boolean se1ONouterw2 = ::sectionedgesON(myDataStructure,outerw1,mape2);
1027 if (!se1ONouterw2) return 0;
1028 Standard_Boolean se2ONouterw1 = ::sectionedgesON(myDataStructure,outerw2,mape1);
1029 if (!se2ONouterw1) return 0;
1031 // NYI : <fi> interfers with faces of <Sj> on edges different from outerw's edges
1032 // ------------------------------------------------------------------------------
1033 Standard_Boolean allI1onseouterw = ::allIonsectionedges(myDataStructure,f1,mape1,mape2);
1034 if (!allI1onseouterw) return 0;
1035 Standard_Boolean allI2onseouterw = ::allIonsectionedges(myDataStructure,f2,mape2,mape1);
1036 if (!allI2onseouterw) return 0;
1039 // NYI : (ncyhsd1 > 1) || (ncyhsd2 > 1)
1040 // ------------------------------------
1043 Standard_Boolean cycy = ( ncyhsd1 == 1 ) && ( ncyhsd2 == 1 );
1044 if (!cycy) return 0;
1046 Standard_Boolean isbound1 = FUN_tool_inS(outerw1,f1);
1047 if (!isbound1) return 0;
1048 Standard_Boolean isbound2 = FUN_tool_inS(outerw2,f2);
1049 if (!isbound2) return 0;
1055 //=======================================================================
1056 //function : KPisdisj
1057 //purpose : detection shapes disjoints
1058 //=======================================================================
1060 Standard_Integer TopOpeBRepBuild_Builder::KPisdisj()
1063 Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
1066 // myShape1 et myShape2 : aucune interference
1067 const TopOpeBRepDS_DataStructure& DS = myDataStructure->DS();
1068 // Standard_Integer nsh = DS.NbShapes();
1069 // if (nsh != 2) return 0;
1071 if (!DS.HasShape(myShape1)) return 0;
1072 if (!DS.HasShape(myShape2)) return 0;
1074 Standard_Integer isdisj1 = KPisdisjsh(myShape1);
1075 Standard_Integer isdisj2 = KPisdisjsh(myShape2);
1079 cout<<"isdisj : "<<isdisj1<<" "<<isdisj2<<endl;
1083 Standard_Integer isdisj = (isdisj1 && isdisj2) ? 1 : 0;
1087 //=======================================================================
1088 //function : KPisfafa
1089 //purpose : detection {face} / {face} toutes HasSameDomain
1090 //=======================================================================
1092 Standard_Integer TopOpeBRepBuild_Builder::KPisfafa()
1095 Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
1098 Standard_Boolean iskp1 = KPisfafash(myShape1);
1099 if ( !iskp1 ) return 0;
1101 Standard_Boolean iskp2 = KPisfafash(myShape2);
1102 if ( !iskp2 ) return 0;
1107 //=======================================================================
1108 //function : KPissoso
1109 //purpose : detection {solide} / {solide} tous HasSameDomain
1110 //=======================================================================
1112 Standard_Integer TopOpeBRepBuild_Builder::KPissoso()
1115 Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
1118 Standard_Boolean iskp1 = KPissososh(myShape1);
1119 if ( !iskp1 ) return 0;
1121 Standard_Boolean iskp2 = KPissososh(myShape2);
1122 if ( !iskp2 ) return 0;
1127 //=======================================================================
1128 //function : KPClearMaps
1130 //=======================================================================
1132 void TopOpeBRepBuild_Builder::KPClearMaps()
1134 myKPMAPf1f2.Clear();
1137 //=======================================================================
1139 //purpose : --> nb des subsshapes <T> de <S> qui sont HasGeometry()
1140 //=======================================================================
1142 Standard_Integer TopOpeBRepBuild_Builder::KPlhg(const TopoDS_Shape& S,const TopAbs_ShapeEnum T) const
1144 TopTools_ListOfShape L;
1145 Standard_Integer n = KPlhg(S,T,L);
1149 //=======================================================================
1151 //purpose : --> nb +liste des subsshapes <T> de <S> qui sont HasGeometry()
1152 //=======================================================================
1154 Standard_Integer TopOpeBRepBuild_Builder::KPlhg(const TopoDS_Shape& S,const TopAbs_ShapeEnum T,TopTools_ListOfShape& L) const
1156 Standard_Integer n = 0;
1160 for (ex.Init(S,T); ex.More(); ex.Next()) {
1161 // for (TopExp_Explorer ex(S,T); ex.More(); ex.Next()) {
1162 const TopoDS_Shape& s = ex.Current();
1163 Standard_Boolean hg = myDataStructure->HasGeometry(s);
1173 //=======================================================================
1176 // KPlhsd --> nb des subsshapes <T> de <S> qui sont HasSameDomain()
1177 //=======================================================================
1179 Standard_Integer TopOpeBRepBuild_Builder::KPlhsd(const TopoDS_Shape& S,const TopAbs_ShapeEnum T) const
1181 TopTools_ListOfShape L;
1182 Standard_Integer n = KPlhsd(S,T,L);
1186 //=======================================================================
1189 // KPlhsd --> nb + liste des subsshapes <T> de <S> qui sont HasSameDomain()
1190 //=======================================================================
1192 Standard_Integer TopOpeBRepBuild_Builder::KPlhsd(const TopoDS_Shape& S,const TopAbs_ShapeEnum T,TopTools_ListOfShape& L) const
1194 Standard_Integer n = 0;
1198 for (ex.Init(S,T); ex.More(); ex.Next()) {
1199 // for (TopExp_Explorer ex(S,T); ex.More(); ex.Next()) {
1200 const TopoDS_Shape& s = ex.Current();
1201 Standard_Boolean hsd = myDataStructure->HasSameDomain(s);
1211 //=======================================================================
1212 //function : KPclasSS
1214 // classifie le shape S1 par rapport a S2 en evitant de prendre
1215 // les shape exLS1 de S1 comme element de classification.
1216 // exS1 peut etre IsNull().
1217 // S1,S2 = SOLID | SHELL
1218 //=======================================================================
1220 TopAbs_State TopOpeBRepBuild_Builder::KPclasSS(const TopoDS_Shape& S1,const TopTools_ListOfShape& exLS1,const TopoDS_Shape& S2)
1222 TopAbs_State state = TopAbs_UNKNOWN;
1223 state = myShapeClassifier.StateShapeShape(S1,exLS1,S2);
1226 if (TopOpeBRepBuild_GettraceKPB()) {
1227 const gp_Pnt& P1 = myShapeClassifier.P3D();
1228 cout<<"point P1 "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z();
1229 cout<<" "; TopAbs::Print(state,cout);cout<<endl;
1236 //=======================================================================
1237 //function : KPclasSS
1239 // classifie le shape S1 par rapport a S2 en evitant de prendre
1240 // le shape exS1 de S1 comme element de classification.
1241 // exS1 peut etre IsNull().
1242 // S1,S2 = SOLID | SHELL
1243 //=======================================================================
1245 TopAbs_State TopOpeBRepBuild_Builder::KPclasSS(const TopoDS_Shape& S1,const TopoDS_Shape& exS1,const TopoDS_Shape& S2)
1247 TopAbs_State state = myShapeClassifier.StateShapeShape(S1,exS1,S2);
1250 if (TopOpeBRepBuild_GettraceKPB()) {
1251 const gp_Pnt& P1 = myShapeClassifier.P3D();
1252 cout<<"point P1 "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z();
1253 cout<<" "; TopAbs::Print(state,cout);cout<<endl;
1260 //=======================================================================
1261 //function : KPclasSS
1262 //purpose : classifie le shape S1 par rapport a S2 sans evitement de shape
1263 // S1,S2 = SOLID | SHELL
1264 //=======================================================================
1266 TopAbs_State TopOpeBRepBuild_Builder::KPclasSS(const TopoDS_Shape& S1,const TopoDS_Shape& S2)
1269 TopAbs_State state = KPclasSS(S1,Snull,S2);
1273 //=======================================================================
1274 //function : KPiskoletgesh
1277 // S est il un shape traite par le cas particulier de koletge?
1278 // si oui : retourne un solide et une liste de faces de collage
1279 //=======================================================================
1281 Standard_Boolean TopOpeBRepBuild_Builder::KPiskoletgesh(const TopoDS_Shape& Sarg,TopTools_ListOfShape& lShsd,TopTools_ListOfShape& lfhsd) const
1284 Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
1286 const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
1287 Standard_Boolean iskolesh = FUNKP_KPiskolesh((*this),BDS,Sarg,lShsd,lfhsd);
1288 if (!iskolesh) return Standard_False;
1291 Standard_Integer nfhsd =
1293 KPlhsd(Sarg,TopAbs_FACE,lfhsd);
1294 TopTools_ListIteratorOfListOfShape it(lfhsd);
1295 for (; it.More(); it.Next() ) {
1296 const TopoDS_Face& fac = TopoDS::Face(it.Value());
1297 Standard_Boolean isplan = FUN_tool_plane(fac);
1298 Standard_Boolean iscylinder = FUN_tool_cylinder(fac);
1299 if (iscylinder) continue;
1300 if (!isplan) return Standard_False;
1302 TopoDS_Wire outerw = BRepTools::OuterWire(fac);
1303 if (outerw.IsNull()) return Standard_False;
1305 TopExp_Explorer exe(outerw, TopAbs_EDGE);
1306 // Standard_Integer ne = 0;
1307 for (; exe.More(); exe.Next()){
1308 const TopoDS_Edge& ed = TopoDS::Edge(exe.Current());
1309 Standard_Boolean isse = BDS.IsSectionEdge(ed);
1310 const TopTools_ListOfShape& sp = (*this).Splits(ed,TopAbs_ON);
1311 if (sp.Extent() == 0) return Standard_False;
1312 if (!isse) return Standard_False;
1315 // if (ne > 1) return Standard_False;
1318 Standard_Integer isol = myDataStructure->Shape(Sarg); Standard_Integer ifac = myDataStructure->Shape(fac);
1319 if(TKPB){cout<<"isol "<<isol<<endl;}
1320 if(TKPB){cout<<"nfhsd "<<nfhsd<<endl;}
1321 if(TKPB){cout<<"ifac "<<ifac<<endl;}
1322 if(TKPB){cout<<"isplan "<<isplan<<endl;}
1323 if(TKPB){cout<<"iscylinder "<<iscylinder<<endl;}
1324 if(TKPB){cout<<endl;}
1328 return Standard_True;
1331 //=======================================================================
1332 //function : KPSameDomain
1333 //purpose : complete the lists L1,L2 with the shapes of the DS
1334 // having same domain :
1335 // L1 = shapes sharing the same domain of L2 shapes
1336 // L2 = shapes sharing the same domain of L1 shapes
1337 // (L1 contains a face)
1338 //=======================================================================
1340 void TopOpeBRepBuild_Builder::KPSameDomain(TopTools_ListOfShape& L1, TopTools_ListOfShape& L2) const
1343 Standard_Integer nl1 = L1.Extent(), nl2 = L2.Extent();
1345 while ( nl1 > 0 || nl2 > 0 ) {
1347 TopTools_ListIteratorOfListOfShape it1(L1);
1348 for (i=1 ; i<=nl1; i++) {
1349 const TopoDS_Shape& S1 = it1.Value();
1351 // Standard_Integer iS1 = myDataStructure->Shape(S1);
1353 TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S1));
1354 for (; itsd.More(); itsd.Next() ) {
1355 const TopoDS_Shape& S2 = itsd.Value();
1357 // Standard_Integer iS2 = myDataStructure->Shape(S2);
1359 Standard_Boolean found = KPContains(S2,L2);
1369 TopTools_ListIteratorOfListOfShape it2(L2);
1370 for (i=1 ; i<=nl2; i++) {
1371 const TopoDS_Shape& S2 = it2.Value();
1373 // Standard_Integer iS2 = myDataStructure->Shape(S2);
1375 TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S2));
1376 for (; itsd.More(); itsd.Next() ) {
1377 const TopoDS_Shape& S1 = itsd.Value();
1379 // Standard_Integer iS1 = myDataStructure->Shape(S1);
1381 Standard_Boolean found = KPContains(S1,L1);
1393 //=======================================================================
1394 //function : KPisdisjsh
1395 //purpose : S est il un shape traite par le cas particulier "disjoint"
1396 //=======================================================================
1398 Standard_Integer TopOpeBRepBuild_Builder::KPisdisjsh(const TopoDS_Shape& Sarg) const
1400 if ( Sarg.IsNull() ) return 0;
1403 Standard_Integer nhg;
1405 nhg = KPlhg(Sarg,TopAbs_SOLID);
1406 if ( nhg != 0 ) return 0;
1408 nhg = KPlhg(Sarg,TopAbs_FACE);
1409 if ( nhg != 0 ) return 0;
1411 nhg = KPlhg(Sarg,TopAbs_EDGE);
1412 if ( nhg != 0 ) return 0;
1414 // un seul niveau de HasSameDomain
1415 Standard_Integer n1,n2;
1416 TopTools_ListOfShape lshsd;
1418 n1 = KPlhsd(Sarg,TopAbs_SOLID,lshsd);
1420 TopTools_ListIteratorOfListOfShape it(lshsd);
1421 for(;it.More();it.Next()) {
1422 const TopoDS_Shape& s = it.Value();
1423 n2 = KPlhsd(s,TopAbs_FACE);
1424 if (n2 != 0 ) return 0;
1428 n1 = KPlhsd(Sarg,TopAbs_FACE,lshsd);
1430 TopTools_ListIteratorOfListOfShape it(lshsd);
1431 for(;it.More();it.Next()) {
1432 const TopoDS_Shape& s = it.Value();
1433 n2 = KPlhsd(s,TopAbs_EDGE);
1434 if (n2 != 0 ) return 0;
1441 //=======================================================================
1442 //function : KPissososh
1443 //purpose : detection S = {solid} tous HasSameDomain
1444 //=======================================================================
1446 Standard_Integer TopOpeBRepBuild_Builder::KPissososh(const TopoDS_Shape& Sarg) const
1448 // que des solides volants (nb total de solides = nb de solides volants)
1449 Standard_Integer nsol1 = 0;
1450 TopExp_Explorer ex1(Sarg,TopAbs_SOLID);
1451 for(; ex1.More(); ex1.Next()) nsol1++;
1453 Standard_Integer nsol2 = 0;
1454 TopExp_Explorer ex2(Sarg,TopAbs_SOLID,TopAbs_COMPSOLID);
1455 for(; ex2.More(); ex2.Next()) nsol2++;
1457 if (nsol1 && (nsol1 != nsol2)) return 0;
1459 // toutes les solides sont HasSameDomain()
1460 Standard_Integer nhsd = KPlhsd(Sarg,TopAbs_SOLID);
1461 if (nhsd != nsol1) return 0;
1463 Standard_Integer n; TopExp_Explorer ex;
1465 // pas de shell volant
1467 for (ex.Init(Sarg,TopAbs_SHELL,TopAbs_SOLID); ex.More(); ex.Next()) n++;
1470 // pas de face volant
1472 for (ex.Init(Sarg,TopAbs_FACE,TopAbs_SHELL); ex.More(); ex.Next()) n++;
1475 // pas d'edge volant
1477 for (ex.Init(Sarg,TopAbs_EDGE,TopAbs_WIRE); ex.More(); ex.Next()) n++;
1480 // pas de vertex volant
1482 for (ex.Init(Sarg,TopAbs_VERTEX,TopAbs_EDGE); ex.More(); ex.Next()) n++;
1488 //=======================================================================
1489 //function : KPisfafash
1490 //purpose : detection S = {face} toutes HasSameDomain
1491 //=======================================================================
1493 Standard_Integer TopOpeBRepBuild_Builder::KPisfafash(const TopoDS_Shape& Sarg) const
1495 // il n'y a que des faces volantes (nb total de faces = nb de faces volantes)
1496 Standard_Integer nfac1 = 0;
1497 TopExp_Explorer ex1(Sarg,TopAbs_FACE);
1498 for(; ex1.More(); ex1.Next()) nfac1++;
1500 Standard_Integer nfac2 = 0;
1501 TopExp_Explorer ex2(Sarg,TopAbs_FACE,TopAbs_SHELL);
1502 for(; ex2.More(); ex2.Next()) nfac2++;
1504 if (nfac1 && (nfac1 != nfac2)) return 0;
1506 // toutes les faces sont HasSameDomain()
1507 Standard_Integer nhsd = KPlhsd(Sarg,TopAbs_FACE);
1508 if (nhsd != nfac1) return 0;
1510 Standard_Integer n; TopExp_Explorer ex;
1512 // pas de wire volant
1514 for (ex.Init(Sarg,TopAbs_WIRE,TopAbs_FACE); ex.More(); ex.Next()) n++;
1517 // pas d'edge volant
1519 for (ex.Init(Sarg,TopAbs_EDGE,TopAbs_WIRE); ex.More(); ex.Next()) n++;
1522 // pas de vertex volant
1524 for (ex.Init(Sarg,TopAbs_VERTEX,TopAbs_EDGE); ex.More(); ex.Next()) n++;
1530 //=======================================================================
1531 //function : KPiskoletgeanalyse
1533 //=======================================================================
1535 void TopOpeBRepBuild_Builder::KPiskoletgeanalyse(const TopOpeBRepDS_Config config2,
1536 const TopAbs_State Stsol1, const TopAbs_State Stsol2,
1537 Standard_Integer& ires) const
1539 // -----------------------------------------------------------------------------
1540 // prequesitory : (nplhsd1 == 1) || (nplhsd2 == 1)
1541 // ------------- <plsdmi> has all interferences Ii = (T, G=edge of outerw1
1542 // ||edge of outerw2, S)
1543 // -----------------------------------------------------------------------------
1547 Standard_Boolean SameOriented = (config2 == TopOpeBRepDS_SAMEORIENTED);
1548 Standard_Boolean DiffOriented = (config2 == TopOpeBRepDS_DIFFORIENTED);
1550 // Standard_Boolean com = Opecom();
1551 // Standard_Boolean c12 = Opec12();
1552 // Standard_Boolean c21 = Opec21();
1553 // Standard_Boolean fus = Opefus();
1556 if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_IN)
1557 // if (com) ires = RESNULL;
1560 if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN) {
1561 // if (c12) ires = RESSHAPE1; // rank(sol1) == 1 && rank(sol2) == 2
1562 // if (c21) ires = RESSHAPE2; // rank(sol1) == 2 && rank(sol2) == 1
1566 if (Stsol2 == TopAbs_OUT && Stsol1 == TopAbs_IN) {
1567 // if (c12) ires = RESSHAPE2; // rank(sol2) == 1 && rank(sol1) == 2
1568 // if (c21) ires = RESSHAPE1; // rank(sol2) == 2 && rank(sol1) == 1
1572 if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT)
1573 // if (fus) ires = RESNEWSOL;
1578 // ==============================
1579 // PREQUESITORY :sol1 is IN sol2
1580 // ==============================
1582 if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_IN)
1583 // if (com) ires = RESSHAPE1;
1586 if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN) {
1587 // if (c12) ires = RESNULL; // rank(sol1) == 1 && rank(sol2) == 2
1588 // if (c21) ires = RESNEWSOL; // rank(sol1) == 2 && rank(sol2) == 1
1592 if (Stsol2 == TopAbs_OUT && Stsol1 == TopAbs_IN) {
1593 // if (c12) ires = RESNULL; // rank(sol2) == 1 && rank(sol1) == 2
1594 // if (c21) ires = RESNEWSOL; // rank(sol2) == 2 && rank(sol1) == 1
1598 if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT)
1599 // if (fus) ires = RESSHAPE2;
1604 Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
1605 if (TKPB) cout<<"ires = "<<ires<<endl;
1610 //=======================================================================
1611 //function : KPisdisjanalyse
1613 //=======================================================================
1615 void TopOpeBRepBuild_Builder::KPisdisjanalyse(const TopAbs_State Stsol1, const TopAbs_State Stsol2,
1616 Standard_Integer& ires,Standard_Integer& icla1,Standard_Integer& icla2) const
1618 ires = RESUNDEF; icla1 = icla2 = SHEUNDEF;
1621 if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1622 ires = RESSHAPE12; icla1 = icla2 = SHEAUCU; //--
1624 else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1625 ires = RESNEWSHA1; icla1 = icla2 = SHECLASAUTR; //--
1627 else if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_OUT) {
1628 ires = RESNEWSHA2; icla1 = icla2 = SHECLASAUTR; //--
1631 else if (Opec12()) {
1632 if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1633 ires = RESSHAPE1; icla1 = SHEGARDTOUS; icla2 = SHEAUCU; //--
1635 else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1636 ires = RESNEWSHA1; icla1 = SHECLASAUTR; icla2 = SHEGARDCOUR; //--
1638 else if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_OUT) {
1639 ires = RESNULL; icla1 = icla2 = SHEAUCU; //--
1642 else if (Opec21()) {
1643 if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1644 ires = RESSHAPE2; icla1 = SHEAUCU; icla2 = SHEGARDTOUS; //--
1646 else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1647 ires = RESNULL; icla1 = icla2 = SHEAUCU; //--
1649 else if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_OUT) {
1650 ires = RESNEWSHA2; icla1 = SHEGARDCOUR; icla2 = SHECLASAUTR; //--
1653 else if (Opecom()) {
1654 if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1655 ires = RESNULL; icla1 = icla2 = SHEAUCU; //--
1657 else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1658 ires = RESNEWSHA2; icla1 = SHECLASAUTR; icla2 = SHEGARDAUTR; //--
1660 else if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_OUT) {
1661 ires = RESNEWSHA1; icla1 = SHEGARDAUTR; icla2 = SHECLASAUTR; //--
1666 Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB();
1667 if (TKPB) cout<<"ires = "<<ires<<" icla1 "<<icla1<<" icla2 "<<icla2<<endl;
1671 //=======================================================================
1672 //function : KPls (class method)
1674 // KPls --> nb des subsshapes <T> de <S>
1675 //=======================================================================
1677 Standard_Integer TopOpeBRepBuild_Builder::KPls(const TopoDS_Shape& S,const TopAbs_ShapeEnum T)
1679 TopTools_ListOfShape L;
1680 Standard_Integer n = KPls(S,T,L);
1684 //=======================================================================
1685 //function : KPls (class method)
1687 // KPls --> nb + liste des subsshapes <T> de <S>
1688 //=======================================================================
1690 Standard_Integer TopOpeBRepBuild_Builder::KPls(const TopoDS_Shape& S, const TopAbs_ShapeEnum T, TopTools_ListOfShape& L)
1692 Standard_Integer n = 0;
1696 for (ex.Init(S,T); ex.More(); ex.Next()) {
1697 // for (TopExp_Explorer ex(S,T); ex.More(); ex.Next()) {
1698 const TopoDS_Shape& s = ex.Current();
1706 //=======================================================================
1707 //function : KPclassF (class method)
1709 // KPclassF : classification F1 par rapport a F2
1710 // F1 et F2 ne partagent aucune arete
1711 // F1 et F2 sont SameDomain
1712 //=======================================================================
1714 TopAbs_State TopOpeBRepBuild_Builder::KPclassF(const TopoDS_Shape& F1,const TopoDS_Shape& F2)
1716 if (F1.IsNull()) return TopAbs_UNKNOWN;
1717 if (F2.IsNull()) return TopAbs_UNKNOWN;
1719 TopoDS_Face F1F = TopoDS::Face(F1); F1F.Orientation(TopAbs_FORWARD);
1720 TopoDS_Face F2F = TopoDS::Face(F2); F2F.Orientation(TopAbs_FORWARD);
1722 TopTools_ListOfShape le1;
1723 Standard_Integer ne1 = KPls(F1F,TopAbs_EDGE,le1);
1724 if ( ne1 == 0 ) return TopAbs_UNKNOWN;
1725 const TopoDS_Edge& e1 = TopoDS::Edge(le1.First());
1727 Standard_Integer isamdom = 1;
1728 TopAbs_State St1 = TopAbs_UNKNOWN;
1729 St1 = myShapeClassifier.StateShapeShape(e1,F2F,isamdom);
1733 //=======================================================================
1734 //function : KPclassFF (class method)
1736 // classifie F1/F2 --> etats des faces l'une par rapport a l'autre
1737 //=======================================================================
1739 void TopOpeBRepBuild_Builder::KPclassFF(const TopoDS_Shape& F1,const TopoDS_Shape& F2,TopAbs_State& St1,TopAbs_State& St2)
1741 St1 = KPclassF(F1,F2);
1742 St2 = KPclassF(F2,F1);
1745 if (TopOpeBRepBuild_GettraceKPB()) {
1746 cout<<"Stf1 ";TopAbs::Print(St1,cout); cout<<" ";
1747 cout<<"Stf2 ";TopAbs::Print(St2,cout); cout<<endl;
1752 //=======================================================================
1753 //function : KPiskoleFF
1755 // classifie F1/F2 --> etats des faces l'une par rapport a l'autre
1756 // --> True si la configutration topologique correspond au cas "iskole".
1757 //=======================================================================
1759 Standard_Boolean TopOpeBRepBuild_Builder::KPiskoleFF(const TopoDS_Shape& F1,const TopoDS_Shape& F2,TopAbs_State& St1,TopAbs_State& St2)
1762 Standard_Integer iF1;
1763 Standard_Boolean tSPS1 = GtraceSPS(F1,iF1);
1764 Standard_Integer iF2;
1765 Standard_Boolean tSPS2 = GtraceSPS(F2,iF2);
1766 if(tSPS1) { GdumpSHA(F1, (char *) "KPiskoleFF ");cout<<endl; }
1767 if(tSPS2) { GdumpSHA(F2, (char *) "KPiskoleFF ");cout<<endl; }
1770 KPclassFF(F1,F2,St1,St2);
1771 Standard_Boolean st1ok = (St1 == TopAbs_OUT || St1 == TopAbs_IN);
1772 Standard_Boolean st2ok = (St2 == TopAbs_OUT || St2 == TopAbs_IN);
1774 if ( !st1ok ) return Standard_False;
1775 if ( !st2ok ) return Standard_False;
1776 Standard_Boolean stok = (St1 != St2);
1777 if ( !stok ) return Standard_False;
1778 return Standard_True;
1781 //=======================================================================
1782 //function : KPContains (class method)
1783 //purpose : returns True if S is in the list L.
1784 //=======================================================================
1786 Standard_Boolean TopOpeBRepBuild_Builder::KPContains(const TopoDS_Shape& S,const TopTools_ListOfShape& L)
1788 for (TopTools_ListIteratorOfListOfShape it(L); it.More(); it.Next() ) {
1789 const TopoDS_Shape& SL = it.Value();
1790 Standard_Boolean issame = SL.IsSame(S);
1791 if ( issame ) return Standard_True;
1793 return Standard_False;
1796 //=======================================================================
1797 //function : KPreturn (class method)
1799 //=======================================================================
1801 Standard_Integer TopOpeBRepBuild_Builder::KPreturn(const Standard_Integer b)
1804 if (TopOpeBRepBuild_GettraceKPB()) {
1805 cout<<"--- IsKPart "<<b;
1806 if ( b == 1 ) cout<<" iskole";
1807 if ( b == 2 ) cout<<" isdisj";
1808 if ( b == 3 ) cout<<" isfafa";
1815 //modified by NIZHNY-MKK Tue May 23 09:48:47 2000.BEGIN
1816 //======================================================================================================
1817 // static function : LocalKPisdisjanalyse
1819 //======================================================================================================
1820 static void LocalKPisdisjanalyse(const TopAbs_State Stsol1, const TopAbs_State Stsol2,
1821 const TopOpeBRepBuild_KPart_Operation& theOperation,
1822 Standard_Integer& ires, Standard_Integer& icla1, Standard_Integer& icla2) {
1823 ires = RESUNDEF; icla1 = icla2 = SHEUNDEF;
1825 switch(theOperation) {
1826 case TopOpeBRepBuild_KPart_Operation_Fuse: {
1827 if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1828 ires = RESSHAPE12; icla1 = icla2 = SHEAUCU; //--
1830 else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1831 ires = RESNEWSHA1; icla1 = icla2 = SHECLASAUTR; //--
1833 else if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_OUT) {
1834 ires = RESNEWSHA2; icla1 = icla2 = SHECLASAUTR; //--
1838 case TopOpeBRepBuild_KPart_Operation_Cut12: {
1839 if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1840 ires = RESSHAPE1; icla1 = SHEGARDTOUS; icla2 = SHEAUCU; //--
1842 else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1843 ires = RESNEWSHA1; icla1 = SHECLASAUTR; icla2 = SHEGARDCOUR; //--
1845 else if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_OUT) {
1846 ires = RESNULL; icla1 = icla2 = SHEAUCU; //--
1850 case TopOpeBRepBuild_KPart_Operation_Cut21: {
1851 if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1852 ires = RESSHAPE2; icla1 = SHEAUCU; icla2 = SHEGARDTOUS; //--
1854 else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1855 ires = RESNULL; icla1 = icla2 = SHEAUCU; //--
1857 else if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_OUT) {
1858 ires = RESNEWSHA2; icla1 = SHEGARDCOUR; icla2 = SHECLASAUTR; //--
1862 case TopOpeBRepBuild_KPart_Operation_Common: {
1863 if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) {
1864 ires = RESNULL; icla1 = icla2 = SHEAUCU; //--
1866 else if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN ) {
1867 ires = RESNEWSHA2; icla1 = SHECLASAUTR; icla2 = SHEGARDAUTR; //--
1869 else if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_OUT) {
1870 ires = RESNEWSHA1; icla1 = SHEGARDAUTR; icla2 = SHECLASAUTR; //--
1875 cout << "Warning: given operation is unknown" << endl;
1882 //======================================================================================================
1883 // static function : BuildNewSolid
1884 // purpose: Build new solid based on sol1 and sol2 according to the states
1885 //======================================================================================================
1886 static TopoDS_Solid BuildNewSolid(const TopoDS_Solid& sol1,
1887 const TopoDS_Solid& sol2,
1888 const TopAbs_State stsol1,
1889 const TopAbs_State stsol2,
1890 const Standard_Integer ires,
1891 const Standard_Integer icla1,
1892 const Standard_Integer icla2,
1893 const TopAbs_State theState1,
1894 const TopAbs_State theState2) {
1896 TopOpeBRepTool_ShapeClassifier aShapeClassifier;
1898 TopTools_MapOfShape isdisjmap;
1899 TopOpeBRepDS_BuildTool aBuildTool;
1901 TopAbs_State solstate,shastatetoadd;
1902 TopoDS_Shell outsha;
1903 Standard_Integer icla;
1904 TopoDS_Solid othersol;
1905 TopoDS_Shell outsha1 = BRepClass3d::OuterShell(sol1);
1906 TopoDS_Shell outsha2 = BRepClass3d::OuterShell(sol2);
1909 TopoDS_Solid newsol;
1910 aBuildTool.MakeSolid(newsol);
1911 if (ires == RESNEWSHA1) {
1912 if ( ! isdisjmap.Contains(outsha1) ) {
1913 isdisjmap.Add(outsha1);
1914 aBuildTool.AddSolidShell(newsol,outsha1);
1917 else if (ires == RESNEWSHA2) {
1918 if ( ! isdisjmap.Contains(outsha2) ) {
1919 isdisjmap.Add(outsha2);
1920 aBuildTool.AddSolidShell(newsol,outsha2);
1926 shastatetoadd = theState1;
1932 TopOpeBRepTool_ShapeExplorer exsha;
1933 for (exsha.Init(sol,TopAbs_SHELL); exsha.More(); exsha.Next()) {
1934 const TopoDS_Shell& shacur = TopoDS::Shell(exsha.Current());
1935 Standard_Boolean isoutsha = shacur.IsEqual(outsha);
1937 Standard_Boolean garde = Standard_True;
1938 if (icla==SHEAUCU) garde = Standard_False;
1939 else if (icla==SHEGARDAUTR || icla==SHECLASAUTR) garde = ! isoutsha;
1940 if (!garde) continue;
1942 Standard_Boolean add = Standard_False;
1943 if ( icla==SHEGARDCOUR ) add = Standard_True;
1944 else if ( icla==SHEGARDAUTR ) add = Standard_True;
1945 else if ( icla==SHEGARDTOUS ) add = Standard_True;
1946 else if ( icla==SHECLASAUTR ) {
1947 TopAbs_State state = aShapeClassifier.StateShapeShape(shacur,Snull,othersol);
1948 add = (state == shastatetoadd);
1951 TopoDS_Shell shaori = shacur;
1952 Standard_Boolean r = (solstate == TopAbs_IN);
1953 if (r) shaori.Complement();
1954 if ( ! isdisjmap.Contains(shaori) ) {
1955 isdisjmap.Add(shaori);
1956 aBuildTool.AddSolidShell(newsol,shaori);
1964 shastatetoadd = theState2;
1970 TopOpeBRepTool_ShapeExplorer exsha;
1971 for (exsha.Init(sol,TopAbs_SHELL); exsha.More(); exsha.Next()) {
1972 const TopoDS_Shell& shacur = TopoDS::Shell(exsha.Current());
1973 Standard_Boolean isoutsha = shacur.IsEqual(outsha);
1975 Standard_Boolean garde = Standard_True;
1976 if (icla==SHEAUCU) garde = Standard_False;
1977 else if (icla==SHEGARDAUTR || icla==SHECLASAUTR) garde = ! isoutsha;
1978 if (!garde) continue;
1980 Standard_Boolean add = Standard_False;
1981 if ( icla==SHEGARDCOUR ) add = Standard_True;
1982 else if ( icla==SHEGARDAUTR ) add = Standard_True;
1983 else if ( icla==SHEGARDTOUS ) add = Standard_True;
1984 else if ( icla==SHECLASAUTR ) {
1985 TopAbs_State state = aShapeClassifier.StateShapeShape(shacur,Snull,othersol);
1986 add = (state == shastatetoadd);
1989 TopoDS_Shell shaori = shacur;
1990 Standard_Boolean r = (solstate == TopAbs_IN);
1991 if (r) shaori.Complement();
1992 aBuildTool.AddSolidShell(newsol,shaori);
2000 //======================================================================================================
2001 // static function : disjPerformFuse
2002 // purpose: is needed in case of KPart==2
2003 // attention: theMapOfResult is cleared before computations
2004 //======================================================================================================
2005 static Standard_Boolean disjPerformFuse(const TopTools_IndexedMapOfShape& theMapOfSolid1,
2006 const TopTools_IndexedMapOfShape& theMapOfSolid2,
2007 TopTools_IndexedMapOfShape& theMapOfResult) {
2009 theMapOfResult.Clear();
2011 TopTools_IndexedMapOfShape aMapOfSolid;
2012 aMapOfSolid = theMapOfSolid1;
2013 Standard_Integer i=1;
2014 for(i=1; i<=theMapOfSolid2.Extent(); i++) {
2015 aMapOfSolid.Add(theMapOfSolid2(i));
2018 TopoDS_Solid sol1; TopoDS_Shell outsha1;
2019 TopoDS_Solid sol2; TopoDS_Shell outsha2;
2020 TopOpeBRepTool_ShapeClassifier aShapeClassifier;
2022 TopTools_MapOfShape aMapOfUsedSolids;
2023 TopoDS_Solid acurrentsolid;
2024 Standard_Integer aMaxNumberOfIterations = aMapOfSolid.Extent()*aMapOfSolid.Extent();
2026 for(i=1; i <=aMapOfSolid.Extent(); i++) {
2027 const TopoDS_Shape& localshape1 = aMapOfSolid(i);
2028 if(localshape1.ShapeType()!=TopAbs_SOLID)
2029 return Standard_False;
2031 sol1 = TopoDS::Solid(localshape1);
2032 acurrentsolid = sol1;
2033 if(aMapOfUsedSolids.Contains(localshape1))
2036 Standard_Integer j=1, acheckiterator=0;
2037 while(j<=aMapOfSolid.Extent() && (acheckiterator <= aMaxNumberOfIterations)) {
2043 const TopoDS_Shape& localshape2 = aMapOfSolid(j);
2044 if(localshape2.ShapeType()!=TopAbs_SOLID)
2045 return Standard_False;
2047 j++; // increase iterator
2049 if(aMapOfUsedSolids.Contains(localshape2)) {
2052 sol2 = TopoDS::Solid(localshape2);
2053 outsha2 = BRepClass3d::OuterShell(sol2);
2055 outsha1 = BRepClass3d::OuterShell(acurrentsolid);
2056 TopAbs_State stsol1 = aShapeClassifier.StateShapeShape(outsha1,Snull,sol2);
2057 TopAbs_State stsol2 = aShapeClassifier.StateShapeShape(outsha2,Snull,acurrentsolid);
2058 Standard_Integer ires=RESUNDEF, icla1=SHEUNDEF, icla2=SHEUNDEF;
2059 LocalKPisdisjanalyse(stsol1, stsol2, TopOpeBRepBuild_KPart_Operation_Fuse, ires, icla1, icla2);
2060 if (ires == RESUNDEF || icla1 == SHEUNDEF || icla2 == SHEUNDEF || ires == RESNULL) {
2061 cout << "Warning: disjPerformFuse: can not determine solid's states" << endl;
2064 if(ires == RESSHAPE12)
2067 if(ires==RESNEWSHA1 || ires==RESNEWSHA2) {
2068 TopoDS_Solid newsol = BuildNewSolid(acurrentsolid, sol2, stsol1, stsol2, ires, icla1, icla2, TopAbs_OUT, TopAbs_OUT);
2069 j=1; // iterate on all solids again except already used (very dengerous method)
2070 acurrentsolid = newsol;
2071 aMapOfUsedSolids.Add(localshape2);
2072 if(acurrentsolid.IsNull())
2073 return Standard_False;
2076 if(acheckiterator > aMaxNumberOfIterations) {
2077 cout << "disjPerformFuse: programming error" << endl;
2078 return Standard_False;
2080 theMapOfResult.Add(acurrentsolid);
2083 return Standard_True;
2086 //======================================================================================================
2087 // static function : disjPerformCommon
2088 // purpose: is needed in case of KPart==2
2089 // attention: theMapOfResult is cleared before computations
2090 //======================================================================================================
2091 static Standard_Boolean disjPerformCommon(const TopTools_IndexedMapOfShape& theMapOfSolid1,
2092 const TopTools_IndexedMapOfShape& theMapOfSolid2,
2093 TopTools_IndexedMapOfShape& theMapOfResult) {
2095 TopoDS_Solid sol1; TopoDS_Shell outsha1;
2096 TopoDS_Solid sol2; TopoDS_Shell outsha2;
2097 TopOpeBRepTool_ShapeClassifier aShapeClassifier;
2099 TopTools_IndexedMapOfShape aMapOfSeparatedSolid1, aMapOfSeparatedSolid2, aMapOfCommonOfCouple;
2100 theMapOfResult.Clear();
2102 disjPerformFuse(theMapOfSolid1, theMapOfSolid1, aMapOfSeparatedSolid1);
2103 disjPerformFuse(theMapOfSolid2, theMapOfSolid2, aMapOfSeparatedSolid2);
2104 // Now common parts of all couples of solids are different
2105 for(Standard_Integer i=1; i <=aMapOfSeparatedSolid1.Extent(); i++) {
2106 const TopoDS_Shape& localshape1 = aMapOfSeparatedSolid1(i);
2107 if(localshape1.ShapeType()!=TopAbs_SOLID)
2108 return Standard_False;
2109 sol1 = TopoDS::Solid(localshape1);
2110 outsha1 = BRepClass3d::OuterShell(sol1);
2112 for(Standard_Integer j=1; j<=aMapOfSeparatedSolid2.Extent(); j++) {
2113 const TopoDS_Shape& localshape2 = aMapOfSeparatedSolid2(j);
2114 if(localshape2.ShapeType()!=TopAbs_SOLID)
2115 return Standard_False;
2117 sol2 = TopoDS::Solid(localshape2);
2118 outsha2 = BRepClass3d::OuterShell(sol2);
2119 TopAbs_State stsol1 = aShapeClassifier.StateShapeShape(outsha1,Snull,sol2);
2120 TopAbs_State stsol2 = aShapeClassifier.StateShapeShape(outsha2,Snull,sol1);
2121 Standard_Integer ires=RESUNDEF, icla1=SHEUNDEF, icla2=SHEUNDEF;
2123 LocalKPisdisjanalyse(stsol1, stsol2, TopOpeBRepBuild_KPart_Operation_Common, ires, icla1, icla2);
2124 if (ires == RESUNDEF || icla1 == SHEUNDEF || icla2 == SHEUNDEF) {
2125 cout << "Warning: disjPerformCommon: can not determine solid's states" << endl;
2133 aMapOfCommonOfCouple.Add(sol1);
2134 aMapOfCommonOfCouple.Add(sol2);
2138 aMapOfCommonOfCouple.Add(sol1);
2142 aMapOfCommonOfCouple.Add(sol2);
2147 TopoDS_Solid newsol = BuildNewSolid(sol1, sol2, stsol1, stsol2, ires, icla1, icla2, TopAbs_IN, TopAbs_IN);
2148 aMapOfCommonOfCouple.Add(newsol);
2156 disjPerformFuse(aMapOfCommonOfCouple, aMapOfCommonOfCouple, theMapOfResult);
2157 return Standard_True;
2160 //======================================================================================================
2161 // static function : disjPerformCut
2162 // purpose: is needed in case of KPart==2
2163 // attention: theMapOfResult is cleared before computations
2164 //======================================================================================================
2165 static Standard_Boolean disjPerformCut(const TopTools_IndexedMapOfShape& theMapOfSolid1,
2166 const TopTools_IndexedMapOfShape& theMapOfSolid2,
2167 TopTools_IndexedMapOfShape& theMapOfResult) {
2168 TopoDS_Solid sol1; TopoDS_Shell outsha1;
2169 TopoDS_Solid sol2; TopoDS_Shell outsha2;
2170 TopOpeBRepTool_ShapeClassifier aShapeClassifier;
2172 TopoDS_Solid acurrentsolid;
2173 TopTools_IndexedMapOfShape aMapOfSeparatedSolid1, aMapOfSeparatedSolid2;
2175 theMapOfResult.Clear();
2177 disjPerformFuse(theMapOfSolid1, theMapOfSolid1, aMapOfSeparatedSolid1);
2178 disjPerformFuse(theMapOfSolid2, theMapOfSolid2, aMapOfSeparatedSolid2);
2180 for(Standard_Integer i=1; i<= aMapOfSeparatedSolid1.Extent(); i++) {
2181 const TopoDS_Shape& localshape1 = aMapOfSeparatedSolid1(i);
2182 if(localshape1.ShapeType()!=TopAbs_SOLID)
2183 return Standard_False;
2184 sol1 = TopoDS::Solid(localshape1);
2185 acurrentsolid = sol1;
2187 Standard_Boolean NullResult = Standard_False;
2189 for(Standard_Integer j=1; j<=aMapOfSeparatedSolid2.Extent() && !NullResult; j++) {
2190 const TopoDS_Shape& localshape2 = aMapOfSeparatedSolid2(j);
2191 if(localshape2.ShapeType()!=TopAbs_SOLID)
2192 return Standard_False;
2193 sol2 = TopoDS::Solid(localshape2);
2194 outsha2 = BRepClass3d::OuterShell(sol2);
2195 outsha1 = BRepClass3d::OuterShell(acurrentsolid);
2196 TopAbs_State stsol1 = aShapeClassifier.StateShapeShape(outsha1,Snull,sol2);
2197 TopAbs_State stsol2 = aShapeClassifier.StateShapeShape(outsha2,Snull,acurrentsolid);
2198 Standard_Integer ires=RESUNDEF, icla1=SHEUNDEF, icla2=SHEUNDEF;
2200 LocalKPisdisjanalyse(stsol1, stsol2, TopOpeBRepBuild_KPart_Operation_Cut12, ires, icla1, icla2);
2201 if (ires == RESUNDEF || icla1 == SHEUNDEF || icla2 == SHEUNDEF) {
2202 cout << "Warning: disjPerformCut: can not determine solid's states" << endl;
2207 NullResult=Standard_True;
2211 NullResult=Standard_True;
2215 NullResult=Standard_False;
2219 NullResult=Standard_True;
2224 TopoDS_Solid newsol = BuildNewSolid(acurrentsolid, sol2, stsol1, stsol2, ires, icla1, icla2, TopAbs_OUT, TopAbs_IN);
2225 acurrentsolid = newsol;
2232 if(acurrentsolid.IsNull())
2233 return Standard_False;
2234 theMapOfResult.Add(acurrentsolid);
2237 return Standard_True;
2239 //modified by NIZHNY-MKK Tue May 23 09:49:03 2000.END