2ebbd107af60dcc9ffa0cf6dfcf80bbcf22ae691
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_GridFF.cxx
1 // file:        TopOpeBRepBuild_GridFF.cxx
2 // Created:     Thu Mar  7 10:49:33 1996
3 // Author:      Jean Yves LEBEY
4 //              <jyl@meteox>
5
6 #include <TopOpeBRepBuild_Builder.ixx>
7
8 #include <TopOpeBRepDS.hxx>
9 #include <TopOpeBRepDS_InterferenceTool.hxx>
10 #include <TopOpeBRepTool_TOOL.hxx>
11 #include <TopOpeBRepTool_ShapeExplorer.hxx>
12 #include <TopOpeBRepTool_ShapeTool.hxx>
13 #include <TopoDS.hxx>
14 #include <BRep_Tool.hxx>
15 #include <TopExp.hxx>
16
17 #include <TopOpeBRepTool_2d.hxx>
18 #include <TopOpeBRepTool_EXPORT.hxx>
19 #include <TopOpeBRepDS_EXPORT.hxx>
20 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
21 #include <TopOpeBRepBuild_define.hxx>
22
23 #ifdef DRAW
24 #include <TopOpeBRepDS_DSX.hxx>
25 Standard_IMPORT void FUN_draw(const TopoDS_Shape& s);
26 Standard_IMPORT void FUN_draw2de (const TopoDS_Shape& ed,const TopoDS_Shape& fa);
27 #endif
28
29 #ifdef DEB
30 //Standard_IMPORT extern void* GFABUMAKEFACEPWES_DEB;
31 Standard_IMPORT void* GFABUMAKEFACEPWES_DEB;
32 #define DEBSHASET(sarg,meth,shaset,str) TCollection_AsciiString sarg((meth));(sarg)=(sarg)+(shaset).DEBNumber()+(str);
33 Standard_EXPORT Standard_Integer GLOBAL_iexE = 0;
34 Standard_EXPORT void debfillw(const Standard_Integer /*i*/) {}
35 Standard_EXPORT void debfille(const Standard_Integer /*i*/) {}
36 Standard_EXPORT void debffwesON(const Standard_Integer i) {cout<<"++ debffwesON "<<i<<endl;}
37 Standard_EXPORT void debffwesmf(const Standard_Integer i) {cout<<"++ debffwesmf "<<i<<endl;}
38 Standard_EXPORT void debfillf(const Standard_Integer i) {cout<<"++ debfillf "<<i<<endl;}
39 Standard_EXPORT void debsplite(const Standard_Integer i) {cout<<"++ debsplite "<<i<<endl;}
40 Standard_EXPORT void debmergef(const Standard_Integer i) {cout<<"++ debmergef "<<i<<endl;}
41 Standard_IMPORT void debfctwesmess(const Standard_Integer i,
42                                    const TCollection_AsciiString& s = "");
43 Standard_IMPORT void debaddpwes(const Standard_Integer iFOR,
44                                 const TopAbs_State TB1,
45                                 const Standard_Integer iEG,
46                                 const TopAbs_Orientation neworiE,
47                                 const TopOpeBRepBuild_PBuilder& PB,
48                                 const TopOpeBRepBuild_PWireEdgeSet& PWES,
49                                 const TCollection_AsciiString& str1,
50                                 const TCollection_AsciiString& str2);
51 #endif
52
53 Standard_EXPORT Standard_Boolean GLOBAL_faces2d = Standard_False;
54 Standard_EXPORT Standard_Boolean GLOBAL_classifysplitedge = Standard_False;  
55
56 #define M_IN(st )      (st == TopAbs_IN)
57 #define M_OUT(st)      (st == TopAbs_OUT)
58 #define M_FORWARD(st ) (st == TopAbs_FORWARD)
59 #define M_REVERSED(st) (st == TopAbs_REVERSED)
60 #define M_INTERNAL(st) (st == TopAbs_INTERNAL)
61 #define M_EXTERNAL(st) (st == TopAbs_EXTERNAL)
62
63 Standard_IMPORT Standard_Boolean FUN_HDS_FACESINTERFER(const TopoDS_Shape& F1, 
64                                                        const TopoDS_Shape& F2,
65                                                        const Handle(TopOpeBRepDS_HDataStructure)& HDS);
66
67 static 
68   TopAbs_State ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E,
69                                              const TopoDS_Shape& Ref);
70 static
71   Standard_Boolean FUN_computeLIFfaces2d(const TopOpeBRepBuild_Builder& BU, 
72                                          const TopoDS_Face& F, 
73                                          const TopoDS_Edge& E, 
74                                          TopOpeBRepDS_PDataStructure& pDS2d);
75 static 
76   Standard_Boolean FUN_computeLIFfaces2d(const TopOpeBRepBuild_Builder& BU, 
77                                          const TopoDS_Face& F, 
78                                          TopOpeBRepDS_PDataStructure& pDS2d);
79
80 //-------------------------------------------------------------
81 // Unused :
82 /*#ifdef DEB
83 //=======================================================================
84 //function :FUN_BUI_FACESINTERFER
85 //purpose  : 
86 //=======================================================================
87 static Standard_Boolean FUN_BUI_FACESINTERFER(const TopoDS_Shape& F1,
88                                               const TopoDS_Shape& F2,
89                                               const TopOpeBRepBuild_Builder& B)
90 {
91   Standard_Boolean yainterf = Standard_False;
92   Handle(TopOpeBRepDS_HDataStructure) HDS = B.DataStructure();
93   
94
95
96   Standard_Boolean ya1 = FUN_HDS_FACESINTERFER(F1,F2,HDS);
97   Standard_Boolean ya2 = FUN_HDS_FACESINTERFER(F2,F1,HDS);
98   yainterf = (ya1 && ya2);
99   return yainterf;
100 }
101 #endif*/
102
103 //=======================================================================
104 //function :TopOpeBRepBuild_FUN_aresamegeom
105 //purpose  : 
106 //=======================================================================
107 Standard_EXPORT Standard_Boolean TopOpeBRepBuild_FUN_aresamegeom (const TopoDS_Shape& S1,
108                                                                   const TopoDS_Shape& S2)
109 {
110   TopoDS_Shape SF1 = S1; 
111   SF1.Orientation(TopAbs_FORWARD);
112   TopoDS_Shape SF2 = S2; 
113   SF2.Orientation(TopAbs_FORWARD);
114   Standard_Boolean same = TopOpeBRepTool_ShapeTool::ShapesSameOriented(SF1,SF2);
115   return same;
116 }
117
118 //=======================================================================
119 //function :FUN_computeLIFfaces2d
120 //purpose  : 
121 //=======================================================================
122 Standard_Boolean FUN_computeLIFfaces2d(const TopOpeBRepBuild_Builder& BU, 
123                                        const TopoDS_Face& F, 
124                                        const TopoDS_Edge& E, 
125                                        TopOpeBRepDS_PDataStructure& pDS2d)
126 // purpose : compute new face/face interferences F FTRA,
127 //  {I = (T(F),ES,FTRA)} / Fsdm F and ES interfers with E which has splits ON
128 //  E is edge of F
129
130 #ifdef DEB
131   Standard_Integer iF;Standard_Boolean tF=BU.GtraceSPS(F,iF);
132 #endif
133   
134   const TopOpeBRepDS_DataStructure& BDS = BU.DataStructure()->DS(); 
135   const TopOpeBRepDS_ListOfInterference& LI = BDS.ShapeInterferences(E);
136   Standard_Integer IE = BDS.Shape(E);
137   Standard_Integer IF = BDS.Shape(F);
138   Standard_Integer rkF = BDS.AncestorRank(F);
139   Standard_Boolean hasspE = BU.IsSplit(E,TopAbs_ON);
140   if (hasspE) hasspE = (BU.Splits(E,TopAbs_ON).Extent() > 0);
141   TopTools_MapOfShape Ffound;
142   
143   TopTools_ListOfShape Fsdm; TopTools_ListIteratorOfListOfShape itf(BDS.ShapeSameDomain(F));
144   for (; itf.More(); itf.Next()){
145     const TopoDS_Shape& f = itf.Value();
146     Standard_Integer rkf = BDS.AncestorRank(f);
147     if (rkf == rkF) continue;
148     Fsdm.Append(f);
149   }
150
151   for (TopOpeBRepDS_ListIteratorOfListOfInterference itI(LI); itI.More(); itI.Next()){
152     const Handle(TopOpeBRepDS_Interference)& I = itI.Value();
153 //    const TopOpeBRepDS_Transition& T = I->Transition();
154     TopAbs_ShapeEnum SB,SA;Standard_Integer IB,IA;TopOpeBRepDS_Kind GT,ST;Standard_Integer G,S;
155     FDS_Idata(I,SB,IB,SA,IA,GT,G,ST,S);
156     if (ST != TopOpeBRepDS_EDGE) return Standard_False;
157
158     TopoDS_Face FTRA; Standard_Integer ITRA = IB;
159     if      (SB == TopAbs_FACE) FTRA = TopoDS::Face(BDS.Shape(IB));
160     else if (SB == TopAbs_EDGE) {
161       Standard_Boolean ok = FUN_tool_findAncestor(Fsdm,TopoDS::Edge(BDS.Shape(S)),FTRA);
162       ITRA = BDS.Shape(FTRA);
163       if (!ok) return Standard_False;      
164     }
165     Standard_Boolean found = Ffound.Contains(FTRA);
166
167     // prequesitory : F and FTRA are SDSO
168     // -------------
169
170     // attached to E : I = (T(FTRA),G,ES),
171     // ES : support edge
172     // GP : geometric point  
173     // recall : rankE  = rankF
174     //          rankTRA = rankS != rankE
175     Standard_Real parE = FDS_Parameter(I);
176     const TopoDS_Edge& ES = TopoDS::Edge(BDS.Shape(S));
177     Standard_Boolean hasspES = BU.IsSplit(ES,TopAbs_ON);
178     if (hasspES) hasspE = (BU.Splits(ES,TopAbs_ON).Extent() > 0); 
179
180     Standard_Boolean sdm = FUN_ds_sdm(BDS,E,ES);
181     Standard_Boolean mkTonEsdm = sdm && hasspE && !found;
182     Standard_Boolean hasfeiF_E_FTRA = FUN_ds_hasFEI(pDS2d,F,IE,ITRA);  //xpu120698
183     mkTonEsdm = mkTonEsdm && !hasfeiF_E_FTRA; //xpu120698
184     if (mkTonEsdm) {
185       Ffound.Add(FTRA);
186       TopoDS_Edge dummy; TopOpeBRepDS_Transition newT;  
187       Standard_Boolean ok = FUN_ds_mkTonFsdm(BU.DataStructure(),IF,ITRA,S,IE,parE,dummy,Standard_True,newT);
188
189       if (ok) {
190         newT.Index(ITRA); TopOpeBRepDS_Config C = TopOpeBRepDS_SAMEORIENTED;
191         Handle(TopOpeBRepDS_Interference) newI = TopOpeBRepDS_InterferenceTool::MakeFaceEdgeInterference(newT,ITRA,IE,Standard_True,C);
192 #ifdef DEB
193         if (tF) {cout<<"f"<<IF<<" + ";newI->Dump(cout);cout<<endl;}
194 #endif
195         pDS2d->AddShapeInterference(F,newI);
196       }
197     }
198     Standard_Boolean mkTonESsdm = sdm && hasspES;
199     Standard_Boolean hasfeiFRA_E_F = FUN_ds_hasFEI(pDS2d,FTRA,IE,IF);  //xpu120698
200     mkTonESsdm = mkTonESsdm && !hasfeiFRA_E_F;  //xpu120698
201     if (mkTonESsdm) { // ff1, IE=3 has interferences, S=8 has none
202       TopoDS_Edge dummy; TopOpeBRepDS_Transition newT; 
203
204       Standard_Real parES; Standard_Boolean ok = FUN_tool_parE(E,parE,ES,parES);
205       if (!ok) continue; 
206       ok = FUN_ds_mkTonFsdm(BU.DataStructure(),ITRA,IF,IE,S,parES,dummy,Standard_True,newT);
207       if (ok) {
208         newT.Index(IF); TopOpeBRepDS_Config C = TopOpeBRepDS_SAMEORIENTED;
209         Handle(TopOpeBRepDS_Interference) newI = TopOpeBRepDS_InterferenceTool::MakeFaceEdgeInterference(newT,IF,IE,Standard_False,C);
210 #ifdef DEB
211         if (tF) {cout<<"f"<<ITRA<<" + ";newI->Dump(cout);cout<<endl;}
212 #endif
213         pDS2d->AddShapeInterference(FTRA,newI);
214       }
215
216       ok = FUN_ds_mkTonFsdm(BU.DataStructure(),ITRA,IF,IE,IE,parE,dummy,Standard_True,newT);      
217       if (ok) {
218         newT.Index(IF); TopOpeBRepDS_Config C = TopOpeBRepDS_SAMEORIENTED;
219         Handle(TopOpeBRepDS_Interference) newI = TopOpeBRepDS_InterferenceTool::MakeFaceEdgeInterference(newT,IF,S,Standard_True,C);
220 #ifdef DEB
221         if (tF) {cout<<endl<<"f"<<ITRA<<" + ";newI->Dump(cout);cout<<endl;}
222 #endif
223         pDS2d->AddShapeInterference(FTRA,newI);
224       }
225       
226     }
227
228     Standard_Boolean mkTonES = hasspES;
229     Standard_Boolean hasfeiF_S_FTRA = FUN_ds_hasFEI(pDS2d,F,S,ITRA);  //xpu120698
230     mkTonES = mkTonES && !hasfeiF_S_FTRA;
231     if (mkTonES) {
232       Standard_Real parES; Standard_Boolean ok = FUN_tool_parE(E,parE,ES,parES);
233       if (!ok) continue;
234       
235       TopoDS_Edge dummy; TopOpeBRepDS_Transition newT; 
236       ok = FUN_ds_mkTonFsdm(BU.DataStructure(),IF,ITRA,S,S,parES,dummy,Standard_True,newT);
237
238       if (ok) {
239         newT.Index(ITRA); TopOpeBRepDS_Config C = TopOpeBRepDS_SAMEORIENTED;
240         Handle(TopOpeBRepDS_Interference) newI = TopOpeBRepDS_InterferenceTool::MakeFaceEdgeInterference(newT,ITRA,S,Standard_False,C);
241 #ifdef DEB
242         if (tF) {cout<<"f"<<iF<<" + ";newI->Dump(cout);cout<<endl;}
243 #endif
244         pDS2d->AddShapeInterference(F,newI);
245       }
246     }
247   } // itI(LI)
248
249   return Standard_True;
250 }
251 //=======================================================================
252 //function :FUN_computeLIFfaces2d
253 //purpose  : 
254 //=======================================================================
255 Standard_Boolean FUN_computeLIFfaces2d(const TopOpeBRepBuild_Builder& BU, 
256                                        const TopoDS_Face& F,
257                                        TopOpeBRepDS_PDataStructure& pDS2d)
258 {
259   TopExp_Explorer ex(F, TopAbs_EDGE);   
260   for (; ex.More(); ex.Next()){
261     const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
262     Standard_Boolean ok = FUN_computeLIFfaces2d(BU,F,E,pDS2d);
263     if (!ok) return Standard_False;
264   }
265   return Standard_True;
266 }
267 //=======================================================================
268 //variable : Standard_EXPORT TopOpeBRepDS_PDataStructure GLOBAL_DS2d
269 //purpose  : 
270 //=======================================================================
271 Standard_EXPORT TopOpeBRepDS_PDataStructure GLOBAL_DS2d = NULL;
272
273 //=======================================================================
274 //function : GMergeFaces
275 //purpose  : 
276 //=======================================================================
277   void TopOpeBRepBuild_Builder::GMergeFaces(const TopTools_ListOfShape& LF1,
278                                             const TopTools_ListOfShape& LF2,
279                                             const TopOpeBRepBuild_GTopo& G1)
280 {
281   if ( LF1.IsEmpty() ) return;
282   if (GLOBAL_DS2d == NULL) GLOBAL_DS2d = (TopOpeBRepDS_PDataStructure)new TopOpeBRepDS_DataStructure();
283   GLOBAL_DS2d->Init();
284
285   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
286
287   const TopoDS_Shape& F1 = LF1.First();
288 #ifdef DEB
289   Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(F1,iF);
290   if(tSPS){
291     cout<<endl<<"--- GMergeFaces "<<endl;
292     GdumpSAMDOM(LF1, (char *) "1 : ");
293     GdumpSAMDOM(LF2, (char *) "2 : ");
294     debmergef(iF);
295   }
296 #endif
297
298   // xpu070598 : filling up DS2
299 //  for (TopTools_ListIteratorOfListOfShape itF1(LF1); itF1.More(); itF1.Next()) GLOBAL_DS2d->AddShape(itF1.Value(),1); 
300    TopTools_ListIteratorOfListOfShape itF1(LF1) ;
301   for ( ; itF1.More(); itF1.Next()) GLOBAL_DS2d->AddShape(itF1.Value(),1);  
302 //  for (TopTools_ListIteratorOfListOfShape itF2(LF2); itF2.More(); itF2.Next()) GLOBAL_DS2d->AddShape(itF2.Value(),2);
303   TopTools_ListIteratorOfListOfShape itF2(LF2) ;
304   for ( ; itF2.More(); itF2.Next()) GLOBAL_DS2d->AddShape(itF2.Value(),2);
305
306 //  for (itF1.Initialize(LF1); itF1.More(); itF1.Next()){
307   itF1.Initialize(LF1) ;
308   for ( ; itF1.More(); itF1.Next()){
309     const TopoDS_Face& FF1 = TopoDS::Face(itF1.Value());
310     FUN_computeLIFfaces2d((*this),TopoDS::Face(FF1),GLOBAL_DS2d);
311   }
312 //  for (itF2.Initialize(LF2); itF2.More(); itF2.Next()){
313   itF2.Initialize(LF2) ;
314   for ( ; itF2.More(); itF2.Next()){
315     const TopoDS_Face& FF2 = TopoDS::Face(itF2.Value());
316     FUN_computeLIFfaces2d((*this),TopoDS::Face(FF2),GLOBAL_DS2d);
317   }
318   // xpu070598
319
320   {
321     for (Standard_Integer ii=1; ii<=GLOBAL_DS2d->NbShapes(); ii++) {
322       TopOpeBRepDS_ListOfInterference& LI = GLOBAL_DS2d->ChangeShapeInterferences(ii);
323       FUN_reducedoublons(LI,(*GLOBAL_DS2d),ii);
324     }
325   }
326
327   myFaceReference = TopoDS::Face(F1);
328   TopOpeBRepBuild_WireEdgeSet WES(F1,this);
329
330   GLOBAL_faces2d = Standard_True;
331   Standard_Integer K1=1; GFillFacesWESK(LF1,LF2,G1,WES,K1);
332   Standard_Integer K3=3; GFillFacesWESK(LF1,LF2,G1,WES,K3); // xpu060598
333   GLOBAL_faces2d = Standard_False;
334
335   // Create a face builder FABU
336   TopoDS_Shape F1F = LF1.First(); F1F.Orientation(TopAbs_FORWARD);
337   Standard_Boolean ForceClass = Standard_True;
338   TopOpeBRepBuild_FaceBuilder FABU;
339   FABU.InitFaceBuilder(WES,F1F,ForceClass);
340   
341   // Build new faces LFM
342   TopTools_ListOfShape LFM;
343
344 #ifdef DEB
345   GFABUMAKEFACEPWES_DEB = (void*)&WES;
346 #endif
347
348   TopTools_DataMapOfShapeInteger MWisOld;
349   GFABUMakeFaces(F1F,FABU,LFM,MWisOld);
350   
351   // xpu281098 : regularisation after GFABUMakeFaces
352   TopTools_ListOfShape newLFM; RegularizeFaces(F1F,LFM,newLFM);
353   LFM.Clear(); LFM.Assign(newLFM);
354
355   // connect new faces as faces built TB1 on LF1 faces
356   TopTools_ListIteratorOfListOfShape it1;
357   for (it1.Initialize(LF1); it1.More(); it1.Next()) {
358     const TopoDS_Shape& F1x = it1.Value();
359     Standard_Boolean tomerge = !IsMerged(F1x,TB1);
360     if (tomerge) {
361       ChangeMerged(F1x, TB1) = LFM;
362     }
363   }
364   
365   // connect new faces as faces built TB2 on LF2 faces
366   TopTools_ListIteratorOfListOfShape it2;
367   for (it2.Initialize(LF2); it2.More(); it2.Next()) {
368     const TopoDS_Shape& F2 = it2.Value();
369     Standard_Boolean tomerge = !IsMerged(F2,TB2);
370     if (tomerge) ChangeMerged(F2,TB2) = LFM;
371   }
372   
373 } // GMergeFaces
374
375 //=======================================================================
376 //function : GFillFacesWES
377 //purpose  : 
378 //=======================================================================
379   void TopOpeBRepBuild_Builder::GFillFacesWES(const TopTools_ListOfShape& ,
380                                               const TopTools_ListOfShape& ,
381                                               const TopOpeBRepBuild_GTopo& ,
382                                               TopOpeBRepBuild_WireEdgeSet& )
383 {
384 } // GFillFacesWES
385
386 static Standard_Boolean FUN_validF1edge(const TopoDS_Shape& F)
387 {
388   Standard_Integer nE = 0; 
389   TopTools_IndexedMapOfShape mEt;
390   TopExp_Explorer exE(F, TopAbs_EDGE);
391 //  for ( exE ; exE.More(); exE.Next()) {
392   for (  ; exE.More(); exE.Next()) {
393     const TopoDS_Shape& e = exE.Current();
394     if (mEt.Contains(e)) continue;
395     mEt.Add(e);
396     nE++; 
397     if (nE > 2) break;
398   }
399   if (nE > 1) return Standard_True;
400   if (nE == 1) {
401     exE.Init(F, TopAbs_EDGE);
402     const TopoDS_Edge& e = TopoDS::Edge(exE.Current());
403     TopoDS_Vertex dummy; Standard_Boolean closed = TopOpeBRepTool_TOOL::ClosedE(e,dummy);
404     return closed;
405   }
406   return Standard_False;
407 }
408
409 //=======================================================================
410 //function : GFillFacesWESMakeFaces
411 //purpose  : 
412 //=======================================================================
413   void TopOpeBRepBuild_Builder::GFillFacesWESMakeFaces(const TopTools_ListOfShape& LLF1,
414                                                        const TopTools_ListOfShape& LF2,
415                                                        const TopTools_ListOfShape& ,//LSO,
416                                                        const TopOpeBRepBuild_GTopo& GM)
417 {
418   TopAbs_State TB1,TB2; GM.StatesON(TB1,TB2);
419   if (LLF1.IsEmpty()) return;
420   
421   // xpu270898 : cto905E2 split(fref6,f33,f16) must be built on fref6
422   TopTools_ListOfShape LF1;
423   TopTools_ListIteratorOfListOfShape itf(LLF1);
424   const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
425   Standard_Integer iref = 0; 
426   for (; itf.More(); itf.Next()){
427     const TopoDS_Shape& fcur = itf.Value();
428     Standard_Integer icur = BDS.Shape(fcur);
429     iref = BDS.SameDomainRef(fcur);
430     if (icur == iref) LF1.Prepend(fcur);
431     else              LF1.Append(fcur);
432   }
433   // xpu270898 : cto905I1 split(f6,f30,fref14) must be built on fref6, f6 is in LFDO1
434 //  Standard_Boolean FFinDO1 = (iFF == iref);
435 //  const TopoDS_Shape& FF = BDS.Shape(iref);
436   const TopoDS_Shape& FF = LF1.First().Oriented(TopAbs_FORWARD);
437   Standard_Integer iFF = BDS.Shape(FF);
438
439   TopOpeBRepBuild_WireEdgeSet WES(FF,this);
440
441 #ifdef DEB
442   Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(FF,iF);
443   if(tSPS) GdumpSHASTA(iF,TB1,WES,"\n--- GFillFacesWESMakeFaces");
444   if(tSPS) debfillf(iF);
445   if(tSPS) debffwesmf(iF);
446 #endif
447
448   Standard_Integer n1 = 0;
449   GLOBAL_faces2d = Standard_True;
450   Standard_Integer K1=1; GFillFacesWESK(LF1,LF2,GM,WES,K1);
451   GLOBAL_faces2d = Standard_False;
452   n1 = WES.StartElements().Extent();
453   
454   Standard_Integer K2=2; GFillFacesWESK(LF1,LF2,GM,WES,K2);
455   n1 = WES.StartElements().Extent();
456   
457   Standard_Integer K3=3; GFillFacesWESK(LF1,LF2,GM,WES,K3);
458   n1 = WES.StartElements().Extent();
459
460   Standard_Integer n2 = WES.StartElements().Extent();
461   myEdgeAvoid.Clear(); // Start edges dues a GFillCurveTopologyWES
462   GCopyList(WES.StartElements(),(n1+1),n2,myEdgeAvoid);
463   TopTools_ListOfShape LOF; // LOF : toutes les faces construites sur WES
464   GWESMakeFaces(FF,WES,LOF);
465
466   // xpu290498
467   //cto 001 F2 : spIN(f18)
468   TopTools_ListIteratorOfListOfShape itF(LOF);
469   while (itF.More()){
470     const TopoDS_Shape& F = itF.Value();
471     Standard_Boolean valid = ::FUN_validF1edge(F);
472     if (!valid) LOF.Remove(itF);
473     else itF.Next();
474   }
475   // xpu290498
476
477   TopTools_ListOfShape LOFS; // LOFS : LOF faces situees TB1/LSO2
478   GKeepShapes(FF,myEmptyShapeList,TB1,LOF,LOFS);
479
480   // les faces construites (LOFS) prennent l'orientation originale de FF  
481   TopAbs_Orientation odsFF = myDataStructure->Shape(iFF).Orientation();
482   for(TopTools_ListIteratorOfListOfShape itt(LOFS);itt.More();itt.Next()) itt.Value().Orientation(odsFF);
483
484   TopTools_ListIteratorOfListOfShape it1;
485   for (it1.Initialize(LF1); it1.More(); it1.Next()) {
486     const TopoDS_Shape& S = it1.Value(); 
487 #ifdef DEB
488     Standard_Integer iS; GtraceSPS(S,iS);
489 #endif
490     MarkSplit(S,TB1);
491     TopTools_ListOfShape& LS1 = ChangeSplit(S,TB1);
492     GCopyList(LOFS,LS1);
493   }
494
495   TopTools_ListIteratorOfListOfShape it2;
496   for (it2.Initialize(LF2); it2.More(); it2.Next()) {
497     const TopoDS_Shape& S = it2.Value(); 
498 #ifdef DEB
499     Standard_Integer iS; GtraceSPS(S,iS);
500 #endif
501     MarkSplit(S,TB2);
502     TopTools_ListOfShape& LS2 = ChangeSplit(S,TB2);
503     GCopyList(LOFS,LS2);
504   }
505 } // GFillFacesWESMakeFaces
506
507 //=======================================================================
508 //function : GFillFaceWES
509 //purpose  : 
510 //=======================================================================
511   void TopOpeBRepBuild_Builder::GFillFaceWES(const TopoDS_Shape& FOR1,
512                                              const TopTools_ListOfShape& LFclass,
513                                              const TopOpeBRepBuild_GTopo& G1,
514                                              TopOpeBRepBuild_WireEdgeSet& WES)
515 {
516   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
517   Standard_Boolean RevOri1 = G1.IsToReverse1();
518   
519 #ifdef DEB
520   Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(FOR1,iF);
521   if(tSPS) GdumpSHASTA(iF,TB1,WES,"--- GFillFaceWES","START");
522   if(tSPS) debfillf(iF);
523 #endif
524   
525   // xpu200598 bcl1;bcl2; tsp(f9)
526   Standard_Boolean opeCut = Opec12() || Opec21(); //xpu200598
527   Standard_Boolean ComOfCut = opeCut && (TB1 == TB2) && (TB1 == TopAbs_IN); //xpu200598
528   Standard_Boolean hsdm = myDataStructure->HasSameDomain(FOR1);//xpu200598
529   if (hsdm && ComOfCut) return; //xpu200598
530   
531   // work on a FORWARD face FF
532   TopoDS_Shape FF = FOR1; FF.Orientation(TopAbs_FORWARD);
533   myFaceToFill = TopoDS::Face(FF);
534   
535   TopOpeBRepTool_ShapeExplorer exWire(FF,TopAbs_WIRE);
536   for (; exWire.More(); exWire.Next()) {
537     TopoDS_Shape W = exWire.Current();
538     Standard_Boolean hasshape = myDataStructure->HasShape(W);
539     
540     if ( ! hasshape ) {
541       // wire W is not in DS : classify it with LFclass faces
542       TopAbs_State pos;
543       Standard_Boolean keep = GKeepShape1(W,LFclass,TB1,pos);
544       if (keep) {
545         TopAbs_Orientation oriW = W.Orientation();
546         TopAbs_Orientation neworiW = Orient(oriW,RevOri1);
547         W.Orientation(neworiW);
548         WES.AddShape(W);
549       }
550       else if (myProcessON && pos == TopAbs_ON)
551         myONElemMap.Add(W);
552     }
553     else { // wire W has edges(s) with geometry : split W edges
554       GFillWireWES(W,LFclass,G1,WES);
555     }
556   }
557   
558 #ifdef DEB
559   if(tSPS) GdumpSHASTA(iF,TB1,WES,"--- GFillFaceWES","END");
560 #endif
561
562   return;
563 } // GFillFaceWES
564
565 //=======================================================================
566 //function : GFillWireWES
567 //purpose  : 
568 //=======================================================================
569   void TopOpeBRepBuild_Builder::GFillWireWES(const TopoDS_Shape& W,
570                                              const TopTools_ListOfShape& LSclass,
571                                              const TopOpeBRepBuild_GTopo& G1,
572                                              TopOpeBRepBuild_WireEdgeSet& WES)
573 {
574   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
575
576 #ifdef DEB
577   Standard_Integer iW; Standard_Boolean tSPS = GtraceSPS(W,iW);
578   if(tSPS){
579     cout<<endl;DEBSHASET(s,"--- GFillWireWES ",WES," ");
580     GdumpSHA(W,(Standard_Address)s.ToCString()); cout<<endl;
581     Standard_Integer nbe = 0;
582     TopOpeBRepTool_ShapeExplorer exE(W,TopAbs_EDGE);for (;exE.More(); exE.Next()) nbe++;
583     cout<<"--- GFillWireWES on W "<<iW<<" with "<<nbe<<" edges "<<endl;
584     debfillw(iW);
585   }
586   GLOBAL_iexE = 0;
587 #endif
588   
589   TopOpeBRepTool_ShapeExplorer exEdge(W,TopAbs_EDGE);
590   for (; exEdge.More(); exEdge.Next()) {
591     const TopoDS_Shape& EOR = exEdge.Current();
592     
593 #ifdef DEB
594     GLOBAL_iexE++;
595     if (tSPS) {
596 //      const TopoDS_Edge& ed = TopoDS::Edge(EOR);
597 //      Standard_Boolean isdegen = BRep_Tool::Degenerated(ed);
598 //      TopLoc_Location L;
599 //      Handle(Geom_Surface) S = BRep_Tool::Surface(myFaceToFill,L);
600 //      Standard_Boolean isclosed = BRep_Tool::IsClosed(ed,S,L);
601 //      TopAbs_Orientation oried = ed.Orientation();
602 //      Standard_Boolean trc = Standard_False;
603 #ifdef DRAW
604 //      if (trc) {FUN_draw(ed); FUN_draw2de(ed,myFaceReference);}
605 #endif
606     }
607 #endif
608     
609     GFillEdgeWES(EOR,LSclass,G1,WES);
610   }
611 } // GFillWireWES
612
613
614 //=======================================================================
615 //function : GFillEdgeWES
616 //purpose  : 
617 //=======================================================================
618   void TopOpeBRepBuild_Builder::GFillEdgeWES(const TopoDS_Shape& EOR,
619                                              const TopTools_ListOfShape& LSclass,
620                                              const TopOpeBRepBuild_GTopo& G1,
621                                              TopOpeBRepBuild_WireEdgeSet& WES)
622 {
623   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
624
625 #ifdef DEB
626   Standard_Integer iE; Standard_Boolean tSPS = GtraceSPS(EOR,iE);
627   if(tSPS)cout<<endl;
628 #endif
629
630 #ifdef DEB
631   Standard_Boolean tosplit =
632 #endif
633                 GToSplit(EOR,TB1);
634 #ifdef DEB
635   Standard_Boolean tomerge =
636 #endif
637                 GToMerge(EOR);
638
639 #ifdef DEB
640   if(tSPS) GdumpSHASTA(iE,TB1,WES,"--- GFillEdgeWES ");
641   if(tSPS) cout<<" tosplit "<<tosplit<<" tomerge "<<tomerge<<endl;
642   if(tSPS) debfille(iE);
643 #endif
644   
645   TopOpeBRepBuild_GTopo GME = G1;
646   GMergeEdgeWES(EOR,GME,WES);
647   
648   TopOpeBRepBuild_GTopo GSE = G1;
649   GSE.ChangeConfig(TopOpeBRepDS_UNSHGEOMETRY,TopOpeBRepDS_UNSHGEOMETRY);
650   GSplitEdgeWES(EOR,LSclass,GSE,WES);
651
652 } // GFillEdgeWES
653
654 static void FUN_samgeomori(const TopOpeBRepDS_DataStructure& BDS, const Standard_Integer iref, const Standard_Integer ifil,
655                            Standard_Boolean& samgeomori)
656 {
657   TopOpeBRepDS_Config cfill = BDS.SameDomainOri(ifil);
658   TopAbs_Orientation oref=BDS.Shape(iref).Orientation(), ofil=BDS.Shape(ifil).Orientation();
659   samgeomori = (cfill == TopOpeBRepDS_SAMEORIENTED);
660   if (oref == TopAbs::Complement(ofil)) samgeomori = !samgeomori;
661 }
662
663 #define UNKNOWN   (0)
664 #define ONSAMESHA (1)
665 #define CLOSESAME (11)
666 #define ONOPPOSHA (2)
667 #define CLOSEOPPO (22)
668 #define FORREVOPPO (222)
669
670 //=======================================================================
671 //function : GSplitEdgeWES
672 //purpose  : 
673 //=======================================================================
674   void TopOpeBRepBuild_Builder::GSplitEdgeWES(const TopoDS_Shape& EOR,
675                                               const TopTools_ListOfShape& LSclass,
676                                               const TopOpeBRepBuild_GTopo& G1,
677                                               TopOpeBRepBuild_WireEdgeSet& WES)
678 {
679   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
680   Standard_Boolean RevOri1 = G1.IsToReverse1();
681   TopAbs_Orientation oriE = EOR.Orientation();
682   TopAbs_Orientation neworiE = Orient(oriE,RevOri1);
683   const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
684   
685   TopAbs_Orientation oEinF; 
686   Standard_Integer Oinref = 0;
687   Standard_Boolean hsdm = myDataStructure->HasSameDomain(myFaceToFill);
688   Standard_Boolean hsdmE = myDataStructure->HasSameDomain(EOR);
689   Standard_Integer ifil = myDataStructure->Shape(myFaceToFill);
690   Standard_Integer iref = myDataStructure->Shape(myFaceReference);
691   if (hsdm) {
692     Oinref = FUN_ds_oriEinF(BDS,TopoDS::Edge(EOR),myFaceReference,oEinF); //xpu060598
693
694     // xpu150998 : cto900P6 : e35ou added to fref34,f53, oEinF=REVERSED, oEinfill=FORWARD
695     TopAbs_Orientation oEinfill; 
696     Standard_Integer Oinfill = FUN_ds_oriEinF(BDS,TopoDS::Edge(EOR),myFaceToFill,oEinfill);
697     if (Oinref == Oinfill) {
698
699       Standard_Boolean reverse = Standard_False; 
700       if (iref != ifil) {
701         // xpu230299 : FRA60275 (e6,fref4,ffill7) + PRO16297
702         TopAbs_Orientation oref = myFaceReference.Orientation();
703         Standard_Boolean samegeomori; FUN_samgeomori(BDS,iref,ifil,samegeomori);
704         reverse = (!samegeomori);
705         if (oref == TopAbs_REVERSED) reverse = !reverse;
706       }
707 //      TopAbs_Orientation oref=myFaceReference.Orientation(), ofill=myFaceToFill.Orientation();
708 //      Standard_Boolean reverse = (oref != ofill);
709
710       TopAbs_Orientation oEinfillTOref = reverse ? TopAbs::Complement(oEinfill) : oEinfill;
711       Standard_Boolean same = (oEinF == oEinfillTOref);
712       if (!same && (oEinF!=TopAbs_INTERNAL) && (oEinF!=TopAbs_EXTERNAL)) oEinF = oEinfillTOref;
713     }
714   }
715   else      Oinref = FUN_ds_oriEinF(BDS,TopoDS::Edge(EOR),myFaceToFill,oEinF); //xpu060598
716   Standard_Boolean newO = (Oinref == ONSAMESHA) || (Oinref == ONOPPOSHA); //xpu060598
717
718   Standard_Boolean isfafa = (myIsKPart == 3);
719   if (isfafa) newO = Standard_False;// xpu110598
720
721   // if (fus) : faces are SDSO : we keep original edge's orientation
722   // if (com) : faces are SDSO : we keep original edge's orientation
723   // if (cut && TBToFill==OUT)  : myFaceToFill is the reference face,
724   //                              we keep original edge's orientation
725
726 #ifdef DEB 
727   Standard_Integer iEOR; Standard_Boolean tSPS = GtraceSPS(EOR,iEOR);
728   Standard_Integer iWESF; /*Standard_Boolean tSPSW = */GtraceSPS(WES.Face(),iWESF);
729   if(tSPS) GdumpSHASTA(iEOR,TB1,WES,"\n--- GSplitEdgeWES","START");
730   if(tSPS) cout<<" RevOri1 : "<<RevOri1<<endl;
731   if(tSPS) debsplite(iEOR);
732 #endif  
733     
734   Standard_Boolean tosplit = GToSplit(EOR,TB1);
735   if (tosplit) {
736     GSplitEdge(EOR,G1,LSclass);
737     //modified by NIZNHY-PKV Mon Mar 19 16:53:40 2001 f
738     if (myIsKPart==4) {
739       // Only solids are available here
740       TopAbs_State aState;
741       Standard_Integer aRank1;
742       TopTools_ListOfShape anAuxList;
743
744       aRank1=ShapeRank(EOR);
745       const TopoDS_Shape& aSolid=(aRank1==1) ? myShape2 : myShape1;
746       
747       TopTools_ListOfShape& aSplitList = ChangeSplit (EOR, TB1);
748       TopTools_ListIteratorOfListOfShape anIt(aSplitList);
749       for (; anIt.More(); anIt.Next()) {
750         const TopoDS_Edge& aSplitEdge=TopoDS::Edge (anIt.Value());
751         aState=ClassifyEdgeToSolidByOnePoint (aSplitEdge, aSolid);
752         if (aState==TB1) {
753           anAuxList.Append (aSplitEdge);
754         }
755       }
756       
757       aSplitList.Clear();
758       
759       anIt.Initialize(anAuxList);
760       for (; anIt.More(); anIt.Next()) {
761         const TopoDS_Shape& aShape=anIt.Value();
762         aSplitList.Append(aShape);
763       }
764     }
765     //modified by NIZNHY-PKV Mon Mar 19 16:53:44 2001 t
766   }
767
768   //xpu200598 : never add spIN in fusion
769   Standard_Boolean opeFus = Opefus(); //xpu200598
770   if (opeFus) //xpu200598
771     if (TB1 == TopAbs_IN) return;  //xpu200598
772      
773   Standard_Boolean issplit = IsSplit(EOR,TB1);
774   if ( issplit ) {
775     const TopTools_ListOfShape& LSE = Splits(EOR,TB1);
776
777 #ifdef DEB
778     if(tSPS) {
779       GdumpSHASTA(iEOR,TB1,WES,"--- GSplitEdgeWES","WES+ Split");
780       cout<<" ";TopAbs::Print(TB1,cout)<<" : "<<LSE.Extent()<<" edge(s) ";
781       TopAbs::Print(neworiE,cout); cout<<endl;
782     }
783 #endif
784
785     for (TopTools_ListIteratorOfListOfShape it(LSE); 
786          it.More(); it.Next()) {
787       TopoDS_Edge newE = TopoDS::Edge(it.Value()); 
788       if (newO) {// xpu060598   
789         // PRO13075 tspIN(f18), tspIN(e17)
790         // we add sp(EOR) to myFaceToFill with its orientation
791         newE.Orientation(oEinF);
792         Standard_Boolean dgE = BRep_Tool::Degenerated(TopoDS::Edge(EOR)); 
793         if (!dgE && hsdmE) {
794           Standard_Real f,l; FUN_tool_bounds(newE,f,l); 
795           Standard_Real x = 0.45678; Standard_Real par = (1-x)*f + x*l; 
796           Standard_Boolean so = Standard_True;
797           Standard_Boolean ok = FUN_tool_curvesSO(newE,par,TopoDS::Edge(EOR),so);
798           if (!ok) {
799 #ifdef DEB
800             cout<<"GSplitEdgeWES: cannot orient SDM split of an edge"<<endl;
801 #endif
802             //return; // nyiFUNRAISE
803           }
804           if (!so) {
805             newE.Reverse();
806           }
807         } //!dgE && hsdmE
808       }// xpu060598     
809       else newE.Orientation(neworiE);
810       
811 #ifdef DEB
812       if (tSPS) debaddpwes(iWESF,TB1,iEOR,neworiE,(TopOpeBRepBuild_Builder* const)this,&WES,"GSplitEdgeWES " ,"WES+ Eisspl ");
813 #endif
814       
815       WES.AddStartElement(newE);
816     }
817   } // issplit
818
819   else {
820     // EOR sans devenir de Split par TB1 : on la garde si elle est situee TB1 / LSclass
821     Standard_Boolean se = BDS.IsSectionEdge(TopoDS::Edge(EOR));
822     Standard_Boolean hs = myDataStructure->HasShape(EOR);
823     Standard_Boolean hg = myDataStructure->HasGeometry(EOR);
824     Standard_Boolean add = Standard_False;
825     Standard_Boolean addON = Standard_False;
826
827     Standard_Boolean isstart = Standard_False;
828     isstart = hs;
829
830     if (se) {
831       Standard_Boolean ftg = !LSclass.IsEmpty();
832       TopAbs_ShapeEnum tclass = LSclass.First().ShapeType();
833       ftg = ftg && (tclass == TopAbs_FACE);
834       if (!ftg) {
835         TopAbs_State pos;
836         Standard_Boolean keepse = GKeepShape1(EOR,LSclass,TB1,pos);
837         if (keepse)
838           add = Standard_True;
839         else if (myProcessON && pos == TopAbs_ON)
840           addON = Standard_True;
841       }
842       
843 #ifdef DEBDEB
844       cout<<"o-o GridFF ffil F"<<ifil<<" se E"<<iEOR<<" / "<<iWESF<<" ";
845       TopAbs::Print(TB1,cout);cout.flush();
846       Standard_Boolean tse = TopOpeBRepDS_GettraceSPSX(iEOR);
847       TopOpeBRepDS_SettraceSPSX(iEOR,Standard_True);
848       if (!ftg) {cout<<" : !ftg --> "; GKeepShape(EOR,LSclass,TB1);cout.flush();}
849       else      {cout<<" : ftg --> non gardee"<<endl;cout.flush();}
850       TopOpeBRepDS_SettraceSPSX(iEOR,tse);
851 #endif
852
853     }
854     else {
855       add = Standard_True;
856       Standard_Boolean testkeep = Standard_True;
857       testkeep = hs && (!hg);
858       if (testkeep) {
859 #ifdef DEB
860         if(tSPS){cout<<"--- GSplitEdgeWES ";}
861 #endif
862         TopAbs_State pos;
863         Standard_Boolean keep = GKeepShape1(EOR,LSclass,TB1,pos);
864         if ( !keep ) {
865           Standard_Boolean testON = (!LSclass.IsEmpty());
866           if (testON) testON = (LSclass.First().ShapeType() == TopAbs_SOLID);
867           if (testON) keep = (pos == TopAbs_ON);
868           addON = myProcessON && keep;
869         }
870         add = keep;
871       }
872     } // !se
873
874     if (add) {
875       TopoDS_Shape newE = EOR;
876        
877       if      (newO)                 newE.Orientation(oEinF);// xpu060598  
878       else if (Oinref == FORREVOPPO) newE.Orientation(TopAbs_INTERNAL);// xpu120898 (PRO14785 : e36 shared by f34 & f39,
879                                                                        // faces sdm with f16)
880       else                           newE.Orientation(neworiE); 
881 #ifdef DEB
882       if(tSPS){
883         DEBSHASET(ss,"--- GSplitEdgeWES ",WES," WES+ edge ");  
884         GdumpSHA(newE,(Standard_Address)ss.ToCString());
885         cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 edge ";
886         TopAbs::Print(neworiE,cout); cout<<endl;
887       }
888 #endif
889
890       if (isstart) {
891 #ifdef DEB
892         if (tSPS) debaddpwes(iWESF,TB1,iEOR,neworiE,(TopOpeBRepBuild_Builder* const)this,&WES,"GSplitEdgeWES " ,"WES+ Enospl ");
893 #endif
894         WES.AddStartElement(newE);
895       }
896       else {
897         WES.AddElement(newE);
898       }
899     } // add
900
901     if (addON) {
902       TopoDS_Shape newE = EOR;
903       newE.Orientation(neworiE);
904       myONElemMap.Add(newE);
905     }
906   } // !issplit
907
908   if (myProcessON && IsSplit(EOR,TopAbs_ON)) {
909     const TopTools_ListOfShape& LSE = Splits(EOR,TopAbs_ON);
910     TopTools_ListIteratorOfListOfShape it(LSE);
911     for (; it.More(); it.Next()) {
912       TopoDS_Edge newE = TopoDS::Edge(it.Value());
913       if (newO) {
914         newE.Orientation(oEinF);
915         Standard_Boolean dgE = BRep_Tool::Degenerated(TopoDS::Edge(EOR)); 
916         if (!dgE && hsdmE) {
917           Standard_Real f,l; FUN_tool_bounds(newE,f,l); 
918           Standard_Real x = 0.45678; Standard_Real par = (1-x)*f + x*l; 
919           Standard_Boolean so = Standard_True;
920           Standard_Boolean ok = FUN_tool_curvesSO(newE,par,TopoDS::Edge(EOR),so);
921           if (!ok) {
922 #ifdef DEB
923             cout<<"GSplitEdgeWES: cannot orient SDM split of an edge"<<endl;
924 #endif
925           }
926           if (!so) newE.Reverse();
927         }
928       }
929       else newE.Orientation(neworiE);
930       myONElemMap.Add(newE);
931     }
932   }
933
934 #ifdef DEB
935   if(tSPS) GdumpSHASTA(iEOR,TB1,WES,"--- GSplitEdgeWES","END");
936 #endif  
937   
938   return;
939 } // GSplitEdgeWES
940
941 Standard_IMPORT Standard_Boolean FUN_ismotheropedef();
942 Standard_IMPORT const TopOpeBRepBuild_GTopo& FUN_motherope();
943 Standard_EXPORT Standard_Boolean GLOBAL_IEtoMERGE = 0; // xpu240498
944
945 #ifdef DEB
946 void debmergee(const Standard_Integer /*i*/) {}
947 #endif
948
949 //=======================================================================
950 //function : GMergeEdgeWES
951 //purpose  : 
952 //=======================================================================
953   void TopOpeBRepBuild_Builder::GMergeEdgeWES(const TopoDS_Shape& EOR,
954                                               const TopOpeBRepBuild_GTopo& G1,
955                                               TopOpeBRepBuild_WireEdgeSet& WES)
956 {
957 #ifdef DEB
958   Standard_Integer iWESF; /*Standard_Boolean tSPSW = */GtraceSPS(WES.Face(),iWESF);
959   Standard_Integer iEOR; Standard_Boolean tSPS = GtraceSPS(EOR,iEOR);
960   if(tSPS){ debmergee(iEOR);
961     DEBSHASET(s,"\n--- GMergeEdgeWES ",WES," START ");  
962     GdumpSHAORIGEO(EOR,(Standard_Address)s.ToCString()); cout<<endl;
963   }
964 #endif
965
966   Standard_Boolean closing = BRep_Tool::IsClosed(TopoDS::Edge(EOR),myFaceToFill); // xpu050598
967   if (closing) return; // xpu050598
968
969   if (Opefus()) return;
970   
971 //  const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
972   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
973   Standard_Boolean RevOri1 = G1.IsToReverse1();
974   TopAbs_Orientation oriE = EOR.Orientation();
975   TopAbs_Orientation neworiE = Orient(oriE,RevOri1);
976   
977   Standard_Boolean hassame = myDataStructure->HasSameDomain(EOR);
978   if (!hassame) return;
979
980   Standard_Boolean Eisref = Standard_False;
981   if (hassame) {
982     Standard_Integer iEref = myDataStructure->SameDomainReference(EOR);
983     const TopoDS_Shape& Eref = myDataStructure->Shape(iEref);
984     Eisref = EOR.IsSame(Eref);
985   }
986
987   TopAbs_State TBEOR = (Eisref) ? TB1 : TB2; 
988   if (TBEOR == TopAbs_OUT) return; //xpu040598
989
990   Standard_Boolean ismerged = IsMerged(EOR,TBEOR);
991   if (ismerged) {
992     if (!Eisref) return;
993
994     const TopTools_ListOfShape& ME = Merged(EOR,TBEOR);
995     TopTools_ListIteratorOfListOfShape it(ME);
996     for(; it.More(); it.Next()) {
997       TopoDS_Shape newE = it.Value();
998       newE.Orientation(neworiE);
999
1000 #ifdef DEB
1001       if (tSPS) debaddpwes(iWESF,TB1,iEOR,neworiE,(TopOpeBRepBuild_Builder* const)this,&WES,"GMergeEdgeWES " ,"WES+ Emerge ");
1002 #endif
1003
1004       WES.AddStartElement(newE);
1005     }
1006     return;
1007   } 
1008
1009   ChangeMerged(EOR,TBEOR) = myEmptyShapeList; 
1010   TopAbs_State stspEOR;
1011 //  if (isfafa) stspEOR = TBEOR; // xpu110598
1012 //  else stspEOR = (TBEOR == TopAbs_IN) ? TopAbs_ON : TopAbs_OUT;
1013   stspEOR = TBEOR; // xpu120598
1014
1015   Standard_Boolean issplit = IsSplit(EOR,stspEOR);
1016   if (!issplit) return;
1017
1018   ChangeMerged(EOR,TBEOR) = Splits(EOR,stspEOR);
1019
1020   const TopTools_ListOfShape& ME = Merged(EOR,TBEOR);
1021 #ifdef DEB
1022   if(tSPS){
1023     DEBSHASET(s,"GMergeEdgeWES(1) ",WES," WES+ Merged ");  
1024     GdumpSHA(EOR,(Standard_Address)s.ToCString());
1025     cout<<" ";TopAbs::Print(TBEOR,cout);
1026     cout<<" : "<<ME.Extent()<<" edge"<<endl;
1027   }
1028 #endif
1029   for(TopTools_ListIteratorOfListOfShape it(ME);it.More();it.Next()) {
1030     TopoDS_Shape newE = it.Value();
1031     newE.Orientation(neworiE);
1032     WES.AddStartElement(newE);
1033   }
1034
1035 #ifdef DEB
1036   if(tSPS){
1037     DEBSHASET(sss,"GMergeEdgeWES ",WES," END ");
1038     GdumpSHA(EOR,(Standard_Address)sss.ToCString());cout<<endl;
1039   }
1040 #endif
1041   
1042 } // GMergeEdgeWES
1043
1044 //=======================================================================
1045 //function : GSplitEdge
1046 //purpose  : 
1047 //=======================================================================
1048   void TopOpeBRepBuild_Builder::GSplitEdge(const TopoDS_Shape& EOR,
1049                                            const TopOpeBRepBuild_GTopo& G1,
1050                                            const TopTools_ListOfShape& LSclass)
1051 {
1052   TopAbs_ShapeEnum t1,t2,ShapeInterf;
1053   G1.Type(t1,t2); ShapeInterf = t1;
1054   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
1055   // work on a FORWARD edge <EF>
1056   TopoDS_Shape EF = EOR; EF.Orientation(TopAbs_FORWARD);
1057   
1058 #ifdef DEB
1059   Standard_Integer iE; Standard_Boolean tSPS = GtraceSPS(EOR,iE);
1060   if (tSPS) GdumpSHASTA(EOR,TB1,"--- GSplitEdge ","\n");
1061   if (tSPS) GdumpEDG(EF);
1062   if (tSPS) debsplite(iE);
1063 #endif
1064
1065   const TopoDS_Edge& EEF = TopoDS::Edge(EF);
1066   Standard_Boolean isse = myDataStructure->DS().IsSectionEdge(EEF);
1067   Standard_Boolean issplitON = IsSplit(EEF,TopAbs_ON);
1068   Standard_Boolean takeON = (TB1 == TopAbs_IN) && (isse) && (issplitON);
1069   takeON = Standard_False;
1070 #ifdef DEB
1071   if (tSPS) cout<<"---- takeON mis a 0"<<endl;
1072 #endif
1073
1074   if ( takeON ) {
1075
1076 #ifdef DEB
1077     if (tSPS) GdumpSHASTA(EOR,TB1,"--- GSplitEdge takeON ","\n");
1078 #endif
1079
1080     MarkSplit(EF,TB1);
1081     TopTools_ListOfShape& SSEL = ChangeSplit(EF,TB1);
1082     SSEL.Clear();
1083     SSEL = Splits(EEF,TopAbs_ON);
1084     return;
1085   }
1086
1087   TopTools_ListOfShape LOE;
1088   
1089   // Make a PaveSet PVS on edge EF
1090   TopOpeBRepBuild_PaveSet PVS(EF);
1091   
1092   // Add the point topology found on edge EF in PVS
1093   myEdgeReference = TopoDS::Edge(EF);
1094   GFillPointTopologyPVS(EF,G1,PVS);
1095   
1096   // mark EF as split TB1
1097   MarkSplit(EF,TB1);
1098   
1099   // build the new edges LOE on EF from the Parametrized Vertex set PVS
1100   GPVSMakeEdges(EF,PVS,LOE);
1101   
1102   Standard_Boolean novertex = LOE.IsEmpty();
1103   if (novertex) return;
1104
1105   TopTools_ListOfShape& SEL = ChangeSplit(EF,TB1);
1106   SEL.Clear();
1107   // NYI ne pas faire de classification des aretes reconstruites / liste de solides
1108   // NYI dans le cas ou l'appel a SplitEdge est utilise pour construire les parties
1109   // NYI (TopAbs_ON,SOLID) (i.e par la construction des parties (TopAbs_IN,FACE)).
1110   TopOpeBRepDS_Config c1 = G1.Config1(),c2 = G1.Config2();
1111   Standard_Boolean UUFACE = (c1==TopOpeBRepDS_UNSHGEOMETRY && c2==TopOpeBRepDS_UNSHGEOMETRY);
1112
1113   Standard_Boolean ONSOLID = Standard_False;
1114   if ( ! LSclass.IsEmpty() ) {
1115     TopAbs_ShapeEnum t = LSclass.First().ShapeType();
1116     ONSOLID = (t == TopAbs_SOLID);
1117   }
1118
1119   Standard_Boolean toclass = UUFACE;
1120   toclass = ! ONSOLID; 
1121
1122   TopTools_ListOfShape loos;
1123   const TopTools_ListOfShape* pls;
1124   if (GLOBAL_classifysplitedge) {
1125     Standard_Integer r=GShapeRank(EOR);
1126     TopoDS_Shape oos=myShape1;
1127     if (r==1) oos = myShape2;
1128     if (!oos.IsNull()) loos.Append(oos); // PMN 5/03/99 Nothing to append
1129     pls = &loos;
1130   }
1131   else if (toclass) {
1132     pls = &LSclass;
1133   }
1134   else {
1135     pls = &myEmptyShapeList;
1136   }
1137
1138   TopTools_ListOfShape aLON;
1139   TopTools_ListIteratorOfListOfShape it(LOE);
1140   for(;it.More();it.Next()) {
1141     const TopoDS_Shape& aE = it.Value();
1142     TopAbs_State pos;
1143     if (GKeepShape1(aE,*pls,TB1,pos))
1144       SEL.Append(aE);
1145     else if (myProcessON && pos == TopAbs_ON)
1146       aLON.Append(aE);
1147   }
1148
1149   if (!aLON.IsEmpty()) {
1150     MarkSplit(EF,TopAbs_ON);
1151     TopTools_ListOfShape& aSLON = ChangeSplit(EF,TopAbs_ON);
1152     aSLON.Clear();
1153     aSLON.Append(aLON);
1154   }
1155
1156 } // GSplitEdge
1157
1158 //modified by NIZNHY-PKV Mon Mar 19 16:50:33 2001 f
1159 #include <BRepClass3d_SolidClassifier.hxx>
1160 //=======================================================================
1161 //function : ClassifyEdgeToSolidByOnePoint
1162 //purpose  : 
1163 //=======================================================================
1164 TopAbs_State ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E,
1165                                                   const TopoDS_Shape& Ref)
1166 {
1167   const Standard_Real PAR_T = 0.43213918;//10.*e^-PI
1168   Standard_Real f2 = 0., l2 = 0., par = 0.;
1169
1170   Handle(Geom_Curve) C3D = BRep_Tool::Curve(E, f2, l2);
1171   gp_Pnt aP3d;
1172
1173   if(C3D.IsNull()) {
1174     //it means that we are in degenerated edge
1175     const TopoDS_Vertex& fv = TopExp::FirstVertex(E);
1176     if(fv.IsNull())
1177       return TopAbs_UNKNOWN;
1178     aP3d = BRep_Tool::Pnt(fv);
1179   }
1180   else {//usual case
1181     par = f2*PAR_T + (1 - PAR_T)*l2;
1182     C3D -> D0(par, aP3d);
1183   }
1184     
1185   BRepClass3d_SolidClassifier SC(Ref);
1186   SC.Perform(aP3d, 1e-7);
1187
1188   return SC.State();
1189 }
1190 //modified by NIZNHY-PKV Mon Mar 19 16:50:36 2001 t