Integration of OCCT 6.5.0 from SVN
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_makefaces.cxx
1  // file:       TopOpeBRepBuild_makefaces.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 <BRep_Builder.hxx>
9 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
10 #include <TopTools_IndexedMapOfOrientedShape.hxx>
11 #include <TopExp.hxx>
12 #include <TopoDS.hxx>
13 #include <TopoDS_Wire.hxx>
14 #include <TopoDS_Compound.hxx>
15 #include <BRep_Tool.hxx>
16 #include <BRepTools.hxx>
17 #include <GeomAdaptor_Surface.hxx>
18 #include <GeomAbs_SurfaceType.hxx>
19 #include <Geom_Surface.hxx>
20 #include <Geom_RectangularTrimmedSurface.hxx>
21 #include <Geom2d_Curve.hxx>
22 #include <Standard_ProgramError.hxx>
23 #include <TopOpeBRepDS.hxx>
24 #include <TopOpeBRepDS_EXPORT.hxx>
25 #include <TopOpeBRepTool.hxx>
26 #include <TopOpeBRepTool_EXPORT.hxx>
27 #include <TopOpeBRepBuild_define.hxx>
28 #include <TopOpeBRepTool_2d.hxx>
29
30
31 #ifdef DEB
32 Standard_EXPORT Standard_Boolean TopOpeBRepBuild_GetcontextNOPURGE();
33 Standard_EXPORT Standard_Boolean TopOpeBRepBuild_GetcontextNOCORRISO();
34 Standard_EXPORT Standard_Boolean TopOpeBRepBuild_GettraceCHK();
35 Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceSTRANGE();
36 #define DEBSHASET(sarg,meth,shaset,str) \
37 TCollection_AsciiString sarg((meth));(sarg)=(sarg)+(shaset).DEBNumber()+(str);
38 Standard_EXPORT void debgfabu(const Standard_Integer i) {cout<<"++ debgfabu "<<i<<endl;}
39 Standard_EXPORT void debwesmf(const Standard_Integer i) {cout<<"++ debwesmf "<<i<<endl;}
40 Standard_EXPORT Standard_Boolean DEBpurclo = Standard_False;
41 void debpurclo() {}
42 void debpurclomess(Standard_Integer i){cout<<"++ debpurclo "<<i<<endl;debpurclo();}
43 Standard_EXPORT void debcorriso(const Standard_Integer i) {cout<<"++ debcorriso "<<i<<endl;}
44 Standard_IMPORT void* GFABUMAKEFACEPWES_DEB;
45 #endif
46
47 #ifdef DRAW
48 #include <DBRep.hxx>
49 #include <TopOpeBRepTool_DRAW.hxx>
50 #endif
51
52 Standard_EXPORT Standard_Boolean FUN_tool_ClosedW(const TopoDS_Wire& W);
53 // Unused :
54 /*#ifdef DEB
55 static void FUN_Raise(){cout<<"--------- ERROR in GWESMakeFaces ---------"<<endl;}
56 #endif*/
57
58 //=======================================================================
59 //function : GWESMakeFaces
60 //purpose  : 
61 //=======================================================================
62 void TopOpeBRepBuild_Builder::GWESMakeFaces
63 (const TopoDS_Shape& FF,TopOpeBRepBuild_WireEdgeSet& WES,TopTools_ListOfShape& LOF)  
64 {
65 #ifdef DEB  
66   Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(FF,iF);
67   DEBSHASET(s,"#--- GWESMakeFaces ",WES," ");
68   if(tSPS){ GdumpSHA(FF,(Standard_Address)s.ToCString());cout<<endl; WES.DumpSS();}
69   if(tSPS){debwesmf(iF);}
70   GFABUMAKEFACEPWES_DEB = (void*)&WES;
71 #endif
72   
73   const Standard_Boolean ForceClass = Standard_True;
74   TopOpeBRepBuild_FaceBuilder FABU;
75   FABU.InitFaceBuilder(WES,FF,ForceClass);
76   
77   // Wire checking,the aim is to rebuild faces having
78   // edges unconnected to the others (in the face UV representation)
79   // This can occur when the face has a closing edge. To avoid this,
80   // we delete the lonesome closing edge from the wire.
81   Standard_Boolean topurge = Standard_True;
82 #ifdef DEB
83   if (TopOpeBRepBuild_GetcontextNOPURGE()) topurge = Standard_False;
84 #endif
85
86 #ifdef DRAW
87   Standard_Boolean traceF = Standard_False;
88   if (traceF) {
89     TopTools_IndexedMapOfShape mapW;
90     for (FABU.InitFace(); FABU.MoreFace(); FABU.NextFace()) {
91       for (FABU.InitWire(); FABU.MoreWire(); FABU.NextWire()) {      
92         TopoDS_Shape W;
93         Standard_Boolean isold = FABU.IsOldWire();
94         if (isold) W = FABU.OldWire();
95         else {
96           BRep_Builder BB;
97           TopoDS_Compound cmp; BB.MakeCompound(cmp);
98           FABU.InitEdge();
99           for (; FABU.MoreEdge(); FABU.NextEdge()) FABU.AddEdgeWire(FABU.Edge(),cmp);
100           W = cmp;
101         }
102         if (W.IsNull()) continue;
103         Standard_Integer iiwi = mapW.Add(W);    TCollection_AsciiString aa("wii_");FUN_tool_draw(aa,W,iiwi);
104       }
105     }
106   }
107 #endif
108   
109   if (topurge) {
110     TopOpeBRepDS_DataStructure& BDS = myDataStructure->ChangeDS();
111     
112     TopTools_IndexedMapOfShape mapPIE; // pseudo internal edges
113     FABU.DetectPseudoInternalEdge(mapPIE);
114
115     TopTools_IndexedDataMapOfShapeShape mapVVsameG,mapVon1Edge,mapVVref; 
116     FABU.DetectUnclosedWire(mapVVsameG,mapVon1Edge);
117     
118     Standard_Integer nVV = mapVVsameG.Extent();
119     if (nVV > 0) {
120       // Updating the DS with same domain vertices,
121       // filling up map <mapVVref>
122       for (Standard_Integer i = 1; i <= nVV; i++) {
123         const TopoDS_Shape& V = mapVVsameG.FindKey(i);
124         Standard_Boolean hsdm = myDataStructure->HasSameDomain(V);
125         if (!hsdm) {
126           Standard_Integer rankV = BDS.AncestorRank(V);
127           
128           const TopoDS_Shape& VsameG = mapVVsameG.FindFromIndex(i);
129
130           // MSV Oct 4, 2001: prefer old vertex as SameDomainReference
131           Standard_Integer rankVsameG = BDS.AncestorRank(VsameG);
132           Standard_Boolean otherRef = (rankVsameG != 0 && rankV != 1);
133
134           if (otherRef)
135             BDS.FillShapesSameDomain(VsameG,V);
136           else
137             BDS.FillShapesSameDomain(V,VsameG);
138
139           hsdm = myDataStructure->HasSameDomain(V);  
140         }
141         if (hsdm) {
142           Standard_Integer Iref = myDataStructure->SameDomainReference(V);
143           const TopoDS_Shape& Vref = myDataStructure->Shape(Iref);
144           mapVVref.Add(V,Vref);
145         }
146       }
147       FABU.CorrectGclosedWire(mapVVref,mapVon1Edge);
148       FABU.DetectUnclosedWire(mapVVsameG,mapVon1Edge);
149     }    
150   }
151     
152   TopTools_DataMapOfShapeInteger MWisOld;
153   TopTools_IndexedMapOfOrientedShape MshNOK;
154   GFABUMakeFaces(FF,FABU,LOF,MWisOld);
155   
156   // 2.  on periodic face F :
157   //   finds up faulty shapes MshNOK to avoid when building up shapes
158   //   (edge no longer closing that appears twice in the new face)
159
160   if (topurge) {
161
162 #ifdef DRAW
163     if (tSPS) {
164       cout<<endl<<"#<< AVANT PurgeClosingEdges "<<endl; 
165       GdumpFABU(FABU);
166       TopTools_ListOfShape dLOF;TopTools_DataMapOfShapeInteger dMWisOld;
167       GFABUMakeFaces(FF,FABU,dLOF,dMWisOld);
168       TopTools_ListIteratorOfListOfShape X(dLOF); for (Standard_Integer i=1;X.More();X.Next(),i++) {
169         TCollection_AsciiString ss("purclo");ss=ss+i;DBRep::Set(ss.ToCString(),X.Value());
170         cout<<"... face "<<ss<<endl;
171       }
172       debpurclomess(iF);
173       DEBpurclo = Standard_True;
174     }
175 #endif
176     
177     const TopoDS_Face& FA = TopoDS::Face(FF);
178     Standard_Boolean puok = TopOpeBRepTool::PurgeClosingEdges(FA,LOF,MWisOld,MshNOK);
179     if (!puok) Standard_Failure::Raise("TopOpeBRepBuild::GWESMakeFaces");
180     topurge = !MshNOK.IsEmpty();
181
182 #ifdef DEB
183     if (tSPS) DEBpurclo = Standard_False;
184 #endif
185   } // topurge
186
187   if (topurge) {
188     TopTools_ListOfShape LOFF;
189     Standard_Boolean puok = TopOpeBRepTool::MakeFaces(TopoDS::Face(FF),LOF,MshNOK,LOFF);
190     if (!puok) Standard_Failure::Raise("TopOpeBRepBuild::GWESMakeFaces");
191     LOF.Clear(); LOF.Assign(LOFF);
192   }
193
194   //1.  on periodic face F :
195   //  translates edge's pcurve to have it in F's UVbounds  
196   //  translates edge's pcurve to have it connexed to others in UV space 
197   Standard_Boolean corronISO = Standard_True;
198 #ifdef DEB
199   if (TopOpeBRepBuild_GetcontextNOCORRISO()) corronISO = Standard_False;
200   if (tSPS) debcorriso(iF);
201 #endif
202   Standard_Boolean ffcloseds = FUN_tool_closedS(FF);
203   corronISO = corronISO && ffcloseds;
204   if (corronISO) {
205     TopTools_ListIteratorOfListOfShape itFF(LOF);
206     TopTools_ListOfShape newLOF;
207     const TopoDS_Face& FFa = TopoDS::Face(FF);
208     for (; itFF.More(); itFF.Next()){
209       TopoDS_Face Fa = TopoDS::Face(itFF.Value());
210       TopOpeBRepTool::CorrectONUVISO(FFa,Fa);
211       newLOF.Append(Fa);
212     }
213     LOF.Clear(); LOF.Assign(newLOF);
214   }
215
216   // xpu280898 : regularisation after GFABUMakeFaces,purge processings
217   TopTools_ListOfShape newLOF; RegularizeFaces(FF,LOF,newLOF);
218   LOF.Clear(); LOF.Assign(newLOF);
219
220 } // GWESMakeFaces
221
222 //------------------------------------------------------
223 // retourne vrai si newFace contient une seule arete non orientee
224 //------------------------------------------------------
225 static Standard_Boolean FUN_purgeFon1nonoriE(const TopoDS_Shape& newFace)
226 {
227   TopExp_Explorer ex(newFace,TopAbs_EDGE);
228   Standard_Integer nE = 0;
229   for (; ex.More(); ex.Next()) nE++;
230   if (nE == 1) {
231     ex.Init(newFace,TopAbs_EDGE);
232     const TopoDS_Shape& ed = ex.Current();
233     TopAbs_Orientation ori = ed.Orientation();
234     Standard_Boolean hasori = (ori == TopAbs_FORWARD) || (ori == TopAbs_REVERSED);
235     if (!hasori) return Standard_True;
236     //// modified by jgv, 6.06.02 for OCC424 ////
237     TopoDS_Edge theEdge = TopoDS::Edge( ed );
238     if (BRep_Tool::Degenerated( theEdge ))
239       return Standard_True;
240     /////////////////////////////////////////////
241   }
242   return Standard_False;
243 }
244
245 //-- ofv --------------------------------------------------------------------
246 // function : FUN_ReOrientIntExtEdge
247 // purpose  : change orientation of INTERNAL (EXTERNAL) edge, if necessary 
248 //            FRE  - tool (edge with FORWARD or REVERSED orientation),
249 //            OFRE - orientation of tool (FORWARD or REVERSED),
250 //            INE  - object (edge with INTERNAL (EXTERNAL) orientation)
251 //---------------------------------------------------------------------------
252 static TopAbs_Orientation FUN_ReOrientIntExtEdge(const TopoDS_Edge& FRE,
253                                                  TopAbs_Orientation OFRE,
254                                                  const TopoDS_Edge& INE)
255 {
256   TopAbs_Orientation result = INE.Orientation();
257   TopoDS_Vertex Vf1,Vl1,Vf2,Vl2;
258
259   TopExp::Vertices(FRE, Vf1, Vl1, Standard_False);
260   TopExp::Vertices(INE, Vf2, Vl2, Standard_False);
261
262   if(OFRE == TopAbs_FORWARD)
263     {
264       if(Vl1.IsSame(Vf2)) result = TopAbs_FORWARD;
265       if(Vl1.IsSame(Vl2)) result = TopAbs_REVERSED;
266       if(Vf1.IsSame(Vf2)) result = TopAbs_REVERSED;
267       if(Vf1.IsSame(Vl2)) result = TopAbs_FORWARD;
268     }
269   if(OFRE == TopAbs_REVERSED)
270     {
271       if(Vl1.IsSame(Vf2)) result = TopAbs_REVERSED;
272       if(Vl1.IsSame(Vl2)) result = TopAbs_FORWARD;
273       if(Vf1.IsSame(Vf2)) result = TopAbs_FORWARD;
274       if(Vf1.IsSame(Vl2)) result = TopAbs_REVERSED;
275     }
276   return result;
277 }
278 //----------------------------------------------------------------------------
279
280 //-- ofv --------------------------------------------------------------------
281 // function : FUN_CheckORI
282 // purpose  :
283 //----------------------------------------------------------------------------
284 static Standard_Integer FUN_CheckORI(TopAbs_Orientation O1,
285                                      TopAbs_Orientation O2)
286 {
287   Standard_Integer result;
288   if((O1 == TopAbs_INTERNAL || O1 == TopAbs_EXTERNAL) && (O2 == TopAbs_INTERNAL || O2 == TopAbs_EXTERNAL)) result = 0;
289   else if((O1 == TopAbs_INTERNAL || O1 == TopAbs_EXTERNAL) && (O2 == TopAbs_FORWARD || O2 == TopAbs_REVERSED)) result = 1;
290   else if((O1 == TopAbs_FORWARD || O1 == TopAbs_REVERSED) && (O2 == TopAbs_INTERNAL || O2 == TopAbs_EXTERNAL)) result = 2;
291   else result = 4;
292   return result;
293 }
294 //----------------------------------------------------------------------------
295 //=======================================================================
296 //function : GFABUMakeFaces
297 //purpose  : 
298 //=======================================================================
299
300 void TopOpeBRepBuild_Builder::GFABUMakeFaces(const TopoDS_Shape& FF,TopOpeBRepBuild_FaceBuilder& FABU,
301                           TopTools_ListOfShape& LOF,TopTools_DataMapOfShapeInteger& MWisOld)
302 {
303 #ifdef DEB
304   Standard_Integer iF;Standard_Boolean tSPS=GtraceSPS(FF,iF);
305   if(tSPS) {
306     cout<<endl;GdumpSHA(FF,(char *) "#--- GFABUMakeFaces ");cout<<endl;
307     GdumpFABU(FABU);debgfabu(iF);
308   }
309   Standard_Boolean strange = TopOpeBRepDS_GettraceSTRANGE();
310 #endif
311   
312   TopTools_ListOfShape lnewFace;
313   TopoDS_Face newFace;
314   TopoDS_Wire newWire;
315   
316   TopLoc_Location Loc;
317   Handle(Geom_Surface) Surf = BRep_Tool::Surface(TopoDS::Face(FF),Loc);
318 // JYL : mise en // des 5 lignes suivantes pour reprendre la correction de DPF
319 //       du 29/07/1998
320 //  GeomAdaptor_Surface GAS1(Surf);
321 //  GeomAbs_SurfaceType tt1 = GAS1.GetType();
322 //  Handle(Standard_Type) T = Surf->DynamicType();
323 //  Standard_Boolean istrim = ( T == STANDARD_TYPE(Geom_RectangularTrimmedSurface) );
324 //  if ( istrim && tt1 == GeomAbs_Plane) Surf = Handle(Geom_RectangularTrimmedSurface)::DownCast(Surf)->BasisSurface();
325   Standard_Real tolFF = BRep_Tool::Tolerance(TopoDS::Face(FF));
326   BRep_Builder BB;
327
328
329   //--ofv:
330   //       Unfortunately, the function GFillONPartsWES2() from file TopOpeBRepBuild_BuilderON.cxx sets orientation of
331   //       some section edges as INTERNAL or EXTERNAL, but they should be FORWARD or REVERSED. It probably makes faces
332   //       without closed boundary, for example. So, we must check carefuly edges with orientation INTERNAL(EXTERNAL).
333   //       Bugs: 60936, 60937, 60938 (cut, fuse, common shapes)
334   TopoDS_Compound CmpOfEdges;
335   BRep_Builder BldCmpOfEdges;
336   TopTools_IndexedDataMapOfShapeListOfShape mapVOE;
337   TopoDS_Face tdF = TopoDS::Face(FF);
338   //--ofv.
339
340   FABU.InitFace();
341   for (; FABU.MoreFace(); FABU.NextFace())
342     {
343       Standard_Integer nbnewWwithe = 0;
344       Standard_Integer nboldW = 0;
345     
346       BB.MakeFace(newFace,Surf,Loc,tolFF);
347 //    myBuildTool.CopyFace(FF,newFace);
348
349       Standard_Integer nbw = FABU.InitWire();
350       for (; FABU.MoreWire(); FABU.NextWire())
351         {
352           Standard_Integer ne = 0;
353           Standard_Integer neFORWARD  = 0;
354           Standard_Integer neREVERSED = 0;
355           Standard_Integer neINTERNAL = 0;
356           Standard_Integer neEXTERNAL = 0;
357
358           Standard_Boolean isold = FABU.IsOldWire();
359           if(isold)
360             {
361               nboldW++;
362               newWire = TopoDS::Wire(FABU.OldWire());
363             }
364           else
365             {
366               BldCmpOfEdges.MakeCompound(CmpOfEdges);//new compound
367               myBuildTool.MakeWire(newWire);
368               FABU.InitEdge();
369               for(; FABU.MoreEdge(); FABU.NextEdge())
370                 {
371                   TopoDS_Edge newEdge = TopoDS::Edge(FABU.Edge());
372 //                if (mEtouched.Contains(newEdge)) continue;// xpu290498
373 //                mEtouched.Add(newEdge);// xpu290498
374
375                   //--ofv:
376                   Standard_Integer nadde = FABU.AddEdgeWire(newEdge,CmpOfEdges);
377                   ne += nadde;
378                   //Standard_Integer nadde = FABU.AddEdgeWire(newEdge,newWire);
379                   //ne += nadde;
380                   //--ofv.
381
382                   TopAbs_Orientation oE = newEdge.Orientation();
383                   if      (oE == TopAbs_INTERNAL) neINTERNAL++;
384                   else if (oE == TopAbs_EXTERNAL) neEXTERNAL++;
385                   else if (oE == TopAbs_FORWARD)  neFORWARD++;
386                   else if (oE == TopAbs_REVERSED) neREVERSED++;
387           
388                   Standard_Boolean hasPC = FC2D_HasCurveOnSurface(newEdge,newFace);                                     // jyl980402+
389                   if (!hasPC)                                                                                           // jyl980402+
390                     {                                                                                                   // jyl980402+
391                       Standard_Real tolE = BRep_Tool::Tolerance(newEdge);                                               // jyl980402+
392                       Standard_Real f2,l2,tolpc; Handle(Geom2d_Curve) C2D;                                              // jyl980402+
393                       //C2D = FC2D_CurveOnSurface(newEdge,newFace,f2,l2,tolpc);                                         // jyl980402+
394                       C2D = FC2D_CurveOnSurface(newEdge,newFace,f2,l2,tolpc, Standard_True);                            // xpu051198 (CTS21701)
395                       if(C2D.IsNull()) Standard_ProgramError::Raise("TopOpeBRepBuild_Builder::GFABUMakeFaces null PC"); // jyl980402+
396                       Standard_Real tol = Max(tolE,tolpc);                                                              // jyl980402+
397                       BRep_Builder BB_PC; BB_PC.UpdateEdge(newEdge,C2D,newFace,tol);                                    // jyl980402+
398                     }                                                                                                   // jyl980402+
399                 } // FABU.MoreEdge()
400
401               //--ofv:
402               if((neINTERNAL == 0 && neEXTERNAL == 0) || (ne == neINTERNAL || ne == neEXTERNAL))
403                 {
404                   TopExp_Explorer EdgeEx;
405                   if(nbw == 1 && ne == 2)
406                     {
407                       EdgeEx.Init(CmpOfEdges,TopAbs_EDGE);
408                       TopoDS_Edge nEdge1 = TopoDS::Edge(EdgeEx.Current());
409                       EdgeEx.Next();
410                       TopoDS_Edge nEdge2 = TopoDS::Edge(EdgeEx.Current());
411                       if( nEdge1.IsSame(nEdge2) )
412                         return;
413                     }
414                   for(EdgeEx.Init(CmpOfEdges,TopAbs_EDGE); EdgeEx.More(); EdgeEx.Next())
415                     {
416                       TopoDS_Edge newEdge = TopoDS::Edge(EdgeEx.Current());
417                       FABU.AddEdgeWire(newEdge,newWire);
418                     }
419                 }
420               else
421                 {
422                   //TopTools_IndexedDataMapOfShapeListOfShape mapVOE;
423                   mapVOE.Clear();
424                   TopExp::MapShapesAndAncestors(CmpOfEdges,TopAbs_VERTEX,TopAbs_EDGE,mapVOE);
425                   // checking: wire is closed and regular. If wire is not close or not regular: vertex has only the one edge
426                   // or vetrex has more then two shared edges, we don't modify it. 
427                   Standard_Boolean WisClsd = Standard_True;
428                   for(Standard_Integer MapStep = 1; MapStep <= mapVOE.Extent(); MapStep++)
429                     {
430                       const TopTools_ListOfShape& LofE = mapVOE.FindFromIndex(MapStep);
431                       if(LofE.Extent() != 2) { WisClsd = Standard_False; break; }
432                     }
433                   if(!WisClsd)
434                     {
435                       //wire is not regular:
436                       TopExp_Explorer EdgeEx;
437                       for(EdgeEx.Init(CmpOfEdges,TopAbs_EDGE); EdgeEx.More(); EdgeEx.Next())
438                         {
439                           TopoDS_Edge newEdge = TopoDS::Edge(EdgeEx.Current());
440                           FABU.AddEdgeWire(newEdge,newWire);
441                         }
442                     }
443                   else
444                     {
445                       //wire seems to be regular:
446                       TopTools_ListOfShape LofAddE;  // list of edges has already been added in wire
447                       Standard_Integer naddsame = 0; 
448                       while( ne > (LofAddE.Extent() + naddsame) )
449                         {
450                           for(Standard_Integer StepMap = 1; StepMap <= mapVOE.Extent(); StepMap++)
451                             {
452                               const TopTools_ListOfShape& LofE = mapVOE.FindFromIndex(StepMap);
453                               TopTools_ListIteratorOfListOfShape itLofE(LofE);
454                               TopoDS_Edge E1 = TopoDS::Edge(itLofE.Value());
455                               itLofE.Next();
456                               TopoDS_Edge E2 = TopoDS::Edge(itLofE.Value());
457                               TopAbs_Orientation O1 = E1.Orientation();
458                               TopAbs_Orientation O2 = E2.Orientation();
459                               Standard_Boolean IsSameE1 = BRep_Tool::IsClosed(E1,tdF);
460                               Standard_Boolean IsSameE2 = BRep_Tool::IsClosed(E2,tdF);
461                               Standard_Boolean AddE1 = Standard_True;
462                               Standard_Boolean AddE2 = Standard_True;
463
464                               //checking current edges in the list of added edges
465                               TopTools_ListIteratorOfListOfShape itLofAddE(LofAddE);
466                               for(; itLofAddE.More(); itLofAddE.Next() )
467                                 {
468                                   const TopoDS_Shape& LE = itLofAddE.Value();
469                                   TopAbs_Orientation OLE = LE.Orientation();
470                                   if(E1.IsSame(LE) && !IsSameE1) { AddE1 = Standard_False; E1.Orientation(OLE); O1 = OLE; }
471                                   if(E2.IsSame(LE) && !IsSameE2) { AddE2 = Standard_False; E2.Orientation(OLE); O2 = OLE; }
472                                 }
473                               Standard_Integer chkORI = FUN_CheckORI(O1,O2);
474                               if(chkORI == 0){ AddE1 = Standard_False; AddE2 = Standard_False; }
475                               if(chkORI == 1)
476                                 {
477                                   TopAbs_Orientation ori = FUN_ReOrientIntExtEdge(E2,O2,E1);
478                                   if(ori == TopAbs_FORWARD) { E1.Orientation(TopAbs_FORWARD); neFORWARD++; }
479                                   if(ori == TopAbs_REVERSED){ E1.Orientation(TopAbs_REVERSED); neREVERSED++; }
480                                   if(ori == TopAbs_REVERSED || ori == TopAbs_FORWARD)
481                                     {
482                                       if(O1 == TopAbs_INTERNAL) neINTERNAL--;
483                                       else neEXTERNAL--;
484                                     }
485                                 }
486                               if(chkORI == 2)
487                                 {
488                                   TopAbs_Orientation ori = FUN_ReOrientIntExtEdge(E1,O1,E2);
489                                   if(ori == TopAbs_FORWARD) { E2.Orientation(TopAbs_FORWARD); neFORWARD++; }
490                                   if(ori == TopAbs_REVERSED){ E2.Orientation(TopAbs_REVERSED); neREVERSED++; }
491                                   if(ori == TopAbs_REVERSED || ori == TopAbs_FORWARD)
492                                     {
493                                       if(O2 == TopAbs_INTERNAL) neINTERNAL--;
494                                       else neEXTERNAL--;
495                                     }
496                                 }
497
498
499
500                               if(AddE1)
501                                 {
502                                   FABU.AddEdgeWire(E1,newWire);
503                                   if(!IsSameE1) LofAddE.Append(E1);
504                                   else naddsame++;
505                                 }
506                               if(AddE2)
507                                 {
508                                   FABU.AddEdgeWire(E2,newWire);
509                                   if(!IsSameE2) LofAddE.Append(E2);
510                                   else naddsame++;
511                                 }
512                             }//for StepMap
513                         } // while ne >
514                     } // not regular
515                 } // neINTERNAL(neEXTERNAL) != 0
516             } // !isold
517           //--ofv.
518
519 #ifdef DEB
520       if ( tSPS ) cout<<"#--- GFABUMakeFaces "<<iF<<" : "<<ne<<" edges"<<endl; 
521 #endif    
522
523       // xpu : 13-11-97
524       if (ne != 0) {
525         Standard_Integer iow = isold? 1: 0;
526         MWisOld.Bind(newWire,iow);
527       }
528       
529       // <newWire> is empty :
530       if ( !isold ) {
531         if (ne == 0) continue;
532         else if (nbw == 1 && (ne == neINTERNAL+neEXTERNAL)) continue;
533         else nbnewWwithe++;
534       }
535
536       // caractere Closed() du nouveau wire newWire
537       if ( !isold ) {
538         Standard_Boolean closed = FUN_tool_ClosedW(newWire);
539         myBuildTool.Closed(newWire,closed); 
540       } // !isold
541       
542       myBuildTool.AddFaceWire(newFace,newWire);
543       
544     } // FABU.MoreWire()
545     
546     if ( nbnewWwithe == 0 && nboldW == 0 ) {
547       continue;
548     }
549
550     Standard_Boolean topurge = FUN_purgeFon1nonoriE(newFace);
551     if (topurge) {
552 #ifdef DEB      
553       if (strange) cout<<"Builder::GFABUMakeFaces -> purgeFon1nonoriE\n";
554 #endif
555       continue;
556     }
557     
558 // Le changement de surface de trim a basis causait la perte des regularites de l'edge
559 // j'ai change par un recadrage du trim en attendant mieux. DPF le 29/07/1998.
560 // Le danger est de modifier une donnee d'entree.
561     Handle(Standard_Type) T = Surf->DynamicType();
562     Standard_Boolean istrim = ( T == STANDARD_TYPE(Geom_RectangularTrimmedSurface) );
563     if (istrim) {
564       Handle(Geom_RectangularTrimmedSurface) 
565         hrts=*((Handle(Geom_RectangularTrimmedSurface)*)&Surf);
566       Standard_Real oumin,oumax,ovmin,ovmax;
567       hrts->Bounds(oumin,oumax,ovmin,ovmax);
568       Standard_Real umin,umax,vmin,vmax;
569       BRepTools::UVBounds(newFace, umin, umax, vmin, vmax);
570       if (umin < oumin) oumin=umin;
571       if (umax > oumax) oumax=umax;
572       if (vmin < ovmin) ovmin=vmin;
573       if (vmax > ovmax) ovmax=vmax;
574       hrts->SetTrim(oumin, oumax, ovmin, ovmax, Standard_True, Standard_True);
575     }
576     lnewFace.Append(newFace);
577
578   } // FABU.MoreFace()
579
580 #ifdef DEB
581   if(tSPS) {
582     cout<<endl;GdumpSHA(FF, (char *) "#--- GFABUMakeFaces avant regularize");cout<<endl;
583     GdumpFABU(FABU);debgfabu(iF);
584   }
585 #endif
586
587   // xpu281098 : regularisation after purge processings (cto009L2,f4ou)
588 //  RegularizeFaces(FF,lnewFace,LOF);
589 //  Standard_Integer nLOF = LOF.Extent(); // DEB
590   LOF.Append(lnewFace);
591
592 } // GFABUMakeFaces