summaryrefslogtreecommitdiff
path: root/src/TopOpeBRepBuild/TopOpeBRepBuild_FREGU.cxx
blob: b8b0e7c2cce0816c2a526ab7947845e06ee5ae23 (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
// file:	TopOpeBRepBuild_Grid.cxx
// Created:	Thu Mar  7 10:49:33 1996
// Author:	Jean Yves LEBEY
//		<jyl@meteox>

#include <TopOpeBRepBuild_Builder.ixx>

#include <TopOpeBRepBuild_WireToFace.hxx>
#include <TopOpeBRepTool.hxx>
#include <TopExp_Explorer.hxx>
#include <TopExp.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <Standard_ProgramError.hxx>
#include <TopOpeBRepDS_define.hxx>

#ifdef DEB
Standard_IMPORT Standard_Boolean TopOpeBRepBuild_GetcontextNOREGUFA();
Standard_IMPORT Standard_Boolean TopOpeBRepBuild_GetcontextREGUXPU();
Standard_IMPORT Standard_Boolean TopOpeBRepBuild_GettraceSAVFREGU();
void debregufa(const Standard_Integer /*iF*/) {}
#endif

#ifdef DRAW
#include <DBRep.hxx>
#endif

#define M_FORWARD(O)  (O == TopAbs_FORWARD)
#define M_REVERSED(O) (O == TopAbs_REVERSED)

//=======================================================================
//function : RegularizeFaces
//purpose  : 
//=======================================================================
void TopOpeBRepBuild_Builder::RegularizeFaces
(const TopoDS_Shape& FF,const TopTools_ListOfShape& lnewFace,TopTools_ListOfShape& LOF)
{
  LOF.Clear();
  myMemoSplit.Clear();

  TopTools_ListIteratorOfListOfShape itl(lnewFace);  
  for (;itl.More();itl.Next()) {
    const TopoDS_Shape& newFace = itl.Value();
    TopTools_ListOfShape newFaceLOF;
    RegularizeFace(FF,newFace,newFaceLOF);
#ifdef DEB
//    Standard_Integer nnewFaceLOF = newFaceLOF.Extent(); // DEB
#endif
    LOF.Append(newFaceLOF);
  }
#ifdef DEB
//  Standard_Integer nLOF = LOF.Extent(); // DEB
#endif

  Standard_Integer nr = myMemoSplit.Extent();
  if (nr == 0 ) return;

  // lfsdFF = faces SameDomain de FF
  TopTools_ListOfShape lfsdFF,lfsdFF1,lfsdFF2;
  GFindSamDom(FF,lfsdFF1,lfsdFF2);
  lfsdFF.Append(lfsdFF1);
  lfsdFF.Append(lfsdFF2);
  
  TopTools_ListIteratorOfListOfShape itlfsdFF(lfsdFF);
  for (; itlfsdFF.More(); itlfsdFF.Next()) {
    const TopoDS_Shape& fsdFF = itlfsdFF.Value();
    // au moins une arete de FF dont le Split() est lui meme Split()
    TopExp_Explorer x;
    for (x.Init(fsdFF,TopAbs_EDGE);x.More();x.Next()) {
//    for (TopExp_Explorer x(fsdFF,TopAbs_EDGE);x.More();x.Next()) {
      const TopoDS_Shape& e = x.Current();
#ifdef DEB
//      Standard_Integer ie = myDataStructure->Shape(e); //DEB
//      Standard_Boolean issect = myDataStructure->DS().IsSectionEdge(TopoDS::Edge(e));
#endif

      Standard_Integer ranke = GShapeRank(e);
      TopAbs_State staeope = (ranke==1) ? myState1 : myState2;
      
      for (Standard_Integer iiista = 1; iiista <= 2; iiista++ ) {
	
	TopAbs_State stae = staeope;
	if (iiista == 2) stae = TopAbs_ON;
	
	Standard_Boolean issplite = IsSplit(e,stae);
	if (!issplite) continue;
	
	TopTools_ListOfShape& lspe = ChangeSplit(e,stae);
#ifdef DEB
//	Standard_Integer nlspe = lspe.Extent(); // DEB
#endif
	TopTools_ListOfShape newlspe;
	for (TopTools_ListIteratorOfListOfShape itl1(lspe);itl1.More();itl1.Next()) {
	  const TopoDS_Shape& esp = itl1.Value();
	  Standard_Boolean espmemo = myMemoSplit.Contains(esp);
	  if (!espmemo) newlspe.Append(esp);
	  else {
	    const TopTools_ListOfShape& lspesp = Splits(esp,stae);
	    GCopyList(lspesp,newlspe);
	  }
	}	
	lspe.Clear();
	GCopyList(newlspe,lspe);

      } // iiista
    } // explorer (fsdFF,TopAbs_EDGE)
  } // itlfsdFF.More()
} // RegularizeFaces

/*static void FUN_setInternal(TopoDS_Face& F)
{
  TopExp_Explorer ex(F,TopAbs_EDGE);
  TopTools_MapOfShape meF,meR,meI;
  for (; ex.More(); ex.Next()){
    const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
    TopAbs_Orientation oE = E.Orientation();
    Standard_Boolean isclo = BRep_Tool::IsClosed(E,F); // E has 2d rep on F
    if (isclo) continue; 
    Standard_Boolean isb = Standard_False; // the edge is FOR + REV in F
    if      (M_FORWARD(oE))  {meF.Add(E); isb = meR.Contains(E);}
    else if (M_REVERSED(oE)) {meR.Add(E); isb = meF.Contains(E);}
    if (isb) meI.Add(E.Oriented(TopAbs_INTERNAL));
  }  

  BRep_Builder BB;
  TopTools_MapIteratorOfMapOfShape it(meI);
  for (; it.More(); it.Next()){
    const TopoDS_Edge& E = TopoDS::Edge(it.Key());
    BB.Remove(F,E.Oriented(TopAbs_FORWARD));
    BB.Remove(F,E.Oriented(TopAbs_REVERSED));
    BB.Add(F,E);
  }
}*/

//=======================================================================
//function : RegularizeFace
//purpose  : 
//=======================================================================
void TopOpeBRepBuild_Builder::RegularizeFace
(const TopoDS_Shape& FF,const TopoDS_Shape& anewFace,TopTools_ListOfShape& LOF)
{
  LOF.Clear();
  const TopoDS_Face& newFace = TopoDS::Face(anewFace);
  Standard_Boolean toregu = Standard_True;
  Standard_Boolean usewtof = Standard_True;
  
#ifdef DEB
  Standard_Integer iF;Standard_Boolean tSPSFF=GtraceSPS(FF,iF);
//  Standard_Boolean savfregu = TopOpeBRepBuild_GettraceSAVFREGU();
  if (TopOpeBRepBuild_GetcontextNOREGUFA()) toregu = Standard_False;
  if (TopOpeBRepBuild_GetcontextREGUXPU()) usewtof = Standard_False;
  if (tSPSFF) debregufa(iF);
#endif

  // If the same edge appears FOR+REV in the resulting face and
  // whereas it's not a closing edge, set it as INTERNAL instead.
  // FRA60275(iF=4) + PRO16297 
//  FUN_setInternal(newFace);

  if (!toregu) {
    LOF.Append(newFace);
    return;
  }
  
  TopTools_DataMapOfShapeListOfShape ownw; // OldWires --> NewWires;
  Standard_Boolean rw = Standard_False;
  Standard_Boolean rf = Standard_False;
  myESplits.Clear();
  
  rw = TopOpeBRepTool::RegularizeWires(newFace,ownw,myESplits);
  
  if ( !rw ) {
    LOF.Append(newFace);
    return;
  }      
  
  TopTools_ListOfShape newfaces;
  if (usewtof) {
    TopOpeBRepBuild_WireToFace wtof;
    TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itownw(ownw);
    for (; itownw.More(); itownw.Next()) {
      const TopTools_ListOfShape& lw = itownw.Value();

      // xpu200798 : cto902D4 f14ou
      // recall ownw = {(ow = old wire, lnw = {list of new wires descendant of old wire}}
      // if lnw is empty, then ow is kept unchanged.
      Standard_Boolean kept = lw.IsEmpty();
      if (kept) {
	const TopoDS_Wire& ow = TopoDS::Wire(itownw.Key());
	wtof.AddWire(ow);
      }
      for(TopTools_ListIteratorOfListOfShape iw(lw);iw.More();iw.Next()) {
	const TopoDS_Wire& w = TopoDS::Wire(iw.Value());
	wtof.AddWire(w);
      }
    }
    wtof.MakeFaces(newFace,newfaces);
#ifdef DEB
//    Standard_Integer nnewfaces = newfaces.Extent(); // DEB
#endif
    rf = (newfaces.Extent() != 0);
  }
  else {
    rf = TopOpeBRepTool::RegularizeFace(newFace,ownw,newfaces);
  }
  
  if (!rf) {
    LOF.Append(newFace);
    return;
  }
  
#ifdef DEB
  if (tSPSFF) { cout<<"RegularizeFace "<<iF<<endl; debregufa(iF); }
#endif
  
  // LOF = nouvelles faces regularisees de newFace
  TopTools_ListIteratorOfListOfShape itlnf(newfaces);
  for (; itlnf.More(); itlnf.Next()) 
    LOF.Append(TopoDS::Face(itlnf.Value()));
  
  // mise a jour des aretes decoupees
  // Edge(FF) = {E}, E-->Split(E) = {E'}, E'-->myESplits(E') = {E''}

  TopTools_MapOfShape menf; // menf = aretes de newFace
  TopExp_Explorer x;
  for (x.Init(newFace,TopAbs_EDGE);x.More();x.Next()) {
    const TopoDS_Shape& E = x.Current();
    menf.Add(E);
  }
  
  // lfsdFF = faces SameDomain de FF
  TopTools_ListOfShape lfsdFF,lfsdFF1,lfsdFF2;
  GFindSamDom(FF,lfsdFF1,lfsdFF2);
  lfsdFF.Append(lfsdFF1);
  lfsdFF.Append(lfsdFF2);
  
  TopTools_ListIteratorOfListOfShape itlfsdFF(lfsdFF);
  for (; itlfsdFF.More(); itlfsdFF.Next()) {
    const TopoDS_Shape& fsdFF = itlfsdFF.Value();

#ifdef DEB
    Standard_Integer ifsdFF=0;Standard_Boolean tSPSfsdFF=GtraceSPS(fsdFF,ifsdFF);
    if (tSPSfsdFF) debregufa(ifsdFF);
#endif    

    Standard_Integer rankfsdFF = GShapeRank(fsdFF);
    TopAbs_State stafsdFF = (rankfsdFF == 1) ? myState1 : myState2;
#ifdef DEB
//    Standard_Boolean issplitfsdFF = IsSplit(fsdFF,stafsdFF);
#endif

/*#ifdef DEB
    const TopTools_ListOfShape& lspfsdFF = Splits(fsdFF,stafsdFF);
    Standard_Integer nlspfsdFF = lspfsdFF.Extent();
#endif*/
    
    // iteration sur les aretes de fsdFF
    for (x.Init(fsdFF,TopAbs_EDGE);x.More();x.Next()) {

      //fsdFFe : 1 edge de fsdFF = 1 face SameDomain de FF
      const TopoDS_Shape& fsdFFe = x.Current(); 

#ifdef DEB
      Standard_Integer ifsdFFe = 0;Standard_Boolean tSPSfsdFFe=GtraceSPS(fsdFFe,ifsdFFe);
      if (tSPSfsdFFe) debregufa(ifsdFFe);
#endif    
      
      // a priori, on ne peut avoir plus de deux etats splites
      // sur l'arete , soit (IN + ON) , soit (OUT + ON) 
      for (Standard_Integer iiista = 1; iiista <= 2; iiista++ ) {
	TopAbs_State stafsdFFe = stafsdFF;
	if (iiista == 2) stafsdFFe = TopAbs_ON;
	
	TopTools_ListOfShape& lspfsdFFe = ChangeSplit(fsdFFe,stafsdFFe);
#ifdef DEB
//	Standard_Boolean issplitfsdFFe = IsSplit(fsdFFe,stafsdFFe);
//	Standard_Integer nlspfsdFFe = lspfsdFFe.Extent();
#endif    
	  
	for (TopTools_ListIteratorOfListOfShape it(lspfsdFFe);it.More();it.Next()) {
	  
	  // fsdFFe (Cf supra E) a ete splittee, espfdsFFe = arete splittee de fsdFFe
	  
	  const TopoDS_Shape& espfsdFFe = it.Value();
	  Standard_Boolean inmenf = menf.Contains(espfsdFFe);
	  if (!inmenf) continue;
	  
	  // fsdFFe (Cf supra E) a ete splittee, espfdsFFe = arete splittee de fsdFFe
	  // espfsdFFe est une arete de Split(fsdFFe) ET figure dans newFace (Cf supra E')
	  
	  Standard_Boolean resplitloc = myESplits.IsBound(espfsdFFe);
	  if (resplitloc) {
	    
	    // fsdFFe (Cf supra E) a ete splittee, espfdsFFe = arete splittee de fsdFFe
	    // espfsdFFe est une arete de Split(fsdFFe) ET figure dans newFace (Cf supra E')
	    // espfsdFFe de newFace a ete redecoupee par RegularizeWires
	    
	    // son decoupage lresplit est stocke dans la DS du Builder
	    const TopTools_ListOfShape& lresplit = myESplits.Find(espfsdFFe); //Cf supra E''
	    
	    // on memorise que espfsdFFe est redecoupee ...
	    myMemoSplit.Add(espfsdFFe);
	    
	    // on stocke le nouveau decoupage de espfsdFFe dans la DS du builder ...
	    TopTools_ListOfShape& lsp = ChangeSplit(espfsdFFe,stafsdFFe);  
	    GCopyList(lresplit,lsp);
	  }
	} // it.More
      } // iiista
    } // explore(fsdFF,TopAbs_EDGE)
  } // itlfsdFF.More()

#ifdef DRAW
  if (tSPSFF) debregufa(iF);
  if (tSPSFF && savfregu) {
    TCollection_AsciiString str("fregu"); str = str + iF;
    DBRep::Set(str.ToCString(),newFace);
    cout<<"newFace "<<str<<" built on face "<<iF<<" saved"<<endl;
  }
#endif
  
} // RegularizeFace