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