0024510: Remove unused local variables
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_GridSS.cxx
1 // Created on: 1996-03-07
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and / or modify it
9 // under the terms of the GNU Lesser General Public version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <TopOpeBRepBuild_Builder.jxx>
18
19 #include <TopOpeBRepBuild_GTool.hxx>
20 #include <TopOpeBRepTool_ShapeExplorer.hxx>
21 #include <BRep_Tool.hxx>
22 #include <TopoDS.hxx>
23 #include <Geom2d_Curve.hxx>
24 #include <Standard_ProgramError.hxx>
25 #include <TopExp.hxx>
26 #include <TopOpeBRepTool_ShapeTool.hxx>
27 #include <TopOpeBRepDS_CurvePointInterference.hxx>
28 #include <GeomAdaptor_Surface.hxx>
29 #include <Geom_Surface.hxx>
30 #include <Geom_CylindricalSurface.hxx>
31 #include <Geom_TrimmedCurve.hxx>
32 #include <Geom2d_Curve.hxx>
33 #include <Geom2d_TrimmedCurve.hxx>
34 #include <Geom2d_Line.hxx>
35 #include <gp_Circ.hxx>
36 #include <gp_Dir2d.hxx>
37 #include <gp_Pnt2d.hxx>
38 #include <gp_Pnt.hxx>
39 #include <Precision.hxx>
40 #include <TopOpeBRepBuild_define.hxx>
41 #include <TopOpeBRepTool.hxx>
42 #include <TopOpeBRepTool_EXPORT.hxx>
43 #include <TopOpeBRepTool_2d.hxx>
44 #include <TopOpeBRepTool_CORRISO.hxx>
45 #include <TopOpeBRepTool_TOOL.hxx>
46 #include <TopOpeBRepDS.hxx>
47 #include <TopOpeBRepDS_EXPORT.hxx>
48 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
49 #include <BRepAdaptor_Surface.hxx>
50 #include <TopOpeBRepBuild_Tools.hxx>
51 #include <TopoDS_Iterator.hxx>
52 #include <TopOpeBRepDS_connex.hxx>
53 #include <gp_Lin2d.hxx>
54 #include <BRepClass_Intersector.hxx>
55 #include <BRepClass_Edge.hxx>
56 #include <IntRes2d_IntersectionPoint.hxx>
57 #include <IntRes2d_IntersectionSegment.hxx>
58 #include <ElCLib.hxx>
59 #include <BRepTools.hxx>
60 #include <GeomAPI_ProjectPointOnSurf.hxx>
61
62 #ifdef DRAW
63 #include <TopOpeBRepTool_DRAW.hxx>
64 #include <TopOpeBRepDS_DRAW.hxx>
65 #endif
66
67
68 #ifdef DEB
69 #define DEBSHASET(sarg,meth,shaset,str) TCollection_AsciiString sarg((meth));(sarg)=(sarg)+(shaset).DEBNumber()+(str);
70 extern Standard_Boolean TopOpeBRepDS_GettraceSTRANGE();
71 Standard_EXPORT void debsplitf(const Standard_Integer i){cout<<"++ debsplitf "<<i<<endl;}
72 Standard_EXPORT void debspanc(const Standard_Integer i){cout<<"++ debspanc "<<i<<endl;}
73 Standard_Integer GLOBAL_iexF = 0;
74 #endif
75
76 Standard_EXPORT Handle(Geom2d_Curve) BASISCURVE2D(const Handle(Geom2d_Curve)& C);
77 Standard_EXPORT void TopOpeBRepDS_SetThePCurve
78 (const BRep_Builder& B,TopoDS_Edge& E, const TopoDS_Face& F,const TopAbs_Orientation O,const Handle(Geom2d_Curve)& C);
79 //Standard_IMPORT Standard_Integer FUN_tool_outofUVbounds
80 //(const TopoDS_Face& fF,const TopoDS_Edge& E,Standard_Real& splitpar);
81
82 //---------------------------------------------
83 static Standard_Integer FUN_getG(const gp_Pnt P,const TopOpeBRepDS_ListOfInterference& LI,const Handle(TopOpeBRepDS_HDataStructure) HDS,Standard_Integer& iEinterf)
84 //---------------------------------------------
85 {
86   TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI);
87   Handle(TopOpeBRepDS_CurvePointInterference) SSI;  
88   for (; ILI.More(); ILI.Next() ) {
89     const Handle(TopOpeBRepDS_Interference)& I = ILI.Value();
90     SSI = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I);
91     if (SSI.IsNull()) continue;
92     Standard_Integer GI = SSI->Geometry();
93     iEinterf = SSI->Support();
94     const TopOpeBRepDS_Point& DSP = HDS->Point(GI);
95     const gp_Pnt& P3d = DSP.Point();
96     Standard_Real tolp = DSP.Tolerance();    
97     Standard_Boolean sameP = P3d.IsEqual(P,tolp);
98     if (sameP) return GI;
99   } 
100   return 0;
101 }
102
103 //----------------------------------------------------------------------        
104 // FUN_EPIforEvisoONperiodicF :
105 // Let <F> be a periodic face,
106 // <E> an edge with as pcurve on <F> a Viso line.
107 //
108 // if the pcurve of par u not bound in [0,2PI] : computes <CPI> interference on 
109 // <E> to split the edge at the point p2pi of u = 2PI; returns true.
110 // else                                        : returns false.
111 //
112 // To split the edge, scans among the list of edge point interferences
113 // <EPIL> in order to get a geometry point falling into geometry P2pi on 
114 // <F> of UV parameters = p2pi.
115 // Gets the new vertex of array <newV> attached to the geometry P2pi.
116 //----------------------------------------------------------------------        
117
118 #define SPLITEDGE      ( 0)
119 #define INCREASEPERIOD ( 1)
120 #define DECREASEPERIOD (-1)
121         
122 static Standard_Boolean FUN_EPIforEvisoONperiodicF
123 (const TopoDS_Edge& E,const TopoDS_Face& F,const TopOpeBRepDS_ListOfInterference& EPIlist,const Handle(TopOpeBRepDS_HDataStructure) HDS,TopOpeBRepDS_ListOfInterference& loCPI)
124 {
125   Standard_Real parone=-1.e7;   
126   TopOpeBRepTool_CORRISO CORRISO(F); CORRISO.Init(F);
127   Standard_Real uper; Standard_Boolean onU = CORRISO.Refclosed(1,uper); 
128   Standard_Real tolF = BRep_Tool::Tolerance(F); Standard_Real tolu = CORRISO.Tol(1,tolF);
129   Standard_Integer recadre = CORRISO.EdgeOUTofBoundsUV(E,onU,tolu,parone);
130   //Standard_Integer recadre = FUN_tool_outofUVbounds(F,E,parone);
131   if (recadre != SPLITEDGE) return Standard_False;
132
133   gp_Pnt p3d; Standard_Boolean ok = FUN_tool_value(parone,E,p3d);
134   if (!ok) return Standard_False; // nyi FUN_Raise
135   Standard_Integer iEinterf=0; Standard_Integer iG = FUN_getG(p3d,EPIlist,HDS,iEinterf);
136   if (iG == 0) {
137 #ifdef DEB
138     Standard_Boolean strange = TopOpeBRepDS_GettraceSTRANGE();
139     if (strange) cout<<"strange : FUN_EPIforEvisoONperiodicF"<<endl;
140 #endif
141     return Standard_False;
142   }
143   if (HDS->Shape(iEinterf).ShapeType() != TopAbs_EDGE) iEinterf = 0;
144 //  else V2pi = TopoDS::Vertex(newV->Array1().Value(iG));
145   
146   // <CPI> :
147   Standard_Integer iS = HDS->Shape(E);
148   TopOpeBRepDS_Transition T(TopAbs_IN, TopAbs_IN, TopAbs_EDGE, TopAbs_EDGE); T.Index(iS);
149   Handle(TopOpeBRepDS_CurvePointInterference) CPI = new TopOpeBRepDS_CurvePointInterference
150       (T,TopOpeBRepDS_EDGE,iEinterf,TopOpeBRepDS_POINT,iG,parone); 
151   loCPI.Append(CPI);
152   return Standard_True;
153 } //FUN_EPIforEvisoONperiodicF
154
155 //----------------------------------------------------------------------
156 // FUN_GetSplitsON :
157 // <F> is a periodic face, <E> has for pcurve on <F> a visoline
158 // of par u not bound in [0,2PI]. 
159 // Splits the edge at <paronE> (UV point for <paronE> has its u=2PI)
160 // Recompute the pcurve for the split with (parameter on edge >= <paronE>)
161 //----------------------------------------------------------------------
162 /*static void FUN_GetSplitsON
163 (const TopoDS_Edge& E, TopoDS_Vertex& V2pi, const Standard_Real& paronE,const TopoDS_Face& F, TopTools_ListOfShape& losplits)
164 {
165   Standard_Real pf,pl,tolpc;  
166   TopoDS_Vertex Vf, Vl; TopExp::Vertices(E,Vf,Vl);
167   Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,F,pf,pl,tolpc);
168   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F);
169   Standard_Real tole = BRep_Tool::Tolerance(E);
170   TopOpeBRepDS_BuildTool BT; BRep_Builder BB;
171   
172   TopAbs_Orientation oriVinf, oriVsup, oriE = E.Orientation();
173   oriVinf = (oriE == TopAbs_FORWARD)? TopAbs_FORWARD: TopAbs_REVERSED;
174   oriVsup = (oriE == TopAbs_FORWARD)? TopAbs_REVERSED: TopAbs_FORWARD;
175   
176   // Einf2pi :
177   TopoDS_Edge Einf2pi; BT.CopyEdge(E,Einf2pi);
178   Vf.Orientation(oriVinf);   BB.Add(Einf2pi,Vf);   BT.Parameter(Einf2pi,Vf,pf);
179   V2pi.Orientation(oriVsup); BB.Add(Einf2pi,V2pi); BT.Parameter(Einf2pi,V2pi,paronE);
180   
181   // Esup2pi :  
182   TopoDS_Edge Esup2pi; BT.CopyEdge(E,Esup2pi);
183   V2pi.Orientation(oriVinf); BB.Add(Esup2pi,V2pi); BT.Parameter(Esup2pi,V2pi,paronE);
184   Vl.Orientation(oriVsup);   BB.Add(Esup2pi,Vl);   BT.Parameter(Esup2pi,Vl,pl);
185   gp_Pnt2d tmp = PC->Value(pf); Standard_Real v = tmp.Y();
186   Handle(Geom2d_Line) L2d = 
187     new Geom2d_Line(gp_Pnt2d(-paronE,v),gp_Dir2d(1.,0.));
188   Handle(Geom2d_TrimmedCurve) PCsup2pi = new Geom2d_TrimmedCurve(L2d,paronE,pl); 
189   TopOpeBRepDS_SetThePCurve(BB,Esup2pi,F,oriE,PCsup2pi);
190   
191 #ifdef DEB
192   Standard_Boolean trc = Standard_False;
193 #ifdef DRAW
194   if (trc) {TCollection_AsciiString aa("PCinf");FUN_tool_draw(aa,Einf2pi,F,0);}
195   if (trc) {TCollection_AsciiString aa("PCsup");FUN_tool_draw(aa,Esup2pi,F,0);} 
196 #endif
197 #endif
198   losplits.Append(Einf2pi); losplits.Append(Esup2pi);
199 }*/
200
201 //---------------------------------------------
202 static void FUN_getEPI(const TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_ListOfInterference& EPI)
203 //---------------------------------------------
204 {
205   TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI);
206   Handle(TopOpeBRepDS_CurvePointInterference) CPI;  
207   for (; ILI.More(); ILI.Next() ) {
208     const Handle(TopOpeBRepDS_Interference)& I = ILI.Value();
209     CPI = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I);
210     if (CPI.IsNull()) continue;
211     TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(CPI,GT,GI,ST,SI);
212     if (GT != TopOpeBRepDS_POINT || ST != TopOpeBRepDS_FACE)  continue;
213     EPI.Append(I);
214   }
215 }
216
217 //---------------------------------------------
218 static void FUN_getEPIonEds(const TopoDS_Shape& FOR,const Handle(TopOpeBRepDS_HDataStructure)& HDS,TopOpeBRepDS_ListOfInterference& EPI)
219 //---------------------------------------------
220 {
221   TopExp_Explorer ex(FOR, TopAbs_EDGE);
222   for (; ex.More(); ex.Next()) {
223     const TopoDS_Shape& E = ex.Current();
224     if (HDS->HasShape(E)) {
225       const TopOpeBRepDS_ListOfInterference& LII = HDS->DS().ShapeInterferences(E);
226       FUN_getEPI(LII,EPI);      
227     }
228   }
229 }
230
231 //=======================================================================
232 //function : GMergeSolids
233 //purpose  : 
234 //=======================================================================
235 void TopOpeBRepBuild_Builder::GMergeSolids(const TopTools_ListOfShape& LSO1,const TopTools_ListOfShape& LSO2,const TopOpeBRepBuild_GTopo& G1)
236 {
237   if ( LSO1.IsEmpty() ) return;
238   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
239   
240   const TopoDS_Shape& SO1 = LSO1.First();
241 #ifdef DEB
242   Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SO1,iSO);
243   if(tSPS){
244     cout<<endl;
245     cout<<"--- GMergeSolids "<<endl;
246     GdumpSAMDOM(LSO1, (char *) "1 : ");
247     GdumpSAMDOM(LSO2, (char *) "2 : ");
248   }
249 #endif
250   
251   mySolidReference = TopoDS::Solid(SO1);
252   TopOpeBRepBuild_ShellFaceSet SFS(SO1,this);
253   GFillSolidsSFS(LSO1,LSO2,G1,SFS);
254   
255   // Create a solid builder SOBU
256   TopoDS_Shape SO1F = LSO1.First(); SO1F.Orientation(TopAbs_FORWARD);
257   TopOpeBRepBuild_SolidBuilder SOBU;
258   Standard_Boolean ForceClassSOBU = Standard_True;
259   SOBU.InitSolidBuilder(SFS,ForceClassSOBU);
260   
261   // Build new solids LSOM
262   TopTools_ListOfShape LSOM;
263   GSOBUMakeSolids(SO1F,SOBU,LSOM);
264   
265   // connect new solids as solids built TB1 on LSO1 solids
266   TopTools_ListIteratorOfListOfShape it1;
267   for (it1.Initialize(LSO1); it1.More(); it1.Next()) {
268     const TopoDS_Shape& aSO1 = it1.Value();
269     Standard_Boolean ismerged = IsMerged(aSO1,TB1);
270     if (ismerged) continue;
271     TopTools_ListOfShape& SOL = ChangeMerged(aSO1,TB1);
272     SOL = LSOM;
273   }
274   
275   // connect new solids as solids built TB2 on LSO2 solids
276   TopTools_ListIteratorOfListOfShape it2;
277   for (it2.Initialize(LSO2); it2.More(); it2.Next()) {
278     const TopoDS_Shape& SO2 = it2.Value();
279     Standard_Boolean ismerged = IsMerged(SO2,TB2);
280     if (ismerged) continue;
281     TopTools_ListOfShape& SOL = ChangeMerged(SO2,TB2);
282     SOL = LSOM;
283   }
284   
285 } // GMergeSolids
286
287 //=======================================================================
288 //function : GFillSolidsSFS
289 //purpose  : 
290 //=======================================================================
291 void TopOpeBRepBuild_Builder::GFillSolidsSFS(const TopTools_ListOfShape& LS1,const TopTools_ListOfShape& LS2,const TopOpeBRepBuild_GTopo& G1,TopOpeBRepBuild_ShellFaceSet& SFS)
292 {
293
294   if ( LS1.IsEmpty() ) return;
295   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
296   myProcessON = (Opecom() || Opefus());
297   if (myProcessON) {
298     myONFacesMap.Clear();
299   }
300   
301   mySolidReference = TopoDS::Solid(LS1.First());
302   
303   TopAbs_State TB;
304   TopOpeBRepBuild_GTopo G;
305   TopTools_ListIteratorOfListOfShape it;
306   
307   G = G1;
308   TB = TB1; it.Initialize(LS1);
309   for(; it.More(); it.Next()) {
310     const TopoDS_Shape& S = it.Value();
311     Standard_Boolean tomerge = !IsMerged(S,TB);
312 #ifdef DEB
313     Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS);
314     if(tSPS){
315       cout<<endl;
316       GdumpSHASTA(S,TB,"--- GFillSolidsSFS "); cout<<" tomerge : "<<tomerge<<endl;
317     }
318 #endif
319     if (tomerge) GFillSolidSFS(S,LS2,G,SFS);
320   }
321   
322   G = G1.CopyPermuted();
323   TB = TB2;
324   it.Initialize(LS2);
325   for (; it.More(); it.Next()) {
326     const TopoDS_Shape& S = it.Value();
327     Standard_Boolean tomerge = !IsMerged(S,TB);
328 #ifdef DEB
329     Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS);
330     if(tSPS){
331       cout<<endl;
332       GdumpSHASTA(S,TB,"--- GFillSolidsSFS "); cout<<" tomerge : "<<tomerge<<endl;
333     }
334 #endif
335     if (tomerge) GFillSolidSFS(S,LS1,G,SFS);
336   }
337
338   if (myProcessON) {
339     AddONPatchesSFS(G1, SFS);
340     myProcessON = Standard_False;
341   }
342
343 } // GFillSolidsSFS
344
345 //=======================================================================
346 //function : GFillSolidSFS
347 //purpose  : 
348 //=======================================================================
349 void TopOpeBRepBuild_Builder::GFillSolidSFS(const TopoDS_Shape& SO1,const TopTools_ListOfShape& LSO2,const TopOpeBRepBuild_GTopo& G1,TopOpeBRepBuild_ShellFaceSet& SFS)
350 {
351   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
352   Standard_Boolean RevOri1 = G1.IsToReverse1();
353   
354 #ifdef DEB
355   Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SO1,iSO);
356   if(tSPS){
357     cout<<endl;
358     GdumpSHASTA(SO1,TB1,"--- GFillSolidSFS ");cout<<endl;
359   }
360 #endif
361   
362   // work on a FORWARD solid SOF
363   TopoDS_Shape SOF = SO1; SOF.Orientation(TopAbs_FORWARD);
364   mySolidToFill = TopoDS::Solid(SOF);
365   
366   TopOpeBRepTool_ShapeExplorer exShell(SOF,TopAbs_SHELL);
367   for (; exShell.More(); exShell.Next()) {
368     TopoDS_Shape SH = exShell.Current();
369     Standard_Boolean hasshape = myDataStructure->HasShape(SH);
370     
371     if ( ! hasshape ) {
372       // shell SH is not in DS : classify it with LSO2 solids
373       Standard_Boolean keep = GKeepShape(SH,LSO2,TB1);
374       if (keep) {
375         TopAbs_Orientation oriSH = SH.Orientation();
376         TopAbs_Orientation neworiSH = Orient(oriSH,RevOri1);
377         SH.Orientation(neworiSH);
378
379 #ifdef DEB
380       if(tSPS){
381         DEBSHASET(ss,"--- GFillSolidSFS ",SFS," AddShape SFS+ shell ");  
382         GdumpSHA(SH,(Standard_Address)ss.ToCString());
383         cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 shell ";
384         TopAbs::Print(neworiSH,cout); cout<<endl;
385       }
386 #endif
387
388         SFS.AddShape(SH);
389       }
390     }
391     else { // shell SH has faces(s) with geometry : split SH faces
392       GFillShellSFS(SH,LSO2,G1,SFS);
393     }
394   }
395   
396 } // GFillSolidSFS
397
398 //=======================================================================
399 //function : GFillSurfaceTopologySFS
400 //purpose  : 
401 //=======================================================================
402 #ifdef DEB
403 void TopOpeBRepBuild_Builder::GFillSurfaceTopologySFS(const TopoDS_Shape& SO1,
404 #else
405 void TopOpeBRepBuild_Builder::GFillSurfaceTopologySFS(const TopoDS_Shape&,
406 #endif
407                                                       const TopOpeBRepBuild_GTopo& G1,
408                                                       TopOpeBRepBuild_ShellFaceSet& /*SFS*/)
409 {
410   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
411   TopAbs_ShapeEnum t1,t2;
412   G1.Type(t1,t2);
413 #ifdef DEB
414   TopAbs_ShapeEnum ShapeInterf = t1;
415 #endif
416   
417 #ifdef DEB
418   Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SO1,iSO);
419   if(tSPS){
420     cout<<endl;
421     cout<<"--- GFillSurfaceTopologySFS ShapeInterf ";TopAbs::Print(ShapeInterf,cout);
422     cout<<endl;
423   }
424   cout<<"GFillSurfaceTopologySFS : NYI"<<endl;
425 #endif
426   
427 } // GFillSurfaceTopologySFS
428
429 //=======================================================================
430 //function : GFillSurfaceTopologySFS
431 //purpose  : 
432 //=======================================================================
433 void TopOpeBRepBuild_Builder::GFillSurfaceTopologySFS
434   (const TopOpeBRepDS_SurfaceIterator& SSit,
435    const TopOpeBRepBuild_GTopo& G1,
436    TopOpeBRepBuild_ShellFaceSet& SFS) const 
437 {
438   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
439   TopOpeBRepDS_Config Conf = G1.Config1();
440   TopAbs_State TB = TB1;
441   if ( Conf == TopOpeBRepDS_DIFFORIENTED ) {
442     if      (TB1 == TopAbs_OUT) TB = TopAbs_IN;
443     else if (TB1 == TopAbs_IN ) TB = TopAbs_OUT;
444   }
445   
446 #ifdef DEB
447   Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SFS.Solid(),iSO);
448   Standard_Integer iref = myDataStructure->Shape(mySolidReference);
449   Standard_Integer ifil = myDataStructure->Shape(mySolidToFill);
450   if(tSPS){
451     cout<<"ifil : "<<ifil<<" iref : "<<iref<<endl;
452     cout<<"solid "<<ifil<<" is ";TopOpeBRepDS::Print(Conf,cout);
453     cout<<endl;
454   }
455 #endif
456   
457   // iG = index of new surface // NYI or existing face
458   Standard_Integer iG = SSit.Current();
459   const TopTools_ListOfShape& LnewF = NewFaces(iG);
460   TopTools_ListIteratorOfListOfShape Iti(LnewF);
461   for (; Iti.More(); Iti.Next()) {
462     TopoDS_Shape F = Iti.Value();
463     TopAbs_Orientation ori = SSit.Orientation(TB);
464     F.Orientation(ori);
465
466 #ifdef DEB
467     if (tSPS){
468       DEBSHASET(ss,"--- GFillSurfaceTopologySFS ",SFS," AddElement SFS+ face ");  
469       GdumpSHA(F,(Standard_Address)ss.ToCString());
470       cout<<" ";TopAbs::Print(TB,cout)<<" : 1 face ";
471       TopAbs::Print(ori,cout); cout<<endl;
472     }
473 #endif
474
475     SFS.AddElement(F);
476   } // iterate on new faces built on surface <iG>
477   
478 } // GFillSurfaceTopologySFS
479
480 //=======================================================================
481 //function : GFillShellSFS
482 //purpose  : 
483 //=======================================================================
484 void TopOpeBRepBuild_Builder::GFillShellSFS(const TopoDS_Shape& SH,
485                                             const TopTools_ListOfShape& LSO2,
486                                             const TopOpeBRepBuild_GTopo& G1,
487                                             TopOpeBRepBuild_ShellFaceSet& SFS)
488 {  
489   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
490
491 #ifdef DEB
492   Standard_Integer ish; Standard_Boolean tSPS = GtraceSPS(SH,ish);
493   if(tSPS){
494       cout<<endl;
495       GdumpSHA(SH, (char *) "--- GFillShellSFS ");
496       cout<<endl;}
497 #endif
498   
499   TopOpeBRepTool_ShapeExplorer exFace;
500   
501   // 1/ : toutes les faces HasSameDomain
502   for (exFace.Init(SH,TopAbs_FACE); exFace.More(); exFace.Next()) {
503     const TopoDS_Shape& FOR = exFace.Current();
504     Standard_Boolean hsd = myDataStructure->HasSameDomain(FOR);
505     if ( hsd ) {
506       GFillFaceSFS(FOR,LSO2,G1,SFS);
507     } // hsd
508   } // exFace.More()
509   
510 #ifdef DEB
511   if (tSPS) {
512     SFS.DumpSS();
513   }
514 #endif
515   
516   // 2/ : toutes les faces non HasSameDomain
517   for (exFace.Init(SH,TopAbs_FACE); exFace.More(); exFace.Next()) {
518     const TopoDS_Shape& FOR = exFace.Current();
519     Standard_Boolean hsd = myDataStructure->HasSameDomain(FOR);
520     if ( !hsd ) {
521       GFillFaceSFS(FOR,LSO2,G1,SFS);
522     } // hsd
523   }
524   
525 } // GFillShellSFS
526
527 // ----------------------------------------------------------------------
528 static void FUNBUILD_MAPSUBSHAPES(const TopoDS_Shape& S,
529                                   const TopAbs_ShapeEnum T,
530                                   TopTools_IndexedMapOfShape& _IM)
531 {
532  TopExp::MapShapes(S,T,_IM);
533 }
534
535 // ----------------------------------------------------------------------
536 static void FUNBUILD_MAPSUBSHAPES(const TopTools_ListOfShape& LOFS,
537                                   const TopAbs_ShapeEnum T,TopTools_IndexedMapOfShape& _IM)
538 {
539  for (TopTools_ListIteratorOfListOfShape it(LOFS);it.More();it.Next())
540    FUNBUILD_MAPSUBSHAPES(it.Value(),T,_IM);
541 }
542
543 // ----------------------------------------------------------------------
544 static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B,
545                                      const TopoDS_Shape& S,
546                                      const TopAbs_State STATE,
547                                      TopTools_IndexedDataMapOfShapeListOfShape& _IDM)
548 {
549   Standard_Boolean issp = B.IsSplit(S,STATE);
550   if (issp) {
551     const TopTools_ListOfShape& l = B.Splits(S,STATE);
552     for (TopTools_ListIteratorOfListOfShape it(l);it.More();it.Next()) {
553       const TopoDS_Shape& sps = it.Value(); // sps = split result of S on state STATE
554       TopTools_ListOfShape thelist;
555       if ( ! _IDM.Contains(sps) ) _IDM.Add(sps, thelist);
556       _IDM.ChangeFromKey(sps).Append(S);
557     }
558   }
559 }
560
561 // ----------------------------------------------------------------------
562 static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B,
563                                      const TopoDS_Shape& S,
564                                      TopTools_IndexedDataMapOfShapeListOfShape& _IDM)
565 {
566   FUNBUILD_MAPANCSPLSHAPES(B,S,TopAbs_IN, _IDM);
567   FUNBUILD_MAPANCSPLSHAPES(B,S,TopAbs_OUT,_IDM);
568 }
569
570 // ----------------------------------------------------------------------
571 static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B,
572                                      const TopTools_IndexedMapOfShape& M,
573                                      TopTools_IndexedDataMapOfShapeListOfShape& _IDM)
574 {
575   Standard_Integer n = M.Extent();
576   for(Standard_Integer i = 1;i <= n;i++) FUNBUILD_MAPANCSPLSHAPES(B,M(i),_IDM);
577 }
578
579 static TopTools_IndexedMapOfShape stabuild_IMELF1;
580 static TopTools_IndexedMapOfShape stabuild_IMELF2;
581 static TopTools_IndexedDataMapOfShapeListOfShape stabuild_IDMEALF1;
582 static TopTools_IndexedDataMapOfShapeListOfShape stabuild_IDMEALF2;
583 static TopOpeBRepDS_Config static_CONF1;
584 static TopOpeBRepDS_Config static_CONF2;
585 // ----------------------------------------------------------------------
586 Standard_EXPORT void FUNBUILD_ANCESTORRANKPREPARE(TopOpeBRepBuild_Builder& B,
587                                                   const TopTools_ListOfShape& LF1,
588                                                   const TopTools_ListOfShape& LF2,
589                                                   const TopOpeBRepDS_Config CONF1,
590                                                   const TopOpeBRepDS_Config CONF2)
591 {
592   static_CONF1 = CONF1;
593   static_CONF2 = CONF2;
594   FUNBUILD_MAPSUBSHAPES(LF1,TopAbs_EDGE,stabuild_IMELF1);
595   FUNBUILD_MAPSUBSHAPES(LF2,TopAbs_EDGE,stabuild_IMELF2);
596   FUNBUILD_MAPANCSPLSHAPES(B,stabuild_IMELF1,stabuild_IDMEALF1);
597   FUNBUILD_MAPANCSPLSHAPES(B,stabuild_IMELF2,stabuild_IDMEALF2);
598 }
599
600 static TopTools_IndexedMapOfShape stabuild_IMEF;
601 // ----------------------------------------------------------------------
602 Standard_EXPORT void FUNBUILD_ANCESTORRANKGET(TopOpeBRepBuild_Builder& /*B*/,
603                                               const TopoDS_Shape& f,
604                                               Standard_Boolean& of1,
605                                               Standard_Boolean& of2)
606 {
607   FUNBUILD_MAPSUBSHAPES(f,TopAbs_EDGE,stabuild_IMEF);
608   Standard_Integer ief = 1,nef = stabuild_IMEF.Extent();
609   of1 = Standard_False;
610   for (ief = 1; ief <= nef; ief++ ) {
611     const TopoDS_Shape& e = stabuild_IMEF(ief); of1 = stabuild_IDMEALF1.Contains(e);
612     if (of1) break;
613   } 
614   of2 = Standard_False;
615   for (ief = 1; ief <= nef; ief++ ) {
616     const TopoDS_Shape& e = stabuild_IMEF(ief); of2 = stabuild_IDMEALF2.Contains(e);
617     if (of2) break;
618   }
619 }
620
621 // ----------------------------------------------------------------------
622 Standard_EXPORT void FUNBUILD_ORIENTLOFS(TopOpeBRepBuild_Builder& B,
623                                          const TopAbs_State TB1,
624                                          const TopAbs_State TB2,
625                                          TopTools_ListOfShape& LOFS)
626 {
627   for (TopTools_ListIteratorOfListOfShape it(LOFS);it.More();it.Next()) {
628     TopoDS_Shape& f = it.Value();
629     Standard_Boolean of1,of2; FUNBUILD_ANCESTORRANKGET(B,f,of1,of2);
630     TopAbs_Orientation orif = f.Orientation();
631     Standard_Boolean r12 = B.Reverse(TB1,TB2); Standard_Boolean r21 = B.Reverse(TB2,TB1);
632     Standard_Boolean rf = Standard_False;
633     if      (of1 && !of2) rf = r12;
634     else if (of2 && !of1) rf = r21;
635     TopAbs_Orientation neworif = B.Orient(orif,rf);
636     f.Orientation(neworif);
637   }
638 }
639
640 Standard_EXPORT Standard_Boolean GLOBAL_revownsplfacori = Standard_False;
641 // GLOBAL_REVerseOWNSPLittedFACeORIentation = True : dans GSplitFaceSFS on 
642 // applique le retournement d'orientation de la face splittee FS de F 
643 // a l'orientation de FS elle-meme (au lieu de l'appliquer a l'orientation 
644 // de la face F comme en standard)
645
646 //Standard_IMPORT extern TopTools_DataMapOfShapeInteger* GLOBAL_SplitAnc; //xpu260598
647 Standard_EXPORTEXTERN TopTools_DataMapOfShapeInteger* GLOBAL_SplitAnc; //xpu260598
648 //static TopAbs_Orientation FUN_intTOori(const Standard_Integer Iori) 
649 //{
650 //  if (Iori == 1)  return TopAbs_FORWARD;
651 //  if (Iori == 2)  return TopAbs_REVERSED;
652 //  if (Iori == 11) return TopAbs_INTERNAL;
653 //  if (Iori == 22) return TopAbs_EXTERNAL;
654 //  return TopAbs_EXTERNAL;
655 //}
656
657 //Standard_IMPORT extern TopTools_ListOfShape* GLOBAL_lfr1;
658 Standard_EXPORTEXTERN TopTools_ListOfShape* GLOBAL_lfr1;
659 //Standard_IMPORT extern Standard_Boolean GLOBAL_lfrtoprocess;
660 Standard_EXPORTEXTERN Standard_Boolean GLOBAL_lfrtoprocess;
661
662 //=======================================================================
663 //function : GSplitFaceSFS
664 //purpose  : 
665 //=======================================================================
666 void TopOpeBRepBuild_Builder::GSplitFaceSFS
667 (const TopoDS_Shape& FOR,const TopTools_ListOfShape& LSclass,const TopOpeBRepBuild_GTopo& G1,
668  TopOpeBRepBuild_ShellFaceSet& SFS)
669 {
670   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
671   Standard_Boolean RevOri1 = G1.IsToReverse1();
672   TopAbs_Orientation oriF = FOR.Orientation();
673   TopAbs_Orientation neworiF = Orient(oriF,RevOri1);
674   const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
675 #ifdef DEB
676   Standard_Integer iFOR =
677 #endif  
678              BDS.Shape(FOR);
679   
680 #ifdef DEB
681   Standard_Integer iiFOR; Standard_Boolean tSPS = GtraceSPS(FOR,iiFOR);
682   if(tSPS){
683     cout<<endl;
684     GdumpSHASTA(FOR,TB1,"--- GSplitFaceSFS ");cout<<" RevOri1 : "<<RevOri1<<endl;debsplitf(iFOR);
685   }
686 #endif  
687   
688   Standard_Boolean issplit = IsSplit(FOR,TB1);
689   if ( issplit ) {
690
691   // LOFS faces all have the same topological orientation.
692   // according to edge origin and operation performed, orientate them.
693   // NYI CDLize MapEdgeAncestors or modify WES in such a way
694   // that it memorizes edge ancestors of added elements.
695
696     TopTools_ListOfShape& LSF = ChangeSplit(FOR,TB1);
697     if ( GLOBAL_revownsplfacori ) {
698       FUNBUILD_ORIENTLOFS(*this,TB1,TB2,LSF);
699     }
700     for (TopTools_ListIteratorOfListOfShape it(LSF); it.More(); it.Next()) {
701       TopoDS_Shape newF = it.Value(); 
702       
703       if (GLOBAL_SplitAnc != NULL) {
704         Standard_Boolean hasoridef = GLOBAL_SplitAnc->IsBound(newF); //xpu260598
705         
706         Standard_Boolean opeFus = Opefus();
707         Standard_Boolean opec12 = Opec12();
708         Standard_Boolean opec21 = Opec21();
709         Standard_Boolean opeCut = opec12 || opec21;
710         Standard_Boolean opeCom = Opecom();
711         
712         if (hasoridef) {
713           Standard_Integer iAnc = GLOBAL_SplitAnc->Find(newF); 
714
715           Standard_Integer rkAnc = BDS.AncestorRank(iAnc);
716           TopAbs_Orientation oAnc = BDS.Shape(iAnc).Orientation(); 
717 #ifdef DEB
718           Standard_Integer iFanc; Standard_Boolean tSPSa = GtraceSPS(BDS.Shape(iAnc),iFanc);
719           if (tSPSa) debspanc(iAnc);
720 #endif    
721           if      (opeCom) {
722             // xpu260598 : orifspIN = orifanc 
723             //  bcl1;bcl2 tspIN(f23) is splitIN(f23), f9 SDDO f23       
724             neworiF = oAnc;
725           }
726           else if (opeCut) {
727             // xpu280598 : cto100G1 spIN(f21)
728             TopAbs_State TBAnc = TopAbs_UNKNOWN; 
729             if (opec12) TBAnc = (rkAnc == 1)? TopAbs_OUT : TopAbs_IN;
730             if (opec21) TBAnc = (rkAnc == 2)? TopAbs_OUT : TopAbs_IN;
731             
732             // if TBAnc == OUT : we keep orientation
733             // else              we reverse it
734             if (TBAnc == TopAbs_OUT) neworiF = oAnc;
735             else                     neworiF = TopAbs::Complement(oAnc);
736           }
737           else if (opeFus) {
738             neworiF = oAnc; //xpu290598     
739           }
740
741           Standard_Boolean reverse = Standard_False;
742           Standard_Integer irefAnc = BDS.SameDomainRef(iAnc);
743           if (irefAnc != iAnc) { // newFace is built on geometry of refAnc
744             Standard_Boolean samegeom=Standard_False;
745             TopOpeBRepDS_Config cAnc = BDS.SameDomainOri(iAnc);
746             if      (cAnc == TopOpeBRepDS_SAMEORIENTED) samegeom = Standard_True;
747             else if (cAnc == TopOpeBRepDS_DIFFORIENTED) samegeom = Standard_False;
748             TopAbs_Orientation orefAnc = BDS.Shape(irefAnc).Orientation();
749             if (oAnc != orefAnc) samegeom = !samegeom;
750             reverse = !samegeom;
751           }
752           if (reverse) neworiF = TopAbs::Complement(neworiF);
753
754         } // hasoridef
755       } 
756       
757       newF.Orientation(neworiF);
758
759       if (GLOBAL_lfrtoprocess) {
760         GLOBAL_lfr1->Append(newF);
761       }
762       else {
763 #ifdef DEB
764         if(tSPS){
765           DEBSHASET(ss,"--- GSplitFaceSFS ",SFS," AddStartElement SFS+ face ");  
766           GdumpSHA(newF,(Standard_Address)ss.ToCString());
767           cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 face ";
768           TopAbs::Print(neworiF,cout); cout<<endl;
769         }
770 #endif
771         
772         SFS.AddStartElement(newF);
773       }
774     }    
775   }
776   else {
777     // FOR n'a pas de devenir de Split par TB1
778     // on garde FOR si elle est situee TB1 / LSclass
779     Standard_Boolean add = Standard_True;
780     
781     Standard_Boolean hs = myDataStructure->HasShape(FOR);
782     Standard_Boolean hg = myDataStructure->HasGeometry(FOR);
783     Standard_Boolean testkeep = Standard_True;
784     testkeep = (hs && (!hg)); // +12/05 macktruck
785     
786     if (testkeep) { 
787       Standard_Boolean keep = GKeepShape(FOR,LSclass,TB1);
788       add = keep;
789     }
790     if (add) {
791       TopoDS_Shape F = FOR;
792       F.Orientation(neworiF);
793
794 #ifdef DEB
795       if(tSPS){
796         DEBSHASET(ss,"--- GSplitFaceSFS ",SFS," AddElement SFS+ face ");  
797         GdumpSHA(F,(Standard_Address)ss.ToCString());
798         cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 face ";
799         TopAbs::Print(neworiF,cout); cout<<endl;
800       }
801 #endif
802
803       SFS.AddElement(F);
804     }
805   }
806   
807 } // GSplitFaceSFS
808
809 //=======================================================================
810 //function : GMergeFaceSFS
811 //purpose  : (methode non utilisee)
812 //=======================================================================
813 void TopOpeBRepBuild_Builder::GMergeFaceSFS
814 (const TopoDS_Shape& FOR,const TopOpeBRepBuild_GTopo& G1,
815  TopOpeBRepBuild_ShellFaceSet& SFS)
816 {  
817 #ifdef DEB
818   Standard_Integer iFOR; Standard_Boolean tSPS = GtraceSPS(FOR,iFOR);
819   if(tSPS){
820     cout<<endl;
821     GdumpSHA(FOR, (char *) "--- GMergeFaceSFS ");
822     cout<<endl;
823   }
824 #endif
825   
826   Standard_Boolean tomerge = GToMerge(FOR);
827   if (!tomerge) return;
828   
829   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
830   Standard_Boolean RevOri1 = G1.IsToReverse1();
831   
832   TopAbs_Orientation oriF = FOR.Orientation();
833   TopAbs_Orientation neworiF = Orient(oriF,RevOri1);
834   
835   TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD);
836   
837   Standard_Boolean makecomsam = GTakeCommonOfSame(G1);
838   Standard_Boolean makecomdif = GTakeCommonOfDiff(G1);
839   if ( !makecomsam && !makecomdif) return;
840   
841   //LFSO,LFDO (samedom,sameori),(samedom,diffori) des 2 shapes peres
842   //LFSO1,LFDO1 (samedom,sameori),(samedom,diffori) du shape pere de F
843   //LFSO2,LFDO2 (samedom,sameori),(samedom,diffori) du shape != pere de F
844   TopTools_ListOfShape LFSO,LFDO,LFSO1,LFDO1,LFSO2,LFDO2;
845   GFindSamDomSODO(FF,LFSO,LFDO);
846   Standard_Integer rankF=GShapeRank(FF),rankX=(rankF)?((rankF==1)?2:1):0;
847   GFindSameRank(LFSO,rankF,LFSO1); GFindSameRank(LFDO,rankF,LFDO1);
848   GFindSameRank(LFSO,rankX,LFSO2); GFindSameRank(LFDO,rankX,LFDO2);
849   
850 #ifdef DEB
851   if(tSPS){
852     cout<<"--------- merge FACE "<<iFOR<<endl;
853     GdumpSAMDOM(LFSO1, (char *) "LFSO1 : "); 
854     GdumpSAMDOM(LFDO1, (char *) "LFDO1 : ");
855     GdumpSAMDOM(LFSO2, (char *) "LFSO2 : "); 
856     GdumpSAMDOM(LFDO2, (char *) "LFDO2 : ");
857   }
858 #endif
859   
860   Standard_Boolean performcom = Standard_False;
861   TopTools_ListOfShape *PtrLF1=NULL,*PtrLF2=NULL;
862   Standard_Integer n1=0,n2=0;
863   if      (makecomsam) { 
864     n1 = LFSO1.Extent(); n2 = LFSO2.Extent();
865     performcom = ( n1 != 0 && n2 != 0 );
866     if (performcom) { PtrLF1 = &LFSO1; PtrLF2 = &LFSO2; }
867   }
868   else if (makecomdif) { 
869     n1 = LFSO1.Extent(); n2 = LFDO2.Extent();
870     performcom = ( n1 != 0 && n2 != 0 );
871     if (performcom) { PtrLF1 = &LFSO1; PtrLF2 = &LFDO2; }
872   }
873   
874 #ifdef DEB
875   if(tSPS) {
876     cout<<"performcom : "<<performcom<<" ";
877     cout<<"makecomsam : "<<makecomsam<<" makcomdif : "<<makecomdif<<" ";
878     cout<<"n1 : "<<n1<<" n2 : "<<n2<<endl;
879     cout<<"GMergeFaceSFS RevOri1 : "<<RevOri1<<endl;
880   }
881 #endif
882   
883   if (performcom) {
884     TopOpeBRepBuild_GTopo gF;
885     if      (makecomsam) {
886       gF = TopOpeBRepBuild_GTool::GComUnsh(TopAbs_FACE,TopAbs_FACE);
887       gF.ChangeConfig(TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_SAMEORIENTED);
888     }
889     else if (makecomdif) {
890       gF = TopOpeBRepBuild_GTool::GComUnsh(TopAbs_FACE,TopAbs_FACE);
891       gF.ChangeConfig(TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_DIFFORIENTED);
892     }
893     
894     GMergeFaces(*PtrLF1,*PtrLF2,gF);
895     
896     // on prend le resultat du merge de F ssi F est HasSameDomain et
897     // qu'elle est la reference de ses faces SameDomain
898     Standard_Boolean addmerge = Standard_False;
899     Standard_Integer iFref = myDataStructure->SameDomainReference(FOR);
900     const TopoDS_Shape& Fref = myDataStructure->Shape(iFref);
901     Standard_Boolean Fisref = FOR.IsSame(Fref);
902     addmerge = Fisref;
903     
904     if ( addmerge ) {
905       const TopTools_ListOfShape& ME = Merged(FOR,TopAbs_IN);
906       for(TopTools_ListIteratorOfListOfShape it(ME);it.More();it.Next()) {
907         TopoDS_Shape newF = it.Value();
908         newF.Orientation(neworiF);
909
910 #ifdef DEB
911       if(tSPS){
912         DEBSHASET(ss,"--- GMergeFaceSFS ",SFS," AddStartElement SFS+ face ");  
913         GdumpSHA(newF,(Standard_Address)ss.ToCString());
914         cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 face ";
915         TopAbs::Print(neworiF,cout); cout<<endl;
916       }
917 #endif
918         SFS.AddStartElement(newF);
919       }
920     }
921   } // performcom
922   
923 #ifdef DEB
924   if(tSPS){cout<<"--------- end merge FACE "<<iFOR<<endl;}
925 #endif
926   
927 } // GMergeFaceSFS
928
929 static Standard_Boolean FUN_SplitEvisoONperiodicF(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Shape& FF)
930 {
931   const TopOpeBRepDS_ListOfInterference& LLI = HDS->DS().ShapeInterferences(FF);
932   if (LLI.Extent() == 0) return Standard_True;
933   TopOpeBRepDS_ListOfInterference LI;
934   TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LLI);     
935   for (; ILI.More(); ILI.Next() ) LI.Append(ILI.Value());
936
937   // LI3 = {I3 = (T(FACE),EG=EDGE,FS=FACE)}
938   TopOpeBRepDS_ListOfInterference LI1; Standard_Integer nIGtEDGE = FUN_selectGKinterference(LI,TopOpeBRepDS_EDGE,LI1);
939   if (nIGtEDGE < 1) return Standard_True;
940   TopOpeBRepDS_ListOfInterference LI2; Standard_Integer nIStFACE = FUN_selectSKinterference(LI1,TopOpeBRepDS_FACE,LI2);
941   if (nIStFACE < 1) return Standard_True;
942   TopOpeBRepDS_ListOfInterference LI3; Standard_Integer nITRASHAFACE = FUN_selectTRASHAinterference(LI2,TopAbs_FACE,LI3);
943   if (nITRASHAFACE < 1) return Standard_True;
944
945   Handle(TopOpeBRepDS_ShapeShapeInterference) SSI; 
946   ILI.Initialize(LI3);
947   for (; ILI.More(); ILI.Next() ) {
948
949     SSI = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(ILI.Value());
950     TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(SSI,GT,GI,ST,SI);
951       
952     const TopoDS_Face& FS = TopoDS::Face( HDS->Shape(SI)); 
953 #ifdef DEB
954     Standard_Integer iFS =
955 #endif
956               HDS->Shape(FS); 
957 //    Standard_Boolean FSper = FUN_periodicS(FS);
958     Standard_Boolean FSper = FUN_tool_closedS(FS);
959     if (!FSper) continue;
960     
961     const TopoDS_Edge& EG = TopoDS::Edge(HDS->Shape(GI));
962 #ifdef DEB
963     Standard_Integer iEG =
964 #endif
965               HDS->Shape(EG);    
966     Standard_Boolean isrest = HDS->DS().IsSectionEdge(EG);
967     if (!isrest) continue;
968     
969     // --------------------------------------------------
970     // <EG> has no representation on face <FS> yet, 
971     // set the pcurve on <FS>.
972     // --------------------------------------------------
973     Standard_Real pf,pl,tol;
974     Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(EG,FS,pf,pl,tol);
975     if (PC.IsNull()) {
976       TopoDS_Edge EEG = EG; Standard_Boolean ok = FUN_tool_pcurveonF(FS,EEG);
977       if (!ok) Standard_ProgramError::Raise("_Builder::SplitONVisolineonCyl");
978       Standard_Real f,l; PC = FC2D_CurveOnSurface(EEG,FS,f,l,tol);
979     }
980     
981     Standard_Boolean uiso,viso;gp_Dir2d d2d;gp_Pnt2d o2d; 
982     TopOpeBRepTool_TOOL::UVISO(PC,uiso,viso,d2d,o2d);
983     if (!viso) continue;
984     
985     // a. cylinders same domain on cylindrical face, with closing edges non same domain :
986     // the 2d rep. of an edge VisoLineOnCyl on the cylindrical face of the other shape 
987     // is not bounded in [0,2PI].
988     // b. cylinder + sphere interfering on the circular edge E (section edge) of the cylinder
989     // with the E's 2d rep on the spherical surface not bounded in [0,2PI] (cto 016 D*).
990     
991     // We have to split the edge at point (2PI,v), and we translate
992     // the split of u >= 2PI to have it in [0,2PI].
993       
994     TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
995     TopOpeBRepDS_ListOfInterference EPIlist; FUN_getEPIonEds(FS,HDS,EPIlist); 
996     TopOpeBRepDS_ListOfInterference loCPI;
997 #ifdef DEB
998     Standard_Boolean recadre =
999 #endif
1000                   FUN_EPIforEvisoONperiodicF(EG,FS,EPIlist, HDS,loCPI);
1001
1002     TopOpeBRepDS_ListOfInterference& lIEG = BDS.ChangeShapeInterferences(EG);
1003     lIEG.Append(loCPI);
1004     
1005 #ifdef DEB
1006     Standard_Boolean trc = TopOpeBRepDS_GettraceSTRANGE();
1007     if (trc) {cout<<"!! recadre is "; if (!recadre) cout<<"not ";
1008               cout<<"done on face FS "<<iFS<<" for edge "<<iEG<<endl;}
1009 #endif
1010   } // ILI
1011   return Standard_True;
1012 }
1013
1014 //=======================================================================
1015 //function : SplitEvisoONperiodicF
1016
1017 //purpose  : KPart for :
1018 //           - cylinders tangent on their cylindrical face,
1019 //           with closing edges not same domain,
1020 //           - cylinder + sphere interfering on the circular edge E (tangent
1021 //           to the spherical surface) of the cylinder with  :
1022 //           E's 2d rep on the spherical surface not bounded in [0,2PI]
1023 //            (cto 016 D*).
1024
1025 //           Adding EPI to split edges with pcurve on <F> a Visoline not 
1026 //           U-bounded in [0,2PI].
1027 // modifies : myDataStructure
1028 //            Scans among the interferences attached to faces for FEI with
1029 //            support <FS> = cylinder, geometry <EG>; adds pcurve on <FS> 
1030 //            for edge <EG> if necessay.
1031 //=======================================================================
1032 void TopOpeBRepBuild_Builder::SplitEvisoONperiodicF()
1033 {
1034 //  myEsplitsONcycy.Clear();
1035   Standard_Integer nsha = myDataStructure->NbShapes();
1036   for (Standard_Integer i = 1; i <= nsha; i++) {
1037     const TopoDS_Shape& FOR = myDataStructure->Shape(i);
1038     Standard_Boolean isface = (FOR.ShapeType() == TopAbs_FACE);
1039     if (!isface) continue;
1040
1041     TopLoc_Location loc; const Handle(Geom_Surface)& S = BRep_Tool::Surface(TopoDS::Face(FOR),loc);
1042     Standard_Boolean periodic = S->IsUPeriodic() || S->IsVPeriodic();
1043     if (!periodic) continue;
1044
1045     TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD);
1046     
1047     Standard_Boolean ok = FUN_SplitEvisoONperiodicF(myDataStructure,FF);
1048     if (!ok) Standard_ProgramError::Raise("_Builder::SplitONVisolineonCyl");
1049   } // i
1050 }
1051
1052 //=======================================================================
1053 //function : GSplitFace
1054 //purpose  : 
1055 //=======================================================================
1056 void TopOpeBRepBuild_Builder::GSplitFace
1057 (const TopoDS_Shape& FOR,const TopOpeBRepBuild_GTopo& GG1,const TopTools_ListOfShape& LSclass)
1058 {
1059   TopOpeBRepBuild_GTopo G1 = GG1;
1060   Standard_Boolean RevOri = Standard_False; 
1061   G1.SetReverse(RevOri);
1062   
1063   TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
1064   TopAbs_ShapeEnum t1,t2; G1.Type(t1,t2);
1065   
1066   // work on a FORWARD face <FForward>
1067   TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD);
1068   
1069 #ifdef DEB
1070   Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(FOR,iF);
1071   if(tSPS){
1072     cout<<endl;GdumpSHASTA(FOR,TB1,"--- GSplitFace ");
1073     cout<<endl;debsplitf(iF);
1074   }
1075 #endif
1076   
1077   // make a WireEdgeSet WES on face FF
1078   TopOpeBRepBuild_WireEdgeSet WES(FF,this);
1079   
1080   // Add ON parts (edges ON solid)
1081   GFillONPartsWES(FOR,G1,LSclass,WES);
1082 #ifdef DEB
1083   Standard_Integer n0 = WES.StartElements().Extent();
1084   if(tSPS) cout <<"--> GSplitFace , after GFillONPartsWES nstartelWES = "<<n0<<endl; 
1085 #endif
1086
1087   // save these edges
1088   TopTools_ListOfShape anEdgesON;
1089   TopTools_ListIteratorOfListOfShape it;
1090   if (myProcessON) {
1091     Standard_Boolean toRevOri = Opefus();
1092     for (it.Initialize(WES.StartElements()); it.More(); it.Next())
1093       anEdgesON.Append(toRevOri ? it.Value().Reversed() : it.Value());
1094     myONElemMap.Clear();
1095   }
1096   
1097   // split the edges of FF : add split edges to WES
1098   GFillFaceWES(FF,LSclass,G1,WES);
1099   Standard_Integer n1 = WES.StartElements().Extent();
1100 #ifdef DEB
1101   if(tSPS) cout <<"--> GSplitFace , after GFillFaceWES nstartelWES = "<<n1<<endl; 
1102 #endif
1103   
1104   // add edges built on curves supported by FF
1105   GFillCurveTopologyWES(FF,G1,WES);
1106   Standard_Integer n2 = WES.StartElements().Extent();
1107 #ifdef DEB
1108   if(tSPS) cout <<"--> GSplitFace , after GFillCurveTopologyWES nstartelWES = "<<n2<<endl; 
1109 #endif
1110   
1111   // myEdgeAvoid = StartElement edges of WES due to GFillCurveTopologyWES
1112   myEdgeAvoid.Clear();
1113   GCopyList(WES.StartElements(),(n1+1),n2,myEdgeAvoid);
1114
1115   // mark FF as split TB1
1116   MarkSplit(FF,TB1);
1117   
1118   // build the new faces LOF on FF from the Wire/Edge set WES
1119   TopTools_ListOfShape LOF;
1120   GWESMakeFaces(FF,WES,LOF);
1121
1122   if (myProcessON && (!anEdgesON.IsEmpty() || !myONElemMap.IsEmpty())) {
1123     // try to make patches with only ON parts.
1124     // prepare the map of used edges to not take the same matter two times
1125     TopTools_IndexedMapOfOrientedShape aMapOE;
1126     for (it.Initialize(LOF); it.More(); it.Next())
1127       for (TopExp_Explorer ex(it.Value(),TopAbs_EDGE); ex.More(); ex.Next())
1128         aMapOE.Add(ex.Current());
1129
1130     FillOnPatches(anEdgesON,FOR,aMapOE);
1131     myONElemMap.Clear();
1132   }
1133
1134   // LOFS : LOF faces located TB1 / LSclass = split faces of state TB1 of FF
1135   TopTools_ListOfShape& LOFS = ChangeSplit(FF,TB1);
1136   LOFS.Clear();
1137   GKeepShapes(FF,myEmptyShapeList,TB1,LOF,LOFS);
1138   
1139 } // GSplitFace
1140
1141 //=======================================================================
1142 //function : AddOnPatchesSFS
1143 //purpose  : 
1144 //=======================================================================
1145
1146 void TopOpeBRepBuild_Builder::AddONPatchesSFS(const TopOpeBRepBuild_GTopo& G1,
1147                                               TopOpeBRepBuild_ShellFaceSet& SFS)
1148 {
1149   // select ON faces not same domain to make patches
1150   const Standard_Real scalMin = 0.999847695; // cos(PI/180)
1151
1152   // iterate on faces from the first shape
1153   Standard_Integer i,j;
1154   for (i=1; i <= myONFacesMap.Extent(); i++) {
1155     const TopoDS_Shape& aFAnc1 = myONFacesMap(i);
1156     if (myDataStructure->DS().AncestorRank(aFAnc1) == 1) {
1157       const TopoDS_Face& aFace1 = TopoDS::Face(myONFacesMap.FindKey(i));
1158       // map edges of the first face
1159       TopTools_IndexedMapOfShape aMapE1;
1160       TopExp::MapShapes(aFace1, TopAbs_EDGE, aMapE1);
1161       // find a non-degenerated edge
1162       TopoDS_Edge aChkEdge;
1163       Standard_Integer k;
1164       for (k=1; k <= aMapE1.Extent() && aChkEdge.IsNull(); k++) {
1165         const TopoDS_Edge& aE = TopoDS::Edge(aMapE1(k));
1166         if (!BRep_Tool::Degenerated(aE))
1167           aChkEdge = aE;
1168       }
1169       if (aChkEdge.IsNull()) continue;
1170       // find a point and a normal
1171       BRepAdaptor_Curve2d aBAC1(aChkEdge, aFace1);
1172       gp_Pnt2d aP2d;
1173       const Standard_Real PAR_T = 0.456321;
1174       Standard_Real par = aBAC1.FirstParameter()*(1.-PAR_T) +
1175                           aBAC1.LastParameter() * PAR_T;
1176       aBAC1.D0(par, aP2d);
1177       BRepAdaptor_Surface aBAS1(aFace1);
1178       gp_Pnt aPbid;
1179       gp_Vec aN1,aDU,aDV;
1180       aBAS1.D1(aP2d.X(),aP2d.Y(),aPbid,aDU,aDV);
1181       aN1 = aDU ^ aDV;
1182       Standard_Real norm = aN1.Magnitude();
1183       if (norm < Precision::Confusion()) continue;
1184       aN1 /= norm;
1185       if (aFace1.Orientation() == TopAbs_REVERSED)
1186         aN1.Reverse();
1187
1188       // iterate on faces from the second shape
1189       Standard_Boolean ok = Standard_True;
1190       for (j=i+1; j <= myONFacesMap.Extent() && ok; j++) {
1191         const TopoDS_Shape& aFAnc2 = myONFacesMap(j);
1192         if (myDataStructure->DS().AncestorRank(aFAnc2) == 2) {
1193           const TopoDS_Face& aFace2 = TopoDS::Face(myONFacesMap.FindKey(j));
1194
1195           // check that the second face has the same boundaries
1196           TopTools_IndexedMapOfShape aMapE2;
1197           TopExp::MapShapes(aFace2, TopAbs_EDGE, aMapE2);
1198           if (aMapE1.Extent() != aMapE2.Extent()) continue;
1199           Standard_Boolean sameBnd = Standard_True;
1200           for (k=1; k <= aMapE2.Extent() && sameBnd; k++)
1201             if (!aMapE1.Contains(aMapE2(k)))
1202               sameBnd = Standard_False;
1203           if (!sameBnd) continue;
1204
1205           // check if it is needed to have a patch here;
1206           // for that the normals should be oriented in the same sense.
1207           BRepAdaptor_Curve2d aBAC2(aChkEdge, aFace2);
1208           aBAC2.D0(par,aP2d);
1209           BRepAdaptor_Surface aBAS2(aFace2);
1210           gp_Vec aN2;
1211           aBAS2.D1(aP2d.X(),aP2d.Y(),aPbid,aDU,aDV);
1212           aN2 = aDU ^ aDV;
1213           norm = aN2.Magnitude();
1214           if (norm < Precision::Confusion()) {
1215             ok = Standard_False;
1216             continue;
1217           }
1218           aN2 /= norm;
1219           if (aFace2.Orientation() == TopAbs_REVERSED)
1220             aN2.Reverse();
1221           Standard_Real scal = aN1 * aN2;
1222           if (scal < scalMin) {
1223             ok = Standard_False;
1224             continue;
1225           }
1226
1227           // select one of the two faces
1228           Standard_Boolean takeFirst = Standard_True;
1229           TopoDS_Face aPatch;
1230           TopAbs_Orientation neworiF;
1231           if (takeFirst) {
1232             aPatch = aFace1;
1233             neworiF = Orient(aFAnc1.Orientation(), G1.IsToReverse1());
1234           }
1235           else {
1236             aPatch = aFace2;
1237             neworiF = Orient(aFAnc2.Orientation(), G1.IsToReverse2());
1238           }
1239           aPatch.Orientation(neworiF);
1240
1241           // add patch to SFS
1242           SFS.AddStartElement(aPatch);
1243
1244           // save ON splits
1245           MarkSplit(aFAnc1,TopAbs_ON);
1246           TopTools_ListOfShape& aLOFS1 = ChangeSplit(aFAnc1,TopAbs_ON);
1247           aLOFS1.Append(aFace1);
1248           MarkSplit(aFAnc2,TopAbs_ON);
1249           TopTools_ListOfShape& aLOFS2 = ChangeSplit(aFAnc2,TopAbs_ON);
1250           aLOFS2.Append(aFace2);
1251         }
1252       }
1253     }
1254   }
1255 }
1256
1257 //=======================================================================
1258 //function : AreFacesCoincideInArea
1259 //purpose  : 
1260 //=======================================================================
1261
1262 static Standard_Boolean AreFacesCoincideInArea (const TopoDS_Shape& theBaseFace,
1263                                                 const TopoDS_Shape& theFace,
1264                                                 const TopoDS_Shape& theEdge,
1265                                                 const TopTools_ListOfShape& allEdges,
1266                                                 Standard_Boolean& isSameOri)
1267 {
1268   // there are given:
1269   // theBaseFace, theFace - possibly coinciding faces;
1270   // allEdges - the edges lying on theBaseFace forming the new boundary loops,
1271   //            they determine the areas of coincidence;
1272   // theEdge - an edge from allEdges pointing to the area to check in.
1273   // we should check that the faces are coincide in this area and have 
1274   // the same orientation considering the orientations of the faces.
1275
1276   TopAbs_Orientation anEdgeOri = theEdge.Orientation();
1277   if (anEdgeOri != TopAbs_FORWARD && anEdgeOri != TopAbs_REVERSED)
1278     return Standard_False;
1279   Standard_Boolean reverse = (anEdgeOri == TopAbs_REVERSED);
1280
1281   TopoDS_Face aBaseFace = TopoDS::Face(theBaseFace);
1282   TopoDS_Face aFace = TopoDS::Face(theFace);
1283   TopoDS_Edge anEdge = TopoDS::Edge(theEdge);
1284   BRep_Builder BB;
1285
1286   // create a ray from the inside of anEdge to the matter side
1287   Standard_Real pf,pl,tol;
1288   Standard_Boolean trim3d = Standard_True;
1289   Handle(Geom2d_Curve) PCref = BRep_Tool::CurveOnSurface(anEdge,aBaseFace,pf,pl);
1290   if (PCref.IsNull()) {
1291     PCref = FC2D_CurveOnSurface(anEdge,aBaseFace,pf,pl,tol,trim3d);
1292     if (PCref.IsNull()) return Standard_False;
1293     tol = BRep_Tool::Tolerance(anEdge);
1294     BB.UpdateEdge(anEdge,PCref,aBaseFace,tol);
1295   }
1296
1297   const Standard_Real T = 0.456789;
1298   Standard_Real pm = (1.-T)*pf + T*pl;
1299   gp_Pnt2d pt; gp_Vec2d d1;
1300   PCref->D1(pm, pt, d1);
1301   if (d1.Magnitude() < gp::Resolution())
1302     return Standard_False;
1303   if (reverse) d1.Reverse();
1304   gp_Vec2d vecInside(-d1.Y(),d1.X());
1305   gp_Lin2d aLin(pt,vecInside);
1306
1307   // find the nearest intersection of aLin with other edges
1308   Standard_Boolean hasInt = Standard_False;
1309   Standard_Real pLinMin = RealLast();
1310   Standard_Real tol2d = Precision::PConfusion();
1311   BRepClass_Intersector anInter;
1312   BRepClass_Edge aBCE;
1313   aBCE.Face() = aBaseFace;
1314   Standard_Real maxDist = Max (BRep_Tool::Tolerance(aBaseFace),
1315                                BRep_Tool::Tolerance(aFace));
1316
1317   Standard_Boolean isError = Standard_False;
1318   TopTools_ListIteratorOfListOfShape it(allEdges);
1319   for (; it.More() && !isError; it.Next()) {
1320     const TopoDS_Edge& aE = TopoDS::Edge(it.Value());
1321     Standard_Real tolE = BRep_Tool::Tolerance(aE);
1322     if (tolE > maxDist) maxDist = tolE;
1323     if (aE.IsEqual(anEdge) ||
1324         (aE.Orientation() != TopAbs_FORWARD && 
1325          aE.Orientation() != TopAbs_REVERSED &&
1326          aE.IsSame(anEdge)))
1327       continue;         // the same pcurve
1328     Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(aE,aBaseFace,pf,pl);
1329     if (PC.IsNull()) {
1330       PC = FC2D_CurveOnSurface(aE,aBaseFace,pf,pl,tol,trim3d);
1331       if (PC.IsNull()) {isError = Standard_True; break;}
1332       BB.UpdateEdge(aE,PC,aBaseFace,tolE);
1333     }
1334     aBCE.Edge() = aE;
1335     anInter.Perform(aLin,pLinMin,tol2d,aBCE);
1336     if (anInter.IsDone()) {
1337       Standard_Integer i;
1338       for (i=1; i <= anInter.NbPoints(); i++) {
1339         const IntRes2d_IntersectionPoint& aIP = anInter.Point(i);
1340         Standard_Real pLin = aIP.ParamOnFirst();
1341         if (pLin > tol2d && pLin < pLinMin) {
1342           pLinMin = pLin;
1343           hasInt = Standard_True;
1344         }
1345       }
1346       for (i=1; i <= anInter.NbSegments() && !isError; i++) {
1347         const IntRes2d_IntersectionSegment& aIS = anInter.Segment(i);
1348         Standard_Real pLinF = aIS.HasFirstPoint() ? aIS.FirstPoint().ParamOnFirst()
1349           : -Precision::Infinite();
1350         Standard_Real pLinL = aIS.HasLastPoint() ? aIS.LastPoint().ParamOnFirst()
1351           : Precision::Infinite();
1352         if (pLinF < tol2d && pLinL > -tol2d) isError = Standard_True;
1353         else if (pLinF > tol2d && pLinF < pLinMin) {
1354           pLinMin = pLinF;
1355           hasInt = Standard_True;
1356         }
1357       }
1358     }
1359   }
1360   if (isError || !hasInt) return Standard_False;
1361
1362   // create a point in the area and get the normal to aBaseFace at it
1363   gp_Pnt2d aP2d = ElCLib::Value(pLinMin*T,aLin);
1364   BRepAdaptor_Surface aBAS(aBaseFace);
1365   gp_Pnt aPnt; gp_Vec d1u,d1v;
1366   aBAS.D1(aP2d.X(),aP2d.Y(),aPnt,d1u,d1v);
1367   gp_Vec aNormBase = d1u ^ d1v;
1368   Standard_Real mag = aNormBase.Magnitude();
1369   if (mag < gp::Resolution()) return Standard_False;
1370   if (aBaseFace.Orientation() == TopAbs_REVERSED) mag = -mag;
1371   aNormBase /= mag;
1372
1373   // project the point aPnt to the second face aFace
1374   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
1375   Standard_Real umin,umax,vmin,vmax;
1376   BRepTools::UVBounds(aFace,umin,umax,vmin,vmax);
1377   GeomAPI_ProjectPointOnSurf aProj(aPnt,aSurf,umin,umax,vmin,vmax);
1378   if (!aProj.NbPoints() || aProj.LowerDistance() > maxDist) return Standard_False;
1379   Standard_Real u,v;
1380   aProj.LowerDistanceParameters(u,v);
1381   aSurf->D1(u,v,aPnt,d1u,d1v);
1382   gp_Vec aNorm = d1u ^ d1v;
1383   mag = aNorm.Magnitude();
1384   if (mag < gp::Resolution()) return Standard_False;
1385   if (aFace.Orientation() == TopAbs_REVERSED) mag = -mag;
1386   aNorm /= mag;
1387
1388   // check normales
1389   Standard_Real dot = aNormBase * aNorm;
1390   const Standard_Real minDot = 0.9999;
1391   if (Abs(dot) < minDot) return Standard_False;
1392   isSameOri = (dot > 0.);
1393
1394   return Standard_True;
1395 }
1396
1397 //=======================================================================
1398 //function : FillOnPatches
1399 //purpose  : 
1400 //=======================================================================
1401
1402 void TopOpeBRepBuild_Builder::FillOnPatches
1403   (const TopTools_ListOfShape& anEdgesON,
1404    const TopoDS_Shape& aBaseFace,
1405    const TopTools_IndexedMapOfOrientedShape& avoidMap)
1406 {
1407   TopoDS_Shape FF = aBaseFace; FF.Orientation(TopAbs_FORWARD);
1408   Standard_Integer rankBF = ShapeRank(aBaseFace);
1409   Standard_Integer rankOpp;
1410   if      (rankBF == 1) rankOpp = 2;
1411   else if (rankBF == 2) rankOpp = 1;
1412   else return;
1413
1414   TopOpeBRepBuild_WireEdgeSet WES(FF,this);
1415   TopTools_MapOfShape aMapON,aMapON1;
1416   TopTools_DataMapOfShapeInteger aMapFState;
1417
1418   TopTools_ListOfShape allEdges;
1419   TopTools_ListIteratorOfListOfShape it;
1420   TopoDS_Iterator itW;
1421   for (it.Initialize(anEdgesON); it.More(); it.Next()) {
1422     const TopoDS_Shape& aE = it.Value();
1423     // is it a part of the boundary of aBaseFace ?
1424     if (!myONElemMap.Contains(aE) && !myONElemMap.Contains(aE.Reversed()) &&
1425         !avoidMap.Contains(aE)) {
1426       allEdges.Append(aE);
1427       aMapON.Add(aE);
1428     }
1429   }
1430   Standard_Integer i;
1431   Standard_Boolean hasWires = Standard_False;
1432   for (i=1; i <= myONElemMap.Extent(); i++) {
1433     const TopoDS_Shape& aE = myONElemMap(i);
1434     if (aE.ShapeType() == TopAbs_WIRE) {
1435       for (itW.Initialize(aE); itW.More(); itW.Next())
1436         if (!avoidMap.Contains(itW.Value())) {
1437           allEdges.Append(itW.Value());
1438           hasWires = Standard_True;
1439         }
1440     }
1441     else if (!avoidMap.Contains(aE)) {
1442       allEdges.Append(aE);
1443       aMapON1.Add(aE);
1444     }
1445   }
1446
1447   // +++
1448   // add elements from anEdgesON (they come from BuilderON)
1449   TopTools_DataMapOfShapeShape anAncMap;
1450   if (!aMapON.IsEmpty())
1451     FillSecEdgeAncestorMap(rankOpp,aMapON,anAncMap);
1452   if (!anAncMap.IsEmpty()) {
1453     for (it.Initialize(anEdgesON); it.More(); it.Next()) {
1454       const TopoDS_Shape& aE = it.Value();         // an ON part
1455       if (anAncMap.IsBound(aE) && !avoidMap.Contains(aE)) {
1456         const TopoDS_Shape& anAncE = anAncMap(aE); // its ancestor edge from opposite shape
1457         const TopTools_ListOfShape& aFaces =       // connex faces of anAncE
1458           FDSCNX_EdgeConnexityShapeIndex (anAncE,myDataStructure,rankOpp);
1459         // determine if aBaseFace has coinciding part on the left side of aE
1460         // with one of connex faces, and this pair of faces are same oriented
1461         Standard_Boolean isOnFace = Standard_False;
1462         TopTools_ListOfShape aFacesToCheck;
1463         TopTools_ListIteratorOfListOfShape itF;
1464         for (itF.Initialize(aFaces); itF.More() && !isOnFace; itF.Next()) {
1465           const TopoDS_Shape& aF = itF.Value();
1466           if (aMapFState.IsBound(aF)) {
1467             Standard_Integer state = aMapFState(aF);
1468             if (state) isOnFace = Standard_True;
1469           }
1470           else aFacesToCheck.Append(aF);
1471         }
1472         for (itF.Initialize(aFacesToCheck); itF.More() && !isOnFace; itF.Next()) {
1473           const TopoDS_Shape& aF = itF.Value();
1474           Standard_Boolean isSameOri = Standard_False;
1475           Standard_Boolean ok;
1476           if (aE.Orientation() != TopAbs_FORWARD && aE.Orientation() != TopAbs_REVERSED) {
1477             ok = AreFacesCoincideInArea(aBaseFace,aF,aE.Oriented(TopAbs_FORWARD),
1478                                         allEdges,isSameOri);
1479             ok = ok || AreFacesCoincideInArea(aBaseFace,aF,aE.Oriented(TopAbs_REVERSED),
1480                                         allEdges,isSameOri);
1481           }
1482           else
1483             ok = AreFacesCoincideInArea(aBaseFace,aF,aE, allEdges,isSameOri);
1484           if (ok && isSameOri) {
1485             aMapFState.Bind(aF,1);
1486             isOnFace = Standard_True;
1487           }
1488           else aMapFState.Bind(aF,0);
1489         }
1490         if (isOnFace)
1491           WES.AddStartElement(aE);
1492       }
1493     }
1494   }
1495
1496   // +++
1497   // add elements from myONElemMap (consisting of parts of the boundary of aBaseFace)
1498   anAncMap.Clear();
1499   if (!aMapON1.IsEmpty())
1500     FillSecEdgeAncestorMap(rankBF,aMapON1,anAncMap);
1501   if (hasWires || !anAncMap.IsEmpty()) {
1502     for (i=1; i <= myONElemMap.Extent(); i++) {
1503       const TopoDS_Shape& aE = myONElemMap(i);
1504       TopoDS_Shape anEdge, anAncE;
1505       if (aE.ShapeType() == TopAbs_WIRE) {
1506         // for a wire get one non-degenerated edge for test
1507         for (itW.Initialize(aE); itW.More() && anEdge.IsNull(); itW.Next()) {
1508           const TopoDS_Edge& e = TopoDS::Edge(itW.Value());
1509           if (avoidMap.Contains(e)) break;
1510           if (!BRep_Tool::Degenerated(e))
1511             anEdge = anAncE = e;
1512         }
1513       }
1514       else if (anAncMap.IsBound(aE) && !avoidMap.Contains(aE)) {
1515         anEdge = aE;
1516         anAncE = anAncMap(aE);
1517       }
1518       if (!anEdge.IsNull()) {
1519         // find faces of the opposite shape touching anAncE
1520         TopTools_ListOfShape aFaces;
1521         FDSCNX_FaceEdgeConnexFaces (aBaseFace,anAncE,myDataStructure,aFaces);
1522         if (aFaces.IsEmpty()) continue;
1523         TopoDS_Shape aCnxF = aFaces.First();
1524         aFaces.Clear();
1525         FindFacesTouchingEdge (aCnxF,anAncE,rankOpp,aFaces);
1526         // determine if aBaseFace has coinciding part on the left side of anEdge
1527         // with one of found faces, and this pair of faces are same oriented
1528         Standard_Boolean isOnFace = Standard_False;
1529         TopTools_ListOfShape aFacesToCheck;
1530         TopTools_ListIteratorOfListOfShape itF;
1531         for (itF.Initialize(aFaces); itF.More() && !isOnFace; itF.Next()) {
1532           const TopoDS_Shape& aF = itF.Value();
1533           if (aMapFState.IsBound(aF)) {
1534             Standard_Integer state = aMapFState(aF);
1535             if (state) isOnFace = Standard_True;
1536           }
1537           else aFacesToCheck.Append(aF);
1538         }
1539         for (itF.Initialize(aFacesToCheck); itF.More() && !isOnFace; itF.Next()) {
1540           const TopoDS_Shape& aF = itF.Value();
1541           Standard_Boolean isSameOri = Standard_False;
1542           Standard_Boolean ok =
1543             AreFacesCoincideInArea (aBaseFace,aF,anEdge,allEdges,isSameOri);
1544           if (ok && isSameOri) {
1545             aMapFState.Bind(aF,1);
1546             isOnFace = Standard_True;
1547           }
1548           else aMapFState.Bind(aF,0);
1549         }
1550         if (isOnFace) {
1551           if (aE.ShapeType() == TopAbs_WIRE)
1552             WES.AddShape(aE);
1553           else
1554             WES.AddStartElement(aE);
1555         }
1556       }
1557     }
1558   }
1559
1560   WES.InitShapes(); WES.InitStartElements();
1561   if (WES.MoreShapes() || WES.MoreStartElements()) {
1562     TopTools_ListOfShape LOF;
1563     GWESMakeFaces(FF,WES,LOF);
1564     // save ON faces
1565     for (it.Initialize(LOF); it.More(); it.Next()) {
1566       const TopoDS_Face& aF = TopoDS::Face(it.Value());
1567       myONFacesMap.Add(aF,aBaseFace);
1568     }
1569   }
1570 }
1571
1572 //=======================================================================
1573 //function : FindFacesTouchingEdge
1574 //purpose  : 
1575 //=======================================================================
1576
1577 void TopOpeBRepBuild_Builder::FindFacesTouchingEdge(const TopoDS_Shape& aFace,
1578                                                     const TopoDS_Shape& anEdge,
1579                                                     const Standard_Integer aShRank,
1580                                                     TopTools_ListOfShape& aFaces) const
1581 {
1582   const TopOpeBRepDS_DataStructure& BDS=myDataStructure->DS();
1583   Standard_Integer anEdgeInd = BDS.Shape(anEdge);
1584   if (!anEdgeInd) return;
1585
1586   const TopOpeBRepDS_ListOfInterference& LI=BDS.ShapeInterferences(aFace);
1587   TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI);
1588   for (;ILI.More();ILI.Next() ) {
1589     const Handle(TopOpeBRepDS_Interference)& I=ILI.Value();
1590     Handle(TopOpeBRepDS_ShapeShapeInterference) SSI=
1591       Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I);
1592     if (SSI.IsNull()) continue;
1593     TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(SSI,GT,GI,ST,SI);
1594     if (GT != TopOpeBRepDS_EDGE || ST != TopOpeBRepDS_FACE) continue;
1595     if (GI != anEdgeInd) continue;
1596     const TopOpeBRepDS_Transition& TFE=SSI->Transition();
1597     if (TFE.ShapeBefore() != TopAbs_FACE || TFE.ShapeAfter() != TopAbs_FACE) continue;
1598     const TopoDS_Shape& FS=BDS.Shape(SI);
1599     if (ShapeRank(FS) != aShRank) continue;
1600     aFaces.Append(FS);
1601   }
1602 }