0028883: Invalid result of Section operation
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_SplitFace.hxx
CommitLineData
b311480e 1// Created on: 1995-09-12
2// Created by: Jean Yves LEBEY
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#ifndef _TopOpeBRepBuild_SplitFace_HeaderFile
18#define _TopOpeBRepBuild_SplitFace_HeaderFile
19
20#include <TopOpeBRepBuild_WireEdgeSet.hxx>
21#include <TopOpeBRepBuild_FaceBuilder.hxx>
22
0797d9d3 23#ifdef OCCT_DEBUG
7fd59977 24Standard_EXPORT void debspf(const Standard_Integer i) {cout<<"++ debspf"<<i<<endl;}
25#endif
26
27//=======================================================================
28//function : SplitFace
29//purpose :
30//=======================================================================
31
32void TopOpeBRepBuild_Builder::SplitFace(const TopoDS_Shape& Foriented,
33 const TopAbs_State ToBuild1,
34 const TopAbs_State ToBuild2)
35{
0797d9d3 36#ifdef OCCT_DEBUG
7fd59977 37 if(TopOpeBRepBuild_GetcontextSF2()){
38 SplitFace2(Foriented,ToBuild1,ToBuild2);
39 return;
40 }
41#endif
42 SplitFace1(Foriented,ToBuild1,ToBuild2);
43 return;
44}
45
46//=======================================================================
47//function : SplitFace1
48//purpose : tout dans le meme edge set
49//=======================================================================
50
51void TopOpeBRepBuild_Builder::SplitFace1(const TopoDS_Shape& Foriented,
52 const TopAbs_State ToBuild1,
53 const TopAbs_State ToBuild2)
54{
55 // process connect connect
56 // operation tobuild1 tobuild2 face F to 1 to 2
57 // --------- -------- -------- ------- ------- -------
58 // common IN IN yes yes yes
59 // fuse OUT OUT yes yes yes
60 // cut 1-2 OUT IN yes yes no
61 // cut 2-1 IN OUT yes yes no
62 //
63 Standard_Boolean tosplit = ToSplit(Foriented,ToBuild1);
64 if ( ! tosplit ) return;
65
66 Standard_Boolean RevOri1 = Reverse(ToBuild1,ToBuild2);
67 Standard_Boolean RevOri2 = Reverse(ToBuild2,ToBuild1);
68 Standard_Boolean ConnectTo1 = Standard_True;
69 Standard_Boolean ConnectTo2 = Standard_False;
70
71 // work on a FORWARD face <Fforward>
72 TopoDS_Shape Fforward = Foriented;
73 myBuildTool.Orientation(Fforward,TopAbs_FORWARD);
74
75 // build the list of faces to split : LF1, LF2
76 TopTools_ListOfShape LF1,LF2;
77 LF1.Append(Fforward);
78 FindSameDomain(LF1,LF2);
79 Standard_Integer n1 = LF1.Extent();
80 Standard_Integer n2 = LF2.Extent();
81
82 // SplitFace on a face having other same domained faces on the
83 // other shape : do not reverse orientation of faces in FillFace
84 if (!n2) RevOri1 = Standard_False;
85 if (!n1) RevOri2 = Standard_False;
86
87 // Create an edge set <WES> connected by vertices
88 // ----------------------------------------------
89 TopOpeBRepBuild_WireEdgeSet WES(Fforward,this);
90
0797d9d3 91#ifdef OCCT_DEBUG
7fd59977 92 Standard_Boolean tSPF=TopOpeBRepBuild_GettraceSPF();
93 Standard_Integer iFace=myDataStructure->Shape(Foriented);
94 if(tSPF){cout<<endl;GdumpSHASTA(Foriented,ToBuild1,"=== SplitFace ");}
95 if(tSPF){GdumpSAMDOM(LF1, (char *) "1 : ");GdumpSAMDOM(LF2, (char *) "2 : ");}
96 if(tSPF) debspf(iFace);
97#endif
98
99 TopTools_ListIteratorOfListOfShape itLF1,itLF2;
100
101 for (itLF1.Initialize(LF1); itLF1.More(); itLF1.Next()) {
102 const TopoDS_Shape& Fcur = itLF1.Value();
103// myDataStructure->Shape(Fcur);//DEB
104 FillFace(Fcur,ToBuild1,LF2,ToBuild2,WES,RevOri1);
105 }
106
107 for (itLF2.Initialize(LF2); itLF2.More(); itLF2.Next()) {
108 const TopoDS_Shape& Fcur = itLF2.Value();
109// myDataStructure->Shape(Fcur);//DEB
110 FillFace(Fcur,ToBuild2,LF1,ToBuild1,WES,RevOri2);
111 }
112
113 // Add the intersection edges to edge set WES
114 // -----------------------------------------
115 AddIntersectionEdges(Fforward,ToBuild1,RevOri1,WES);
116
0797d9d3 117#ifdef OCCT_DEBUG
7fd59977 118 Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(Fforward,iF);
119 if(tSPS) WES.DumpSS();
120#endif
121
122 // Create a Face Builder FBU
123 // ------------------------
124 TopOpeBRepBuild_FaceBuilder FBU;
125 FBU.InitFaceBuilder(WES,Fforward,Standard_False); //forceclass = False
126
127 // Build the new faces
128 // -------------------
129 TopTools_ListOfShape& FaceList = ChangeMerged(Fforward,ToBuild1);
130 MakeFaces(Fforward,FBU,FaceList);
131
132 // connect new faces as faces built <ToBuild1> on LF1 faces
133 // --------------------------------------------------------
134 for (itLF1.Initialize(LF1); itLF1.More(); itLF1.Next()) {
135 TopoDS_Shape Fcur = itLF1.Value();
136 MarkSplit(Fcur,ToBuild1);
137 TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild1);
138 if ( ConnectTo1 ) FL = FaceList;
139 }
140
141 // connect new faces as faces built <ToBuild2> on LF2 faces
142 // --------------------------------------------------------
143 for (itLF2.Initialize(LF2); itLF2.More(); itLF2.Next()) {
144 TopoDS_Shape Fcur = itLF2.Value();
145 MarkSplit(Fcur,ToBuild2);
146 TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild2);
147 if ( ConnectTo2 ) FL = FaceList;
148 }
149
150} // SplitFace1
151
152//=======================================================================
153//function : SplitFace2
154//purpose :
155//=======================================================================
156
157void TopOpeBRepBuild_Builder::SplitFace2(const TopoDS_Shape& Foriented,
158 const TopAbs_State ToBuild1,
159 const TopAbs_State ToBuild2)
160{
161 // process connect connect
162 // operation tobuild1 tobuild2 face F to 1 to 2
163 // --------- -------- -------- ------- ------- -------
164 // common IN IN yes yes yes
165 // fuse OUT OUT yes yes yes
166 // cut 1-2 OUT IN yes yes no
167 // cut 2-1 IN OUT yes yes no
168 //
169 Standard_Boolean tosplit = ToSplit(Foriented,ToBuild1);
170 if ( ! tosplit ) return;
171
172 Standard_Boolean RevOri1 = Reverse(ToBuild1,ToBuild2);
173 Standard_Boolean RevOri2 = Reverse(ToBuild2,ToBuild1);
174 Standard_Boolean ConnectTo1 = Standard_True;
175 Standard_Boolean ConnectTo2 = Standard_False;
176
177 // work on a FORWARD face <Fforward>
178 TopoDS_Shape Fforward = Foriented;
179 myBuildTool.Orientation(Fforward,TopAbs_FORWARD);
180
181 TopTools_ListOfShape LF1 ; //liste des faces de 1 samedomain
182 TopTools_ListOfShape LF2 ; //liste des faces de 2 samedomain
183 LF1.Append(Fforward);
184 FindSameDomain(LF1,LF2);
185 Standard_Integer n1 = LF1.Extent();
186 Standard_Integer n2 = LF2.Extent();
187
0797d9d3 188#ifdef OCCT_DEBUG
7fd59977 189 Standard_Boolean tSPF = TopOpeBRepBuild_GettraceSPF();
190// Standard_Integer iFace = myDataStructure->Shape(Foriented);
191 if (tSPF) {
192 cout<<endl;
193 GdumpSHASTA(Foriented,ToBuild1,"=== SplitFace ");
194 GdumpSAMDOM(LF1, (char *) "samedomain 1 : ");
195 GdumpSAMDOM(LF2, (char *) "samedomain 2 : ");
196 }
197#endif
198
199 // SplitFace on a face having other same domained faces on the
200 // other shape : do not reverse orientation of faces in FillFace
201 if (!n2) RevOri1 = Standard_False;
202 if (!n1) RevOri2 = Standard_False;
203
204 TopTools_ListOfShape LFSO; //liste des faces de 1,2 samedomainsameorientation
205 TopTools_ListOfShape LFOO; //liste des faces de 1,2 samedomainoppositeorient
206
207 // LFSO : faces des shapes 1 ou 2, de meme orientation que Fforward.
208 // LFOO : faces des shapes 1 ou 2, d'orientation contraire que Fforward.
209 LFSO.Append(Fforward);
210 FindSameDomainSameOrientation(LFSO,LFOO);
211
212 TopTools_ListOfShape LFSO1,LFOO1; // same domain, same orientation, et du shape de F
213 TopTools_ListOfShape LFSO2,LFOO2; // "" "",du shape autre que celui de F
214
215 // on construit les parties ToBuild1 de F
216 Standard_Integer rankF = ShapeRank(Foriented);
217 Standard_Integer rankX = (rankF) ? ((rankF == 1) ? 2 : 1) : 0;
218
219 FindSameRank(LFSO,rankF,LFSO1);
220 FindSameRank(LFOO,rankF,LFOO1);
221 FindSameRank(LFSO,rankX,LFSO2);
222 FindSameRank(LFOO,rankX,LFOO2);
223
0797d9d3 224#ifdef OCCT_DEBUG
7fd59977 225 if ( tSPF ) {
226 GdumpSAMDOM(LFSO1, (char *) "LFSO1 : ");
227 GdumpSAMDOM(LFOO1, (char *) "LFOO1 : ");
228 GdumpSAMDOM(LFSO2, (char *) "LFSO2 : ");
229 GdumpSAMDOM(LFOO2, (char *) "LFOO2 : ");
230 }
231#endif
232
233 TopAbs_State tob1 = ToBuild1;
234 TopAbs_State tob2 = ToBuild2;
235 TopAbs_State tob1comp = (ToBuild1 == TopAbs_IN) ? TopAbs_OUT : TopAbs_IN;
236 TopAbs_State tob2comp = (ToBuild2 == TopAbs_IN) ? TopAbs_OUT : TopAbs_IN;
237 TopTools_ListIteratorOfListOfShape itLF ;
238
239 // --------------------------------------------------------------------
240 // traitement des faces de meme orientation que Fforward dans WireEdgeSet WES1
241 // --------------------------------------------------------------------
242 TopOpeBRepBuild_WireEdgeSet WES1(Fforward,this);
243
244 // traitement des faces de 1 same domain, same orientation que F : LFSO1
245 for (itLF.Initialize(LFSO1); itLF.More(); itLF.Next()) {
246 const TopoDS_Shape& Fcur = itLF.Value();
247// myDataStructure->Shape(Fcur);//DEB
248 // les wires de Fcur sont a comparer avec les faces de 2
249 FillFace(Fcur,tob1,LF2,tob2,WES1,RevOri1);
250 }
251
252 // traitement des faces de 2 same domain, same orientation que F : LFSO2
253 for (itLF.Initialize(LFSO2); itLF.More(); itLF.Next()) {
254 const TopoDS_Shape& Fcur = itLF.Value();
255// myDataStructure->Shape(Fcur);//DEB
256 // les wires de Fcur sont a comparer avec les faces de 1
257 FillFace(Fcur,tob2,LF1,tob1,WES1,RevOri2);
258 }
259
260 // traitement des faces de 1 same domain, oppo orientation que F : LFOO1
261 for (itLF.Initialize(LFOO1); itLF.More(); itLF.Next()) {
262 const TopoDS_Shape& Fcur = itLF.Value();
263// myDataStructure->Shape(Fcur);//DEB
264 // les wires de Fcur sont a comparer avec les faces de 2
265 FillFace(Fcur,tob1comp,LF2,ToBuild2,WES1,!RevOri1);
266 }
267
268 // traitement des faces de 2 same domain, oppo orientation que F : LFOO2
269 for (itLF.Initialize(LFOO2); itLF.More(); itLF.Next()) {
270 const TopoDS_Shape& Fcur = itLF.Value();
271// myDataStructure->Shape(Fcur);//DEB
272 // les wires de Fcur sont a comparer avec les faces de 1
273 FillFace(Fcur,tob2comp,LF1,ToBuild1,WES1,!RevOri2);
274 }
275
276 // Add the intersection edges to edge set WES1
277 // ------------------------------------------
278 AddIntersectionEdges(Fforward,ToBuild1,RevOri1,WES1);
279
280 // Create a Face Builder FBU1
281 // ------------------------
282 TopOpeBRepBuild_FaceBuilder FBU1(WES1,Fforward);
283
284 // Build the new faces
285 // -------------------
286 TopTools_ListOfShape& FaceList1 = ChangeMerged(Fforward,ToBuild1);
287 MakeFaces(Fforward,FBU1,FaceList1);
288
289 // connect new faces as faces built <ToBuild1> on LF1 faces
290 // --------------------------------------------------------
291 for (itLF.Initialize(LF1); itLF.More(); itLF.Next()) {
292 TopoDS_Shape Fcur = itLF.Value();
293 MarkSplit(Fcur,ToBuild1);
294 TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild1);
295 if ( ConnectTo1 ) FL = FaceList1;
296 }
297
298 // --------------------------------------------------------------------
299 // traitement des faces de meme orientation que Fforward dans WireEdgeSet WES2
300 // --------------------------------------------------------------------
301 TopOpeBRepBuild_WireEdgeSet WES2(Fforward,this);
302
303 // traitement des faces de 1 same domain, same orientation que F : LFSO1
304 for (itLF.Initialize(LFSO1); itLF.More(); itLF.Next()) {
305 const TopoDS_Shape& Fcur = itLF.Value();
306// myDataStructure->Shape(Fcur);//DEB
307 // les wires de Fcur sont a comparer avec les faces de 2
308 FillFace(Fcur,tob1comp,LF2,tob2,WES2,!RevOri1);
309 }
310
311 // traitement des faces de 2 same domain, same orientation que F : LFSO2
312 for (itLF.Initialize(LFSO2); itLF.More(); itLF.Next()) {
313 const TopoDS_Shape& Fcur = itLF.Value();
314// myDataStructure->Shape(Fcur);//DEB
315 // les wires de Fcur sont a comparer avec les faces de 1
316 FillFace(Fcur,tob2comp,LF1,tob1,WES2,!RevOri2);
317 }
318
319 // traitement des faces de 1 same domain, oppo orientation que F : LFOO1
320 for (itLF.Initialize(LFOO1); itLF.More(); itLF.Next()) {
321 const TopoDS_Shape& Fcur = itLF.Value();
322// myDataStructure->Shape(Fcur);//DEB
323 // les wires de Fcur sont a comparer avec les faces de 2
324 FillFace(Fcur,tob1,LF2,ToBuild2,WES2,RevOri1);
325 }
326
327 // traitement des faces de 2 same domain, oppo orientation que F : LFOO2
328 for (itLF.Initialize(LFOO2); itLF.More(); itLF.Next()) {
329 const TopoDS_Shape& Fcur = itLF.Value();
330// myDataStructure->Shape(Fcur);//DEB
331 // les wires de Fcur sont a comparer avec les faces de 1
332 FillFace(Fcur,tob2,LF1,ToBuild1,WES2,RevOri2);
333 }
334
335 // Add the intersection edges to edge set WES2
336 // ------------------------------------------
337 AddIntersectionEdges(Fforward,ToBuild2,RevOri2,WES2);
338
339 // Create a Face Builder FBU2
340 // -------------------------
341 TopOpeBRepBuild_FaceBuilder FBU2(WES2,Fforward);
342
343 // Build the new faces
344 // -------------------
345 TopTools_ListOfShape& FaceList2 = ChangeMerged(Fforward,ToBuild2);
346 MakeFaces(Fforward,FBU2,FaceList2);
347
348 // connect new faces as faces built <ToBuild2> on LF2 faces
349 // --------------------------------------------------------
350 for (itLF.Initialize(LF2); itLF.More(); itLF.Next()) {
351 TopoDS_Shape Fcur = itLF.Value();
352 MarkSplit(Fcur,ToBuild2);
353 TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild2);
354 if ( ConnectTo2 ) FL = FaceList2;
355 }
356
357} // SplitFace2
358
359
360#if 0
361//=======================================================================
362//function : SplitFaceOK
363//purpose : tout dans le meme edge set
364//=======================================================================
365
366void TopOpeBRepBuild_Builder::SplitFaceOK(const TopoDS_Shape& Foriented,
367 const TopAbs_State ToBuild1,
368 const TopAbs_State ToBuild2)
369{
370 // process connect connect
371 // operation tobuild1 tobuild2 face F to 1 to 2
372 // --------- -------- -------- ------- ------- -------
373 // common IN IN yes yes yes
374 // fuse OUT OUT yes yes yes
375 // cut 1-2 OUT IN yes yes no
376 // cut 2-1 IN OUT yes yes no
377 //
378 Standard_Boolean tosplit = ToSplit(Foriented,ToBuild1);
379 if ( ! tosplit ) return;
380
381 Standard_Boolean RevOri1 = Reverse(ToBuild1,ToBuild2);
382 Standard_Boolean RevOri2 = Reverse(ToBuild2,ToBuild1);
383 Standard_Boolean ConnectTo1 = Standard_True;
384 Standard_Boolean ConnectTo2 = Standard_False;
385
386 // work on a FORWARD face <Fforward>
387 TopoDS_Shape Fforward = Foriented;
388 myBuildTool.Orientation(Fforward,TopAbs_FORWARD);
389
390 // build the list of faces to split : LF1, LF2
391 TopTools_ListOfShape LF1,LF2;
392 LF1.Append(Fforward);
393 FindSameDomain(LF1,LF2);
394 Standard_Integer n1 = LF1.Extent();
395 Standard_Integer n2 = LF2.Extent();
396
397 // SplitFace on a face having other same domained faces on the
398 // other shape : do not reverse orientation of faces in FillFace
399 if (!n2) RevOri1 = Standard_False;
400 if (!n1) RevOri2 = Standard_False;
401
402 // Create an edge set <WES> connected by vertices
403 // ---------------------------------------------
404 TopOpeBRepBuild_WireEdgeSet WES(Fforward,this);
405
0797d9d3 406#ifdef OCCT_DEBUG
7fd59977 407 Standard_Boolean tSPF = TopOpeBRepBuild_GettraceSPF();
408 Standard_Integer iFace = myDataStructure->Shape(Foriented);
409 if(tSPF){cout<<endl;GdumpSHASTA(Foriented,ToBuild1,"=== SplitFaceOK ");}
410 if(tSPF){GdumpSAMDOM(LF1,"1 : ");GdumpSAMDOM(LF2,"2 : ");}
411#endif
412
413 TopTools_ListIteratorOfListOfShape itLF1,itLF2;
414
415 for (itLF1.Initialize(LF1); itLF1.More(); itLF1.Next()) {
416 const TopoDS_Shape& Fcur = itLF1.Value();
417 Standard_Integer icur = myDataStructure->Shape(Fcur);//DEB
418 FillFace(Fcur,ToBuild1,LF2,ToBuild2,WES,RevOri1);
419 }
420
421 for (itLF2.Initialize(LF2); itLF2.More(); itLF2.Next()) {
422 const TopoDS_Shape& Fcur = itLF2.Value();
423 Standard_Integer icur = myDataStructure->Shape(Fcur);//DEB
424 FillFace(Fcur,ToBuild2,LF1,ToBuild1,WES,RevOri2);
425 }
426
427 // Add the intersection edges to edge set WES
428 // -----------------------------------------
429 AddIntersectionEdges(Fforward,ToBuild1,RevOri1,WES);
430
431 // Create a Face Builder FBU
432 // ------------------------
433 TopOpeBRepBuild_FaceBuilder FBU(WES,Fforward);
434
435 // Build the new faces
436 // -------------------
437 TopTools_ListOfShape& FaceList = ChangeMerged(Fforward,ToBuild1);
438 MakeFaces(Fforward,FBU,FaceList);
439
440 // connect new faces as faces built <ToBuild1> on LF1 faces
441 // --------------------------------------------------------
442 for (itLF1.Initialize(LF1); itLF1.More(); itLF1.Next()) {
443 TopoDS_Shape Fcur = itLF1.Value();
444 MarkSplit(Fcur,ToBuild1);
445 TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild1);
446 if ( ConnectTo1 ) FL = FaceList;
447 }
448
449 // connect new faces as faces built <ToBuild2> on LF2 faces
450 // --------------------------------------------------------
451 for (itLF2.Initialize(LF2); itLF2.More(); itLF2.Next()) {
452 TopoDS_Shape Fcur = itLF2.Value();
453 MarkSplit(Fcur,ToBuild2);
454 TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild2);
455 if ( ConnectTo2 ) FL = FaceList;
456 }
457
458} // SplitFaceOK
459
460// #if 0
461#endif
462
463//#ifndef _TopOpeBRepBuild_SplitFace_HeaderFile
464#endif