summaryrefslogtreecommitdiff
path: root/src/TopOpeBRepBuild/TopOpeBRepBuild_ffsfs.cxx
blob: d223c78fa673f76a5b461e8d2f6b22a7f3bb66f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
// file:	TopOpeBRepBuild_ffsfs.cxx
// Created:	Thu Mar  7 10:49:33 1996
// Author:	Jean Yves LEBEY
//		<jyl@meteox>

#include <TopOpeBRepBuild_Builder.jxx>
#include <TopOpeBRepBuild_define.hxx>
#include <TopOpeBRepBuild_FuseFace.hxx>

#include <TopOpeBRepDS_EXPORT.hxx>
#include <TopOpeBRepDS_samdom.hxx>
#include <TopOpeBRepTool_EXPORT.hxx>
#include <TopOpeBRepTool_SC.hxx>
#include <BRepClass3d_SolidExplorer.hxx>
#include <BRepTopAdaptor_FClass2d.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS.hxx>

#ifdef DEB
#define DEBSHASET(sarg,meth,shaset,str) TCollection_AsciiString sarg((meth));(sarg)=(sarg)+(shaset).DEBNumber()+(str);
Standard_EXPORT Standard_Boolean TopOpeBRepBuild_GetcontextNOFUFA();
Standard_EXPORT void debffsfs(const Standard_Integer i){cout<<"+++ debffsfs "<<i<<endl;}
Standard_EXPORT void debffflo(const Standard_Integer i){cout<<"+++ debffflo "<<i<<endl;}
#endif

static Standard_Boolean STATIC_motheropedef = Standard_False; static TopOpeBRepBuild_GTopo STATIC_Gmotherope;
Standard_EXPORT void FUN_setmotherope(const TopOpeBRepBuild_GTopo& G) {STATIC_Gmotherope = G;STATIC_motheropedef = Standard_True;}
Standard_EXPORT void FUN_unsetmotherope() { STATIC_motheropedef = Standard_False; }
Standard_EXPORT Standard_Boolean FUN_ismotheropedef() { return STATIC_motheropedef; }
Standard_EXPORT const TopOpeBRepBuild_GTopo& FUN_motherope() { return STATIC_Gmotherope; } 

//Standard_IMPORT extern Standard_Boolean GLOBAL_classifysplitedge;
Standard_EXPORTEXTERN Standard_Boolean GLOBAL_classifysplitedge;
//Standard_IMPORT extern Standard_Boolean GLOBAL_revownsplfacori;
Standard_EXPORTEXTERN Standard_Boolean GLOBAL_revownsplfacori;
Standard_EXPORT void FUNBUILD_ANCESTORRANKPREPARE
(TopOpeBRepBuild_Builder& B,const TopTools_ListOfShape& LF1,const TopTools_ListOfShape& LF2,const TopOpeBRepDS_Config c1,const TopOpeBRepDS_Config c2);
Standard_EXPORT void FUNBUILD_ANCESTORRANKGET(TopOpeBRepBuild_Builder& B,const TopoDS_Shape& f,Standard_Boolean& of1,Standard_Boolean& of2);

static Standard_Integer FUN_getAncestorFsp(TopOpeBRepBuild_Builder& B,TopOpeBRepTool_ShapeClassifier& SC,const TopTools_ListOfShape& LF,const TopoDS_Shape& fsp,Standard_Boolean& p3ddef,gp_Pnt& p3d);
static Standard_Integer FUN_getAncestorFsp(TopOpeBRepBuild_Builder& B,TopOpeBRepTool_ShapeClassifier& SC,const TopTools_ListOfShape& LF1,const TopTools_ListOfShape& LF2,const TopoDS_Shape& fsp);
#ifdef DEB
//static void FUN_getAncestorFsp(const Handle(TopOpeBRepDS_HDataStructure)& HDS,TopOpeBRepTool_ShapeClassifier& SC,const TopTools_ListOfShape& LF1,const TopTools_ListOfShape& LF2,const TopTools_ListOfShape& spFOR,
//			       TopTools_DataMapOfShapeInteger* SplitAnc);
#endif

static Standard_Integer FUN_getAncestorFsp(TopOpeBRepBuild_Builder& B,TopOpeBRepTool_ShapeClassifier& SC,const TopTools_ListOfShape& LF,const TopoDS_Shape& fsp,Standard_Boolean& p3ddef,gp_Pnt& p3d)
{
#ifndef DEB
//  static const TopOpeBRepDS_DataStructure& BDS = B.DataStructure()->DS();
  const TopOpeBRepDS_DataStructure& BDS = B.DataStructure()->DS(); // How to do static <--> const
#else
  const TopOpeBRepDS_DataStructure& BDS = B.DataStructure()->DS();
#endif
  TopTools_ListIteratorOfListOfShape itf(LF);
  for (; itf.More(); itf.Next()){
    const TopoDS_Face& f = TopoDS::Face(itf.Value());
    TopAbs_State st = SC.StateShapeShape(fsp,f,1);
    if ((st == TopAbs_UNKNOWN) || (st == TopAbs_OUT)) continue;
    if (st == TopAbs_ON) {
      if (!p3ddef) {
	Standard_Boolean ok = BRepClass3d_SolidExplorer::FindAPointInTheFace(TopoDS::Face(fsp),p3d);
	if (!ok) return 0;
	p3ddef = Standard_True;
      }
      gp_Pnt2d p2d;Standard_Real dd = 0.; Standard_Boolean ok = FUN_tool_projPonF(p3d,f,p2d,dd);
      if (!ok) return 0;
      Standard_Real tolf = BRep_Tool::Tolerance(f)*1.e1;
      if (dd > tolf) return 0;
      Standard_Real  TolClass  = 1e-8; BRepTopAdaptor_FClass2d FClass2d(f,TolClass);
      st = FClass2d.Perform(p2d);
    }
    if (st == TopAbs_IN) {
      Standard_Integer ianc = BDS.Shape(f);
      return ianc;
    }
  } // itf(LF)
  return 0;
}

static Standard_Integer FUN_getAncestorFsp(TopOpeBRepBuild_Builder& B,TopOpeBRepTool_ShapeClassifier& SC,
			      const TopTools_ListOfShape& LF1,const TopTools_ListOfShape& LF2,const TopoDS_Shape& fsp)
{
  // IMPORTANT : fsp is split IN/OUT of F1,so it has only one ancestor face
  // LF1 faces sdm with LF2
#ifndef DEB
  const TopOpeBRepDS_DataStructure& BDS = B.DataStructure()->DS();
#else
  const TopOpeBRepDS_DataStructure& BDS = B.DataStructure()->DS();
#endif
  Standard_Boolean of1,of2; FUNBUILD_ANCESTORRANKGET(B,fsp,of1,of2);	
  Standard_Integer rkfsp = 0;
  if      (of1 && !of2) rkfsp = 1;
  else if (of2 && !of1) rkfsp = 2;
  Standard_Boolean unk = (rkfsp == 0);

  Standard_Integer rkf1 = BDS.AncestorRank(LF1.First()); 
  Standard_Integer rkf2 = BDS.AncestorRank(LF2.First());  
  Standard_Boolean p3ddef = Standard_False; gp_Pnt p3d;
  
  Standard_Boolean ison1 = (rkf1 == rkfsp); 
  Standard_Boolean ison2 = (rkf2 == rkfsp); 

  Standard_Integer ianc1=0,ianc2=0;
  if (ison1 || unk) 
    ianc1 = FUN_getAncestorFsp(B,SC,LF1,fsp,p3ddef,p3d);
  if (ison1) return ianc1;

  if (ison2 || unk) 
    ianc2 = FUN_getAncestorFsp(B,SC,LF2,fsp,p3ddef,p3d);
  if (ison2) return ianc2;

  if (ianc1 + ianc2 >0) {
    if      (ianc1 == 0) return ianc2; 
    else if (ianc2 == 0) return ianc1;
    else                 return 0; // fsp has 2 ancestor faces
  } 
  return 0;
}

Standard_EXPORT TopTools_DataMapOfShapeInteger* GLOBAL_SplitAnc = NULL; //xpu260598

static void FUN_getAncestorFsp(TopOpeBRepBuild_Builder& B,TopOpeBRepTool_ShapeClassifier& SC,
			       const TopTools_ListOfShape& LF1,const TopTools_ListOfShape& LF2,
			       const TopoDS_Shape& FOR,TopTools_DataMapOfShapeInteger* SplitAnc)
{	
  if (SplitAnc == NULL) return;

  Standard_Boolean issplitIN = B.IsSplit(FOR,TopAbs_IN); 
  Standard_Boolean issplitOU = B.IsSplit(FOR,TopAbs_OUT); 
  if (!issplitIN && !issplitOU) return;

  TopTools_ListOfShape spFOR; 
  if (issplitIN) FDS_copy(B.Splits(FOR,TopAbs_IN),spFOR);
  if (issplitOU) FDS_copy(B.Splits(FOR,TopAbs_OUT),spFOR);

  for (TopTools_ListIteratorOfListOfShape itsp(spFOR); itsp.More(); itsp.Next()){
    const TopoDS_Shape& fsp = itsp.Value();
    
    Standard_Boolean isbound = SplitAnc->IsBound(fsp);
    if (isbound) continue;
    
    Standard_Integer ianc = FUN_getAncestorFsp(B,SC,LF1,LF2,fsp);
    if (ianc != 0) {
      SplitAnc->Bind(fsp,ianc);
    }
  } // itsp
}

Standard_EXPORT TopTools_ListOfShape* GLOBAL_lfr1 = NULL;
Standard_EXPORT Standard_Boolean GLOBAL_lfrtoprocess = Standard_False;
//Standard_IMPORT extern TopTools_ListOfShape* GLOBAL_lfr1;
//Standard_IMPORT TopTools_ListOfShape* GLOBAL_lfr1;
//Standard_IMPORT extern Standard_Boolean GLOBAL_lfrtoprocess;
//Standard_IMPORT Standard_Boolean GLOBAL_lfrtoprocess;

//=======================================================================
//function : GFillFaceSFS
//purpose  : 
//=======================================================================
void TopOpeBRepBuild_Builder::GFillFaceSFS(const TopoDS_Shape& FOR,const TopTools_ListOfShape& LSO2,const TopOpeBRepBuild_GTopo& Gin,TopOpeBRepBuild_ShellFaceSet& SFS)
{
  TopAbs_State TB1,TB2; Gin.StatesON(TB1,TB2);
  
#ifdef DEB
  Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(FOR,iF);
  if(tSPS)cout<<endl;
#endif
#ifndef DEB
//  static const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
  const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
#else
  const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
#endif
  Standard_Boolean tosplit = GToSplit(FOR,TB1);
  Standard_Boolean tomerge = GToMerge(FOR);
#ifdef DEB
//  Standard_Integer iFOR = BDS.Shape(FOR);
#endif
  Standard_Integer rkFOR = BDS.AncestorRank(FOR);
  
#ifdef DEB
  if(tSPS){
    GdumpSHASTA(FOR,TB1,"--- GFillFaceSFS START ");
    cout<<" tosplit "<<tosplit<<" tomerge "<<tomerge<<endl;
    debffsfs(iF);
  }
#endif
  
  TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD);  
  Standard_Boolean hsd = myDataStructure->HasSameDomain(FOR);	//xpu280598
  GLOBAL_lfrtoprocess = Standard_False;

  if ( tosplit && tomerge ) {
    
    // merge des faces SameDomain
    
    // on effectue le merge ssi FOR est la reference de ses faces SameDomain
    Standard_Integer iref = myDataStructure->SameDomainReference(FOR);
    const TopoDS_Shape& fref = myDataStructure->Shape(iref);
    Standard_Boolean isref = FOR.IsSame(fref);

    Standard_Boolean makemerge = isref;
    // xpu280199 PRO16958 : f10=ref(f6), GToMerge(f10)=false 
    Standard_Boolean makemergeref = GToMerge(fref);
    makemerge = makemerge || (!makemergeref && (rkFOR == 1));
    
    if (makemerge) {
      
#ifdef DEB
      if(tSPS) {
	GdumpSHASTA(FOR,TB1,"[[[[[[[[[[[[[[[[[[[[[[[[[[ GFillFaceSFS makemerge START ");
	cout<<endl;
      }
#endif

      Standard_Boolean performfufa = Standard_True;
#ifdef DEB
      performfufa = !TopOpeBRepBuild_GetcontextNOFUFA();
#endif	  
      if (performfufa) {	
	GLOBAL_lfrtoprocess = Standard_True;
	if (GLOBAL_lfrtoprocess) {
	  if (GLOBAL_lfr1==NULL) GLOBAL_lfr1=(TopTools_ListOfShape*)new TopTools_ListOfShape();
	  GLOBAL_lfr1->Clear();
	}
      }

      // xpu280598 : Filling up GLOBAL_SplitAnc = {(fsp,ifanc)}
      //              . fsp = spIN/OU(fanc),
      //              . fanc hsdm is the unique ancestor face     
      if ( GLOBAL_SplitAnc == NULL ) GLOBAL_SplitAnc = (TopTools_DataMapOfShapeInteger*) new TopTools_DataMapOfShapeInteger(); 
      GLOBAL_SplitAnc->Clear();

      TopTools_ListOfShape LFSO,LFDO,LFSO1,LFDO1,LFSO2,LFDO2;
      GFindSamDomSODO(FF,LFSO,LFDO); // -980617
//      FDSSDM_sordor(FF,LFSO,LFDO);
      Standard_Integer rankF=GShapeRank(FF),rankX=(rankF)?((rankF==1)?2:1):0;
      GFindSameRank(LFSO,rankF,LFSO1);
      GFindSameRank(LFDO,rankF,LFDO1);
      GFindSameRank(LFSO,rankX,LFSO2);
      GFindSameRank(LFDO,rankX,LFDO2);
      TopTools_ListOfShape LF1,LF2;
      
      TopOpeBRepBuild_GTopo GM;
      TopAbs_State TB,NTB;
      Standard_Boolean dodo;
      Standard_Integer l1,l2;
      
      // WES : toutes les faces de meme orientation topologique
      LF1 = LFSO1; // NYI pointeurs
      LF2 = LFSO2; // NYI pointeurs
      l1 = LF1.Extent(); l2 = LF2.Extent();
      dodo = (l1!=0) && (l2!=0);      
      
      FUN_unsetmotherope(); // +12/07
      
      GM = Gin;
      GM.ChangeConfig(TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_SAMEORIENTED);
      if (dodo) {
#ifdef DEB
	if(tSPS){
	  GdumpSAMDOM(LF1, (char *) "LF1 (LFSO1) : ");
	  GdumpSAMDOM(LF2, (char *) "LF2 (LFSO2) : ");
	}
#endif
	GLOBAL_classifysplitedge = Standard_True;
	GFillFacesWESMakeFaces(LF1,LF2,LSO2,GM);
	GLOBAL_classifysplitedge = Standard_False;
	
	GLOBAL_revownsplfacori = Standard_True;
	FUNBUILD_ANCESTORRANKPREPARE
	  (*this,LF1,LF2,TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_SAMEORIENTED);
	if (hsd) FUN_getAncestorFsp((*this),myShapeClassifier,
				    LF1,LF2,FOR,GLOBAL_SplitAnc); //xpu280598

	// GLOBAL_lfrtoprocess = t 
	// ==> on ne stocke PAS les faces 'startelement' dans le SFS
	//     mais dans GLOBAL_lfr1,
	// GLOBAL_lfrtoprocess = f
	// ==> on stocke normalement dans le SFS et pas dans GLOBAL_lfr1
	// NYI : + argument a la methode GSplitFaceSFS ?? a voir

	// ici : GLOBAL_lfrtoprocess = t
	if (GLOBAL_lfr1==NULL) GLOBAL_lfr1=(TopTools_ListOfShape*)new TopTools_ListOfShape(); //flo150998
	GLOBAL_lfr1->Clear();
	GSplitFaceSFS(FOR,LSO2,GM,SFS);
	GLOBAL_lfrtoprocess = Standard_False;
	GLOBAL_revownsplfacori = Standard_False;
      }
      
      // WES : FOR + faces d'orientation topologique opposee
      LF1 = LFSO1; // NYI pointeurs
      LF2 = LFDO2; // NYI pointeurs
      l1 = LF1.Extent(); l2 = LF2.Extent();
      dodo = (l1!=0) && (l2!=0);
      
      
      GM = Gin; // OUT,OUT-> OUT,IN + IN OUT
      TB = TB2; //           ------
      NTB = TopAbs_IN; // NTB = (TB == TopAbs_OUT) ? TopAbs_IN : TopAbs_OUT;
      GM.ChangeValue(TB,TopAbs_ON,Standard_False);
      GM.ChangeValue(NTB,TopAbs_ON,Standard_True);
      GM.ChangeConfig(TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_DIFFORIENTED);
      FUN_setmotherope(GM); // +12/07
      if (dodo) {
#ifdef DEB
	if(tSPS){
	  TopAbs_State TB11,TB21; GM.StatesON(TB11,TB21);
	  cout<<endl;
	  cout <<"@@@@"<<endl;
	  cout <<"@@@@@@@@ partie 1 : ";TopAbs::Print(TB11,cout);cout<<" ";TopAbs::Print(TB21,cout);cout<<endl;
	  cout <<"@@@@"<<endl;
	  GdumpSAMDOM(LF1, (char *) "LF1 (LFSO1) : ");
	  GdumpSAMDOM(LF2, (char *) "LF2 (LFDO2) : ");
	  cout<<endl;
	}
#endif
	GLOBAL_classifysplitedge = Standard_True;
	GFillFacesWESMakeFaces(LF1,LF2,LSO2,GM);
	GLOBAL_classifysplitedge = Standard_False;
	
	GLOBAL_revownsplfacori = Standard_True;
	FUNBUILD_ANCESTORRANKPREPARE
	  (*this,LF1,LF2,TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_DIFFORIENTED);
	if (hsd) FUN_getAncestorFsp((*this),myShapeClassifier,
				    LF1,LF2,FOR,GLOBAL_SplitAnc); //xpu280598
	
	if ( Opecom() ) {
	  Standard_Boolean issplitIN = IsSplit(FOR,TopAbs_IN); 
	  if (issplitIN) {
	    const TopTools_ListOfShape& spFOR = Splits(FOR,TopAbs_IN);
	    TopTools_ListOfShape spFORcopy; FDS_copy(spFOR,spFORcopy);

	    TopTools_ListIteratorOfListOfShape it(LF1);
	    for (; it.More(); it.Next()) {
	      const TopoDS_Shape& f = it.Value();
	      Standard_Boolean issplit = IsSplit(f,TopAbs_IN);
	      if ( issplit ) ChangeSplit(f,TopAbs_IN).Clear();
	    }
	    it.Initialize(LF2);
	    for (; it.More(); it.Next()) {
	      const TopoDS_Shape& f = it.Value();
	      Standard_Boolean issplit = IsSplit(f,TopAbs_IN);
	      if ( issplit ) ChangeSplit(f,TopAbs_IN).Clear();
	    }
	    ChangeSplit(FOR,TopAbs_IN).Append(spFORcopy); // keep split for reference
	  } // issplitIN
	} // OpeCom 

	GSplitFaceSFS(FOR,LSO2,GM,SFS);
	GLOBAL_revownsplfacori = Standard_False;

      } // dodo
      
      if (!Opecom()) {
	GM = Gin; // OUT,OUT-> OUT,IN + IN OUT
	TB = TB1; //                    ------ 
	//      NTB = (TB == TopAbs_OUT) ? TopAbs_IN : TopAbs_OUT;
	NTB = TopAbs_IN;
	GM.ChangeValue(TopAbs_ON,TB,Standard_False);
	GM.ChangeValue(TopAbs_ON,NTB,Standard_True);
	GM.ChangeConfig(TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_DIFFORIENTED);
	FUN_setmotherope(GM); // +12/07
	if (dodo) {
#ifdef DEB
	  if(tSPS){
	    TopAbs_State TB12,TB22; GM.StatesON(TB12,TB22);
	    cout<<endl;
	    cout <<"@@@@"<<endl;
	    cout <<"@@@@@@@@ partie 2 : ";TopAbs::Print(TB12,cout);cout<<" ";TopAbs::Print(TB22,cout);cout<<endl;
	    cout <<"@@@@"<<endl;
	    GdumpSAMDOM(LF1, (char *) "LF1 (LFSO1) : ");
	    GdumpSAMDOM(LF2, (char *) "LF2 (LFDO2) : ");
	    cout<<endl;
	  }
#endif
	  GLOBAL_classifysplitedge = Standard_True;
	  GFillFacesWESMakeFaces(LF1,LF2,LSO2,GM);
	  GLOBAL_classifysplitedge = Standard_False;
	  
	  GLOBAL_revownsplfacori = Standard_True;
	  FUNBUILD_ANCESTORRANKPREPARE
	    (*this,LF1,LF2,TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_DIFFORIENTED);
	  if (hsd) FUN_getAncestorFsp((*this),myShapeClassifier,
				      LF1,LF2,FOR,GLOBAL_SplitAnc); //xpu280598
	  GSplitFaceSFS(FOR,LSO2,GM,SFS);
	  GLOBAL_revownsplfacori = Standard_False;
	}
      } // !Opecom
      
      FUN_unsetmotherope(); // +12/07
      
#ifdef DEB
      if(tSPS) { 
	GdumpSHASTA(FOR,TB1,"]]]]]]]]]]]]]]]]]]]]]]]]]] GFillFaceSFS makemerge END ");
	cout<<endl;
      }
#endif

      GLOBAL_SplitAnc->Clear(); // xpu280598

      // FuseFace
      SFS.ChangeStartShapes().Extent();
      if (performfufa) {	
#ifdef DEB
	if(tSPS) debffflo(iF);
#endif
//	const TopTools_ListOfShape& lou = Splits(FF,TopAbs_OUT); Standard_Integer nou = lou.Extent();
//	const TopTools_ListOfShape& lin = Splits(FF,TopAbs_IN);  Standard_Integer nin = lin.Extent();
//	GCopyList(lou,*GLOBAL_lfr1);
//	GCopyList(lin,*GLOBAL_lfr1);	
#ifdef DEB
//	Standard_Integer nlfr1 = GLOBAL_lfr1->Extent();
#endif

	// NYI : Builder += methode pour le process fufa
	TopOpeBRepBuild_FuseFace fufa; TopTools_ListOfShape ldum; Standard_Integer addinternal = 1; // disparition
	fufa.Init(ldum,*GLOBAL_lfr1,addinternal);
	fufa.PerformFace();
	Standard_Boolean isdone = fufa.IsDone();
	if (!isdone) return;
#ifdef DEB
//	Standard_Boolean ismodified = fufa.IsModified();
#endif
	const TopTools_ListOfShape& lfr2 = fufa.LFuseFace();
//
//	const TopTools_ListOfShape& lfr2 = *GLOBAL_lfr1
	// les faces remplacantes
	for (TopTools_ListIteratorOfListOfShape itlfr2(lfr2);itlfr2.More();itlfr2.Next()) {
	  const TopoDS_Shape& flfr2 = itlfr2.Value();
	  
#ifdef DEB
	  if(tSPS){
	    DEBSHASET(ss,"--- FillFaceSFS apres fufa",SFS," AddStartElement SFS+ face ");  
	    GdumpSHA(flfr2,(Standard_Address)ss.ToCString());
	    cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 face ";
	    TopAbs::Print(flfr2.Orientation(),cout); cout<<endl;
	  }
#endif
	  SFS.AddStartElement(flfr2);
	}
	SFS.ChangeStartShapes().Extent();
      } // performfufa (context)
      
    } // makemerge
  } // tosplit && tomerge
  
  else if ( tosplit && !tomerge ) {    
    GSplitFace(FOR,Gin,LSO2);
    GSplitFaceSFS(FOR,LSO2,Gin,SFS);
  }
  else if ( !tosplit && !tomerge ) {
    GSplitFaceSFS(FOR,LSO2,Gin,SFS);
  }
  
  myEdgeAvoid.Clear();
  
#ifdef DEB
  if(tSPS){
    GdumpSHASTA(FOR,TB1,"--- GFillFaceSFS END ");cout<<endl;
  }
#endif
 
} // GFillFaceSFS