Test for 0022778: Bug in BRepMesh
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_Builder1.cxx
CommitLineData
b311480e 1// Created on: 1999-09-29
2// Created by: Maxim ZVEREV
3// Copyright (c) 1999-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22
23#include <TopOpeBRepBuild_Builder1.ixx>
24#include <TopOpeBRepTool_ShapeExplorer.hxx>
25#include <TopAbs_Orientation.hxx>
26#include <TopoDS.hxx>
27#include <TopOpeBRepDS_HDataStructure.hxx>
28#include <TopOpeBRepDS_ShapeWithState.hxx>
29#include <TopOpeBRepBuild_WireEdgeSet.hxx>
30#include <TopAbs_ShapeEnum.hxx>
31#include <TopExp.hxx>
32#include <TopOpeBRepTool_2d.hxx>
33#include <Geom2d_Curve.hxx>
34#include <BRepAdaptor_Surface.hxx>
35#include <BRep_Tool.hxx>
36#include <TopOpeBRepDS_EXPORT.hxx>
37#include <Geom2dAPI_ProjectPointOnCurve.hxx>
38#include <TopOpeBRepBuild_Tools.hxx>
39#include <BRepTopAdaptor_FClass2d.hxx>
40#include <TopOpeBRepDS_Interference.hxx>
41#include <TopOpeBRepDS_ShapeShapeInterference.hxx>
42#include <TopOpeBRepDS_ListOfInterference.hxx>
43#include <TopOpeBRepDS_ListIteratorOfListOfInterference.hxx>
44#include <TopOpeBRepDS_Transition.hxx>
45#include <TColStd_MapOfInteger.hxx>
46
47//define parameter division number as 10*e^(-PI) = 0.43213918
48const Standard_Real PAR_T = 0.43213918;
49
50static TopTools_IndexedMapOfShape mySDEdgeMap;
51
52static TopAbs_State ClassifyEdgeToFaceByOnePoint(const TopoDS_Edge& E,
53 const TopoDS_Face& F);
54
55//modified by NIZHNY-MZV Thu Apr 20 09:58:59 2000
56///////////////////
57//this variable used to separate old algo from the new one
58//because new algo can not be used in LocOpe and Mechanical Features (for the moment)
59//that's why we use new algo only in BRepAlgoAPI_BooleanOperation
60//in all other cases old algo is called (see the methods GFillSolidSFS, GFillShellSFS, etc.);
61Standard_EXPORT Standard_Boolean GLOBAL_USE_NEW_BUILDER = Standard_False;
62
63//=======================================================================
64//function : Constructor
65//purpose :
66//=======================================================================
67TopOpeBRepBuild_Builder1::TopOpeBRepBuild_Builder1(const TopOpeBRepDS_BuildTool& BT)
68 : TopOpeBRepBuild_Builder(BT)
69{
70 mySameDomMap.Clear();
71 myMapOfEdgeFaces.Clear();
72 mySplitsONtoKeep.Clear();
73 myProcessedPartsOut2d.Clear();
74 myProcessedPartsON2d.Clear();
75}
76
77//modified by NIZNHY-PKV Mon Dec 16 11:37:59 2002 f
78/*
79//=======================================================================
80//function : Destroy
81//purpose :
82//=======================================================================
83void TopOpeBRepBuild_Builder1::Destroy()
84{
85}
86*/
87//modified by NIZNHY-PKV Mon Dec 16 11:38:05 2002 t
88//=======================================================================
89//function : Clear
90//purpose :
91//=======================================================================
92void TopOpeBRepBuild_Builder1::Clear()
93{
94 TopOpeBRepBuild_Builder::Clear();
95
96// mySameDomMap.Clear();
97// myMapOfEdgeFaces.Clear();
98// mySplitsONtoKeep.Clear();
99// myProcessedPartsOut2d.Clear();
100// myProcessedPartsON2d.Clear();
101// myDataStructure -> ChangeDS().ChangeMapOfShapeWithStateObj().Clear();
102// myDataStructure -> ChangeDS().ChangeMapOfShapeWithStateTool().Clear();
103}
104
105
106//=======================================================================
107//function : Perform
108//purpose :
109//=======================================================================
110void TopOpeBRepBuild_Builder1::Perform(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
111{
112 TopOpeBRepBuild_Builder::Perform(HDS);
113}
114
115//=======================================================================
116//function : Perform
117//purpose :
118//=======================================================================
119void TopOpeBRepBuild_Builder1::Perform(const Handle(TopOpeBRepDS_HDataStructure)& HDS,
120 const TopoDS_Shape& S1,
121 const TopoDS_Shape& S2)
122{
123 //modified by NIZHNY-MZV Wed Apr 19 17:23:12 2000
124 //see the comments at the top of file about this global variable
125 if(!GLOBAL_USE_NEW_BUILDER) {
126 TopOpeBRepBuild_Builder::Perform(HDS, S1, S2);
127 return;
128 }
129
130
131 mySameDomMap.Clear();
132 myMapOfEdgeFaces.Clear();
133 mySplitsONtoKeep.Clear();
134 myProcessedPartsOut2d.Clear();
135 myProcessedPartsON2d.Clear();
136
137 myShape1 = S1; myShape2 = S2;
138 Perform(HDS);
139
140 myIsKPart = FindIsKPart();
141 if((myIsKPart == 1) || (myIsKPart == 5))
142 myIsKPart=4;
143
144 if (myIsKPart==4) {
145 // For the moment States will be calculated in case SOLID/SOLID only
146 PerformShapeWithStates();
147 }
148}
149
150//=======================================================================
151//function : MergeKPart
152//purpose :
153//=======================================================================
154void TopOpeBRepBuild_Builder1::MergeKPart(const TopAbs_State TB1,
155 const TopAbs_State TB2)
156{
157 TopOpeBRepBuild_Builder::MergeKPart(TB1, TB2);
158}
159
160//=======================================================================
161//function : MergeKPart
162//purpose :
163//=======================================================================
164void TopOpeBRepBuild_Builder1::MergeKPart()
165{
166 if ( myIsKPart == 1 ) { // iskole
167 MergeKPartiskole();
168 }
169 else if ( myIsKPart == 5 ) { // iskoletge
170 MergeKPartiskoletge();
171 }
172 else if (myIsKPart == 2) { // isdisj
173 MergeKPartisdisj();
174 }
175 else if ( myIsKPart == 3 ) { // isfafa
176 MergeKPartisfafa();
177 }
178 else if ( myIsKPart == 4 ) { // issoso
179 MergeKPartissoso();
180
181 TopTools_ListIteratorOfListOfShape its(Merged(myShape1,myState1));
182 for (; its.More(); its.Next()) {
183 CorrectResult2d(its.Value());
184 }
185 }
186
187 End();
188
189}
190
191//=======================================================================
192//function : GFillSolidSFS
193//purpose :
194//=======================================================================
195void TopOpeBRepBuild_Builder1::GFillSolidSFS(const TopoDS_Shape& SO1,
196 const TopTools_ListOfShape& LSO2,
197 const TopOpeBRepBuild_GTopo& G1,
198 TopOpeBRepBuild_ShellFaceSet& SFS)
199{
200 //modified by NIZHNY-MZV Wed Apr 19 17:23:12 2000
201 //see the comments at the top of file about this global variable
202 if(!GLOBAL_USE_NEW_BUILDER) {
203 TopOpeBRepBuild_Builder::GFillSolidSFS(SO1, LSO2, G1, SFS);
204 return;
205 }
206
207 myMapOfEdgeFaces.Clear();
208
209 TopExp::MapShapesAndAncestors(myShape1, TopAbs_EDGE, TopAbs_FACE, myMapOfEdgeFaces);
210 TopExp::MapShapesAndAncestors(myShape2, TopAbs_EDGE, TopAbs_FACE, myMapOfEdgeFaces);
211
212 TopAbs_State TB1,TB2;
213 G1.StatesON(TB1,TB2);
214
215// printf("TB1 =%d, TB2 = %d\n", TB1, TB2);
216
217 Standard_Boolean RevOri1 = G1.IsToReverse1();
218
219 TopoDS_Shape SOF = SO1;
220 mySolidToFill = TopoDS::Solid(SOF);
221
222 TopOpeBRepTool_ShapeExplorer exShell(SOF,TopAbs_SHELL);
223 for (; exShell.More(); exShell.Next()) {
224 TopoDS_Shape SH = exShell.Current();
225 Standard_Boolean hasshape = myDataStructure->HasShape(SH);
226
227 if ( ! hasshape ) {
228 // shell SH is not in DS : Get its state (to the LS02) from map and define to keep or not
229 TopAbs_State shSt = myDataStructure -> DS().GetShapeWithState(SH).State();
230 Standard_Boolean keep = (shSt == TB1) ? Standard_True : Standard_False;
231 if (keep) {
232 TopAbs_Orientation oriSH = SH.Orientation();
233 TopAbs_Orientation neworiSH = Orient(oriSH,RevOri1);
234 SH.Orientation(neworiSH);
235
236 SFS.AddShape(SH);
237 }
238 }
239 else { // shell SH has faces(s) with geometry : split SH faces
240 GFillShellSFS(SH,LSO2,G1,SFS);
241 }
242 }
243}
244
245//=======================================================================
246//function : GFillShellSFS
247//purpose :
248//=======================================================================
249void TopOpeBRepBuild_Builder1::GFillShellSFS (const TopoDS_Shape& SH,
250 const TopTools_ListOfShape& LSO2,
251 const TopOpeBRepBuild_GTopo& G1,
252 TopOpeBRepBuild_ShellFaceSet& SFS)
253{
254 //modified by NIZHNY-MZV Wed Apr 19 17:23:12 2000
255 //see the comments at the top of file about this global variable
256 if(!GLOBAL_USE_NEW_BUILDER) {
257 TopOpeBRepBuild_Builder::GFillShellSFS(SH, LSO2, G1, SFS);
258 return;
259 }
260
261 TopAbs_State TB1,TB2;
262 G1.StatesON(TB1,TB2);
263 Standard_Boolean RevOri1 = G1.IsToReverse1();
264
265 TopOpeBRepTool_ShapeExplorer exFace;
266
267 TopoDS_Shape SH1 = SH;// SH1.Orientation(TopAbs_FORWARD);
268
269 //1) process firstly same domain faces and non-interference faces
270 for (exFace.Init(SH1,TopAbs_FACE); exFace.More(); exFace.Next()) {
271 TopoDS_Shape FOR = exFace.Current();
272 if(!myDataStructure -> HasShape(FOR)) {
273 //DS doesn't contain FACE , get its state and define to keep or not
274 TopAbs_State shSt = myDataStructure -> DS().GetShapeWithState(FOR).State();
275 Standard_Boolean keep = (shSt == TB1) ? Standard_True : Standard_False;
276 if (keep) {
277 TopAbs_Orientation oriF = FOR.Orientation();
278 TopAbs_Orientation neworiF = Orient(oriF,RevOri1);
279 FOR.Orientation(neworiF);
280 SFS.AddElement(FOR);
281 }
282 continue;
283 }
284 Standard_Boolean hsd = myDataStructure->HasSameDomain(FOR);
285 if ( hsd && !mySameDomMap.Contains(FOR))
286 GFillFaceSameDomSFS(FOR,LSO2,G1,SFS);
287 }
288
289 //2 Process all other faces
290 for (exFace.Init(SH1,TopAbs_FACE); exFace.More(); exFace.Next()) {
291 TopoDS_Shape FOR = exFace.Current();
292 if(!myDataStructure -> HasShape(FOR)
293 ||
294 myDataStructure->HasSameDomain(FOR))
295 continue;
296 GFillFaceNotSameDomSFS(FOR, LSO2, G1, SFS);
297 }
298} // GFillShellSFS
299
300//=======================================================================
301//function : GFillFaceNotSameDomSFS
302//purpose :
303//=======================================================================
304void TopOpeBRepBuild_Builder1::GFillFaceNotSameDomSFS(const TopoDS_Shape& FOR,
305 const TopTools_ListOfShape& LSO2,
306 const TopOpeBRepBuild_GTopo& Gin,
307 TopOpeBRepBuild_ShellFaceSet& SFS)
308{
309 TopOpeBRepBuild_GTopo G1 = Gin;
310 Standard_Boolean RevOri = Standard_False;
311 G1.SetReverse(RevOri);
312
313 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
314
315 // work on a FORWARD face <FForward>
316 TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD);
317
318 // make a WireEdgeSet WES on face FF
319 TopOpeBRepBuild_WireEdgeSet WES(FF,this);
320
321 // Add ON parts (edges ON solid)
322 GFillONPartsWES(FOR,G1,LSO2,WES);
323
324 // save these edges
325 TopTools_ListOfShape anEdgesON;
326 TopTools_ListIteratorOfListOfShape it;
327 if (myProcessON) {
328 Standard_Boolean toRevOri = Opefus();
329 for (it.Initialize(WES.StartElements()); it.More(); it.Next())
330 anEdgesON.Append(toRevOri ? it.Value().Reversed() : it.Value());
331 myONElemMap.Clear();
332 }
333
334 // split the edges of FF : add split edges to WES
335 GFillFaceNotSameDomWES(FF,LSO2,G1,WES);
336
337 // add edges built on curves supported by FF
338 GFillCurveTopologyWES(FF,G1,WES);
339
340 myEdgeAvoid.Clear();
341
342 // mark FF as split TB1
343 MarkSplit(FF,TB1);
344
345 // build the new faces LOF on FF from the Wire/Edge set WES
346 TopTools_ListOfShape LOF;
347 GWESMakeFaces(FF,WES,LOF);
348
349 if (myProcessON && (!anEdgesON.IsEmpty() || !myONElemMap.IsEmpty())) {
350 // try to make patches with only ON parts.
351 // prepare the map of used edges to not take the same matter two times
352 TopTools_IndexedMapOfOrientedShape aMapOE;
353 for (it.Initialize(LOF); it.More(); it.Next())
354 for (TopExp_Explorer ex(it.Value(),TopAbs_EDGE); ex.More(); ex.Next())
355 aMapOE.Add(ex.Current());
356
357 FillOnPatches(anEdgesON,FOR,aMapOE);
358 myONElemMap.Clear();
359 }
360
361 // LOFS : LOF faces located TB1 / LSclass = split faces of state TB1 of FF
362 TopTools_ListOfShape& LOFS = ChangeSplit(FF,TB1);
363 LOFS.Clear();
364 GKeepShapes(FF,myEmptyShapeList,TB1,LOF,LOFS);
365
366 GSplitFaceSFS(FOR, LSO2, Gin, SFS);
367} // GFillFaceSFS
368
369//=======================================================================
370//function : GFillFaceNotSameDomWES
371//purpose :
372//=======================================================================
373void TopOpeBRepBuild_Builder1::GFillFaceNotSameDomWES(const TopoDS_Shape& FOR1,
374 const TopTools_ListOfShape& LFclass,
375 const TopOpeBRepBuild_GTopo& G1,
376 TopOpeBRepBuild_WireEdgeSet& WES)
377{
378 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
379 Standard_Boolean RevOri1 = G1.IsToReverse1();
380
381 mySourceShapes.Clear();
382
383 // work on a FORWARD face FF
384 TopoDS_Shape FF = FOR1; FF.Orientation(TopAbs_FORWARD);
385
386 TopOpeBRepTool_ShapeExplorer exWire(FF,TopAbs_WIRE);
387 for (; exWire.More(); exWire.Next()) {
388 TopoDS_Shape W = exWire.Current();
389 Standard_Boolean hasshape = myDataStructure->HasShape(W);
390
391 if ( ! hasshape ) {
392 // wire W is not in DS : get its state and define to keep or not
393 TopAbs_State shSt = myDataStructure -> DS().GetShapeWithState(W).State();
394 Standard_Boolean keep = (shSt == TB1) ? Standard_True : Standard_False;
395 if (keep || (myProcessON && shSt == TopAbs_ON)) {
396 TopAbs_Orientation oriW = W.Orientation();
397 TopAbs_Orientation neworiW = Orient(oriW,RevOri1);
398 W.Orientation(neworiW);
399 if (keep) WES.AddShape(W);
400 else myONElemMap.Add(W);
401 mySourceShapes.Add(W);
402 }
403 }
404 else { // wire W has edges(s) with geometry : split W edges
405 GFillWireNotSameDomWES(W,LFclass,G1,WES);
406 }
407 }
408 return;
409} // GFillFaceWES
410
411//=======================================================================
412//function : GFillWireNotSameDomWES
413//purpose :
414//=======================================================================
415void TopOpeBRepBuild_Builder1::GFillWireNotSameDomWES(const TopoDS_Shape& W,
416 const TopTools_ListOfShape& LSclass,
417 const TopOpeBRepBuild_GTopo& G1,
418 TopOpeBRepBuild_WireEdgeSet& WES)
419{
420 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
421 Standard_Boolean RevOri1 = G1.IsToReverse1();
422
423 TopoDS_Shape WW = W; //WW.Orientation(TopAbs_FORWARD);
424
425 TopOpeBRepTool_ShapeExplorer exEdge(WW,TopAbs_EDGE);
426 for (; exEdge.More(); exEdge.Next()) {
427 TopoDS_Shape EOR = exEdge.Current();
428 Standard_Boolean hasshape = myDataStructure->HasShape(EOR);
429
430 if ( ! hasshape ) {
431 // edge EOR is not in DS : get its state and define to keep or not
432 TopAbs_State shSt = myDataStructure -> DS().GetShapeWithState(EOR).State();
433 Standard_Boolean keep = (shSt == TB1) ? Standard_True : Standard_False;
434 if (keep || (myProcessON && shSt == TopAbs_ON)) {
435 TopAbs_Orientation oriE = EOR.Orientation();
436 TopAbs_Orientation neworiE = Orient(oriE,RevOri1);
437 EOR.Orientation(neworiE);
438 if (keep) WES.AddElement(EOR);
439 else myONElemMap.Add(EOR);
440 mySourceShapes.Add(EOR);
441 }
442 }
443 else { // wire W has edges(s) with geometry : split W edges
444 GFillEdgeNotSameDomWES(EOR,LSclass,G1,WES);
445 }
446 }
447} // GFillWireWES
448
449
450//=======================================================================
451//function : GFillEdgeNotSameDomWES
452//purpose :
453//=======================================================================
454void TopOpeBRepBuild_Builder1::GFillEdgeNotSameDomWES(const TopoDS_Shape& EOR,
455 const TopTools_ListOfShape& /*LSclass*/,
456 const TopOpeBRepBuild_GTopo& G1,
457 TopOpeBRepBuild_WireEdgeSet& WES)
458{
459 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
460 Standard_Boolean RevOri1 = G1.IsToReverse1();
461
462
463
464 TopAbs_Orientation oriE = EOR.Orientation();
465 TopAbs_Orientation neworiE = Orient(oriE,RevOri1);
466 //1) Get split parts of edge with state TB1
467 const TopTools_ListOfShape& LSE = myDataStructure -> DS().GetShapeWithState(EOR).Part(TB1);
468 TopTools_ListIteratorOfListOfShape it (LSE);
469
470 for(; it.More(); it.Next()) {
471 TopoDS_Edge newE = TopoDS::Edge(it.Value());
472 newE.Orientation(neworiE);
473 WES.AddStartElement(newE);
474 mySourceShapes.Add(newE);
475 }
476
477 //2) Get ON parts of the edge and define to keep it or not
478 const TopTools_ListOfShape& LSEOn = myDataStructure -> DS().GetShapeWithState(EOR).Part(TopAbs_ON);
479 TopTools_ListIteratorOfListOfShape itON (LSEOn);
480 for(; itON.More(); itON.Next()) {
481 TopoDS_Edge newE = TopoDS::Edge(itON.Value());
482 newE.Orientation(neworiE);
483 if(mySplitsONtoKeep.Contains(newE)) {
484 WES.AddStartElement(newE);
485 continue;
486 }
487 // we keep all degenerated edges here because FillONPartsWES can not process them
488 if(BRep_Tool::Degenerated(newE)) {
489 WES.AddStartElement(newE);
490 mySourceShapes.Add(newE);
491 }
492 if (myProcessON) {
493 myONElemMap.Add(newE);
494 mySourceShapes.Add(newE);
495 }
496 }
497} // GFillEdgeWES
498
499
500/////////////////// ALL FUNCTIONS FOR SAME DOMAIN FACES
501//=======================================================================
502//function : GFillFaceSameDomSFS
503//purpose :
504//=======================================================================
505void TopOpeBRepBuild_Builder1::GFillFaceSameDomSFS(const TopoDS_Shape& FOR,
506 const TopTools_ListOfShape& LSO2,
507 const TopOpeBRepBuild_GTopo& Gin,
508 TopOpeBRepBuild_ShellFaceSet& SFS)
509{
510 myProcessedPartsOut2d.Clear();
511 myProcessedPartsON2d.Clear();
512 myMapOfEdgeWithFaceState.Clear();
513 mySDEdgeMap.Clear();
514 mySourceShapes.Clear();
515
516 //we process all same domain faces during cycling throught the Shape1
517 if(myDataStructure -> DS().AncestorRank(FOR) != 1)
518 return;
519
520 TopOpeBRepBuild_GTopo G1 = Gin;
521
522 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
523
524 // work on a FORWARD face <FForward>
525 TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD);
526
527 // make a WireEdgeSet WES on face FF
528 TopOpeBRepBuild_WireEdgeSet WES(FF,this);
529
530 // split the edges of FF : add split edges to WES
531 GFillFaceSameDomWES(FOR,LSO2,G1,WES);
532
533 myEdgeAvoid.Clear();
534
535 // mark FF as split TB1
536 MarkSplit(FF,TB1);
537
538 // build the new faces LOF on FF from the Wire/Edge set WES
539 TopTools_ListOfShape LOF, oriLOF;
540 GWESMakeFaces(FF,WES,LOF);
541
542 // LOFS : LOF faces located TB1 / LSclass = split faces of state TB1 of FF
543 TopTools_ListOfShape& LOFS = ChangeSplit(FF,TB1);
544
545 //orientate new faces by the right way
546 Standard_Boolean OrigRev = (FOR.Orientation() == TopAbs_FORWARD ? Standard_False : Standard_True);
547 TopTools_ListIteratorOfListOfShape LOFit(LOF);
548 for(; LOFit.More(); LOFit.Next()) {
549 TopoDS_Shape aFace = LOFit.Value();
550 TopTools_IndexedMapOfShape aEM;
551 TopExp::MapShapes(aFace, TopAbs_EDGE, aEM);
552 Standard_Boolean rev = Standard_False;
553 for(Standard_Integer i = 1; i <= aEM.Extent(); i++) {
554 const TopoDS_Shape& anEdge = aEM(i);
555 if(myMapOfEdgeWithFaceState.IsBound(anEdge)) {
556 rev = (Standard_Boolean)myMapOfEdgeWithFaceState.Find(anEdge);
557 break;
558 }
559 }
560 if(OrigRev)
561 aFace.Reverse();
562
563 if(rev)
564 aFace.Reverse();
565
566 oriLOF.Append(aFace);
567 SFS.AddStartElement(aFace);
568 }
569
570 LOFS.Clear();
571 GKeepShapes(FF,myEmptyShapeList,TB1,oriLOF,LOFS);
572} // GFillFaceSFS
573
574//=======================================================================
575//function : GFillFaceSameDomWES
576//purpose :
577//=======================================================================
578void TopOpeBRepBuild_Builder1::GFillFaceSameDomWES(const TopoDS_Shape& FOR1,
579 const TopTools_ListOfShape& /*LFclass*/,
580 const TopOpeBRepBuild_GTopo& G1,
581 TopOpeBRepBuild_WireEdgeSet& WES)
582{
583 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
584
585 myBaseFaceToFill = TopoDS::Face(FOR1);
586
587 TopTools_IndexedMapOfShape curSameDomMap;
588 curSameDomMap.Add(FOR1);
589
590 Standard_Integer i, nF;
591 for(i = 1; i <= curSameDomMap.Extent(); i++) {
592 TopTools_ListIteratorOfListOfShape it = myDataStructure -> SameDomain(curSameDomMap(i));
593 for(; it.More(); it.Next()) {
594 const TopoDS_Shape& SDF = it.Value();
595 curSameDomMap.Add(SDF);
596 mySameDomMap.Add(SDF);
597
598 TopExp::MapShapes(SDF, TopAbs_EDGE, mySDEdgeMap);
599 }
600 }
601
602 nF = curSameDomMap.Extent();
603 for(i = 1; i<= nF; i++) {
604 TopoDS_Shape curF = curSameDomMap(i);
605
606 TopoDS_Shape curFF = curF;
607 curFF.Orientation(TopAbs_FORWARD);
608
609 mySDFaceToFill = TopoDS::Face(curF);
610 Standard_Integer iref = myDataStructure -> DS().AncestorRank(curFF);
611
612 TopAbs_State TB;
613 Standard_Boolean RevOri = Standard_False;
614 TopOpeBRepBuild_GTopo GFTW = G1;
615 if(iref == 1) {//object
616 TB = TB1;
617 RevOri = G1.IsToReverse1();
618 }
619 else {//tool
620 RevOri = G1.IsToReverse2();
621 TB = TB2;
622 if(RevOri)
623 GFTW = G1.CopyPermuted();
624 }
625 //we need to pass GTopo according to ancestor rank
626 GFillCurveTopologyWES(curFF,GFTW,WES);
627
628 //process ON parts from not SD faces
629 PerformONParts(curFF, curSameDomMap, G1, WES);
630
631 const TopTools_ListOfShape& LSF = myDataStructure -> DS().ShapeSameDomain(curFF);
632
633 TopOpeBRepTool_ShapeExplorer exWire(curFF,TopAbs_WIRE);
634 for (; exWire.More(); exWire.Next()) {
635 TopoDS_Shape W = exWire.Current();
636 Standard_Boolean hasshape = myDataStructure->HasShape(W);
637 TopAbs_State shSt = myDataStructure -> DS().GetShapeWithState(W).State();
638
639 if ( ! hasshape && (shSt != TopAbs_ON)) {
640 // wire W is not in DS : get its state and define to keep or not
641 Standard_Boolean keep = (shSt == TB) ? Standard_True : Standard_False;
642 if (keep) {
643 TopAbs_Orientation oriW = W.Orientation();
644 TopAbs_Orientation neworiW = Orient(oriW,RevOri);
645
646 if(myBaseFaceToFill != mySDFaceToFill)
647 TopOpeBRepBuild_Tools::UpdatePCurves(TopoDS::Wire(W),
648 TopoDS::Face(mySDFaceToFill),
649 TopoDS::Face(myBaseFaceToFill));
650 else {
651 mySourceShapes.Add(W);
652 }
653
654 TopExp_Explorer we(W, TopAbs_EDGE);
655 Standard_Boolean stateOfFaceOri = Standard_False;
656 Standard_Boolean UseEdges = Standard_False;
657 for(; we.More(); we.Next()) {
658 TopoDS_Edge EOR = TopoDS::Edge(we.Current());
659
660 TopAbs_Orientation oldori = EOR.Orientation();
661 OrientateEdgeOnFace(EOR,TopoDS::Face(myBaseFaceToFill),
662 TopoDS::Face(mySDFaceToFill), G1, stateOfFaceOri);
663
664 // OrientateEdgeOnFace(TopoDS::Edge(EOR), TopoDS::Face(myBaseFaceToFill),
665 // TopoDS::Face(mySDFaceToFill), G1, stateOfFaceOri);
666 if(EOR.Orientation() != oldori) {
667 UseEdges = Standard_True;
668 WES.AddStartElement(EOR);
669 }
670
671 myMapOfEdgeWithFaceState.Bind(EOR, (Standard_Integer)stateOfFaceOri);
672 }
673
674 if(!UseEdges) {
675 W.Orientation(neworiW);
676 WES.AddShape(W);
677 }
678 }
679 }
680 else { // wire W has edges(s) with geometry : split W edges
681 GFillWireSameDomWES(W, LSF,G1,WES);
682 }
683 }
684 }
685 return;
686} // GFillFaceWES
687
688//=======================================================================
689//function : GFillWireSameDomWES
690//purpose :
691//=======================================================================
692void TopOpeBRepBuild_Builder1::GFillWireSameDomWES(const TopoDS_Shape& W,
693 const TopTools_ListOfShape& LSclass,
694 const TopOpeBRepBuild_GTopo& G1,
695 TopOpeBRepBuild_WireEdgeSet& WES)
696{
697 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
698
699 TopoDS_Shape WW = W; //WW.Orientation(TopAbs_FORWARD);
700
701 Standard_Integer iref = myDataStructure -> DS().AncestorRank(W);
702
703 Standard_Boolean RevOri;
704 TopAbs_State TB;
705 if(iref == 1) {//object
706 TB = TB1;
707 RevOri = G1.IsToReverse1();
708 }
709 else {//tool
710 RevOri = G1.IsToReverse2();
711 TB = TB2;
712 }
713
714
715 TopOpeBRepTool_ShapeExplorer exEdge(WW,TopAbs_EDGE);
716 for (; exEdge.More(); exEdge.Next()) {
717 TopoDS_Shape EOR = exEdge.Current();
718 Standard_Boolean hasshape = myDataStructure->HasShape(EOR);
719 if ( ! hasshape ) {
720 // edge EOR is not in DS : get its state and define to keep or not
721 TopAbs_State shSt = myDataStructure -> DS().GetShapeWithState(EOR).State();
722 Standard_Boolean keep = (shSt == TB) ? Standard_True : Standard_False;
723 if (keep) {
724 TopAbs_Orientation oriE = EOR.Orientation();
725 Orient(oriE,RevOri);
726
727 if(mySDFaceToFill != myBaseFaceToFill) {
728 TopOpeBRepBuild_Tools::UpdateEdgeOnFace(TopoDS::Edge(EOR),
729 TopoDS::Face(mySDFaceToFill),
730 TopoDS::Face(myBaseFaceToFill));
731 }
732 else {
733 mySourceShapes.Add(EOR);
734 }
735
736 Standard_Boolean stateOfFaceOri = Standard_False;
737
738 OrientateEdgeOnFace(TopoDS::Edge(EOR), TopoDS::Face(myBaseFaceToFill),
739 TopoDS::Face(mySDFaceToFill), G1, stateOfFaceOri);
740 myMapOfEdgeWithFaceState.Bind(EOR, (Standard_Integer)stateOfFaceOri);
741 WES.AddElement(EOR);
742 }
743 }
744 else { // wire W has edges(s) with geometry : split W edges
745 GFillEdgeSameDomWES(EOR,LSclass,G1,WES);
746 }
747 }
748} // GFillWireWES
749
750//=======================================================================
751//function : GFillEdgeSameDomWES
752//purpose :
753//=======================================================================
754void TopOpeBRepBuild_Builder1::GFillEdgeSameDomWES(const TopoDS_Shape& EOR,
755 const TopTools_ListOfShape& LSclass,
756 const TopOpeBRepBuild_GTopo& G1,
757 TopOpeBRepBuild_WireEdgeSet& WES)
758{
759 TopAbs_State TB1,TB2, TB; G1.StatesON(TB1,TB2);
760
761 Standard_Integer iref = myDataStructure -> DS().AncestorRank(EOR);
762
763 Standard_Boolean RevOri;
764 if(iref == 1) {//object
765 TB = TB1;
766 RevOri = G1.IsToReverse1();
767 }
768 else {//tool
769 RevOri = G1.IsToReverse2();
770 TB = TB2;
771 }
772
773 TopAbs_Orientation oriE = EOR.Orientation();
774 Orient(oriE,RevOri);
775
776 //1) Get split parts of edge with state TB
777 const TopTools_ListOfShape& LSE = myDataStructure -> DS().GetShapeWithState(EOR).Part(TB);
778 TopTools_ListIteratorOfListOfShape it (LSE);
779 Standard_Boolean first = Standard_True;
780 for(; it.More(); it.Next()) {
781
782 TopoDS_Edge newE = TopoDS::Edge(it.Value());
783 newE.Orientation(oriE);
784
785 if(mySDFaceToFill != myBaseFaceToFill) {
786 TopOpeBRepBuild_Tools::UpdateEdgeOnFace(newE,
787 TopoDS::Face(mySDFaceToFill),
788 TopoDS::Face(myBaseFaceToFill));
789 }
790 else {
791 mySourceShapes.Add(newE);
792 }
793
794 Standard_Boolean stateOfFaceOri = Standard_False;
795 OrientateEdgeOnFace(newE, TopoDS::Face(myBaseFaceToFill),
796 TopoDS::Face(mySDFaceToFill), G1, stateOfFaceOri);
797 myMapOfEdgeWithFaceState.Bind(newE, (Standard_Integer)stateOfFaceOri);
798
799 WES.AddStartElement(newE);
800 }
801
802 //2) Get ON parts of the edge and define to keep it or not
803 const TopTools_ListOfShape& LSEOn = myDataStructure -> DS().GetShapeWithState(EOR).Part(TopAbs_ON);
804 first = Standard_True;
805 it.Initialize(LSEOn);
806 for(; it.More(); it.Next()) {
807
808 TopoDS_Edge aSplitPart = TopoDS::Edge(it.Value());
809 aSplitPart.Orientation(EOR.Orientation());
810
811
812 //do ON 2D computation
813 if(myDataStructure -> HasSameDomain(aSplitPart) || myDataStructure -> HasSameDomain(EOR)) {
814 Standard_Integer flag = 0;
815 //First of All : if SDFaceToFill is REVERSED we need to reverse aSplitPart
816 TopoDS_Shape eON = aSplitPart;
817 TopoDS_Shape nEOR = EOR;
818 if(mySDFaceToFill.Orientation() == TopAbs_REVERSED) {
819 eON.Reverse();
820 nEOR.Reverse();
821 }
822 TopTools_ListOfShape aListOfPieces, aListOfFaces, aListOfPieceOut2d;
823 //Out 2d pieces we compute only one time : for the Object
824 if(myProcessedPartsOut2d.Contains(eON))
825 continue;
826 flag = PerformPieceOn2D (eON, mySDFaceToFill, nEOR, aListOfPieces, aListOfFaces, aListOfPieceOut2d);
827 TopTools_ListIteratorOfListOfShape aPIt2d(aListOfPieceOut2d);
828 for(; aPIt2d.More(); aPIt2d.Next()) {
829 TopoDS_Shape aFP = aPIt2d.Value();
830 TopoDS_Shape aRP = aPIt2d.Value();
831 aFP.Reverse();
832 WES.AddStartElement(aFP);
833 WES.AddStartElement(aRP);
834 myProcessedPartsOut2d.Add(aFP);
835 }
836 TopTools_ListIteratorOfListOfShape aPIt(aListOfPieces), aFIt(aListOfFaces);
837 for(; aPIt.More(); aPIt.Next()) {
838 TopoDS_Shape aPieceToKeep = aPIt.Value();
839 const TopoDS_Shape& aPieceFace = aFIt.Value();
840 if(aPieceFace == mySDFaceToFill) {
841 Standard_Boolean IsRev = (aPieceToKeep.Orientation() == nEOR.Orientation());
842
843 Standard_Boolean stateOfFaceOri = Standard_False;
844 aPieceToKeep.Orientation(oriE);
845 OrientateEdgeOnFace(TopoDS::Edge(aPieceToKeep), TopoDS::Face(myBaseFaceToFill),
846 TopoDS::Face(mySDFaceToFill), G1, stateOfFaceOri);
847 //if edge was in not the right orientation we need to reverse it
848 if(!IsRev)
849 aPieceToKeep.Reverse();
850
851 myMapOfEdgeWithFaceState.Bind(aPieceToKeep, (Standard_Integer)stateOfFaceOri);
852
853 WES.AddStartElement(aPieceToKeep);
854 }
855 aFIt.Next();
856 }
857 if(flag) //if flag == 0 we should go to the IN2D or OUT2D
858 continue;
859 }
860
861 //do IN 2D computation
862 TopoDS_Shape aSDShape;
863 TopAbs_State aState = TopAbs_UNKNOWN;
864
865 if(LSclass.Extent() == 1) {
866 aSDShape = LSclass.First();
867 aState = ClassifyEdgeToFaceByOnePoint(aSplitPart, TopoDS::Face(aSDShape));
868 }
869 else { //if face has more than one same domain faces we need to detect for each part complement same domain face
870 TopTools_ListIteratorOfListOfShape LSClassIt(LSclass);
871 for(; LSClassIt.More(); LSClassIt.Next()) {
872 TopoDS_Face curSD = TopoDS::Face(LSClassIt.Value());
873 aState = ClassifyEdgeToFaceByOnePoint(aSplitPart,curSD);
874 // aState = ClassifyEdgeToFaceByOnePoint(aSplitPart, TopoDS::Face(curSD));
875 if(aState == TopAbs_IN || aState == TopAbs_ON) {
876 aSDShape = curSD;
877 break;
878 }
879 }
880 }
881
882 //we should process all same domain edges (ON2D) in the code above
883 //and we can not proceess edges with UNKNOWN state
884 if(aState == TopAbs_ON || aState == TopAbs_UNKNOWN)
885 continue;
886
887 //OUT2D computation
888 if(aState == TopAbs_OUT || aSDShape.IsNull()) {
889 //it means that SplitPart is ON
890 //comparing with myShape2 but Out of all this SD faces
891 //so we need to find adjacent faces and they also MUST be SameDomain and compute all in reverse order
892
893 Standard_Boolean keep = Standard_False;
894
895 if(aSDShape.IsNull()) {
896 aSDShape = LSclass.First();
897 }
898
899 //compute adjacents
900 TopoDS_Shape aAdjSDFace;
901 const TopTools_ListOfShape& aFEL = myMapOfEdgeFaces.FindFromKey(EOR);
902 TopTools_ListIteratorOfListOfShape aEFIt(aFEL);
903 if(aFEL.Extent() <= 2) { //we don't compute adjacent if we have more than one adjacent face
904 for(; aEFIt.More(); aEFIt.Next()) {
905 if(mySDFaceToFill.IsSame(aEFIt.Value()))
906 continue;
907 else {
908 if(myDataStructure -> HasSameDomain(aEFIt.Value())) {
909 aAdjSDFace = aEFIt.Value();
910 break;
911 }
912 }
913 }
914 }
915
916 if(!aAdjSDFace.IsNull()) {
917 TopTools_IndexedMapOfShape aEAdjMap;
918 TopExp::MapShapes(aAdjSDFace, TopAbs_EDGE, aEAdjMap);
919
920 Standard_Integer index = aEAdjMap.FindIndex(EOR);
921 TopoDS_Shape AdjEOR = aEAdjMap.FindKey(index);
922
923 TopTools_ListIteratorOfListOfShape it1 = myDataStructure -> SameDomain(aAdjSDFace);
924 TopoDS_Shape aSDToAdjFace = it1.Value();
925
926 TopoDS_Edge aSplitP = aSplitPart;
927 aSplitP.Orientation(AdjEOR.Orientation());
928
929 gp_Vec aTg, aN1, aN2,aN3, aBiN;
930 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(TopoDS::Face(aSDToAdjFace), aSplitP, aN2);
931 if(aSDToAdjFace.Orientation() == TopAbs_REVERSED)
932 aN2.Reverse();
933
934 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(TopoDS::Face(aAdjSDFace), aSplitP, aN3);
935 if(aAdjSDFace.Orientation() == TopAbs_REVERSED)
936 aN3.Reverse();
937
938 TopOpeBRepBuild_Tools::GetTangentToEdge(aSplitP, aTg);
939 if (aSplitP.Orientation() == TopAbs_REVERSED) {
940 aTg.Reverse();
941 }
942
943 aBiN = aTg^aN2;
944
945 Standard_Real scalarPr = 0.;
946
947 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(TopoDS::Face(mySDFaceToFill), aSplitP, aN1);
948 if(mySDFaceToFill.Orientation() == TopAbs_REVERSED)
949 aN1.Reverse();
950 scalarPr = aBiN*aN1;
951
952 if(fabs(scalarPr) <= 1e-10) {//try to step inside
953 TopOpeBRepBuild_Tools::GetNormalInNearestPoint(TopoDS::Face(mySDFaceToFill), aSplitP, aN1);
954 if(mySDFaceToFill.Orientation() == TopAbs_REVERSED)
955 aN1.Reverse();
956 scalarPr = aBiN*aN1;
957 if(fabs(scalarPr) <= 1e-10) // this can not be
958 keep = (TB == TopAbs_IN); //just to do something
959 }
960
961 TopAbs_State aPartState = (scalarPr > 0) ? TopAbs_IN : TopAbs_OUT;
962
963 keep = (aPartState == TB) ? Standard_True : Standard_False;
964 }
965 else { //if aAdjFace.IsNull() - it must not happen
966 keep = (TB == TopAbs_IN);
967 }
968
969 if(keep) {
970 if(mySDFaceToFill != myBaseFaceToFill) {
971 TopOpeBRepBuild_Tools::UpdateEdgeOnFace(aSplitPart,
972 TopoDS::Face(mySDFaceToFill),
973 TopoDS::Face(myBaseFaceToFill));
974 }
975 else {
976 mySourceShapes.Add(aSplitPart);
977 }
978
979 Standard_Boolean stateOfFaceOri = Standard_False;
980 OrientateEdgeOnFace(aSplitPart, TopoDS::Face(myBaseFaceToFill),
981 TopoDS::Face(mySDFaceToFill), G1, stateOfFaceOri);
982 myMapOfEdgeWithFaceState.Bind(aSplitPart, (Standard_Integer)stateOfFaceOri);
983
984 WES.AddStartElement(aSplitPart);
985 }
986 continue;
987 }
988 //end case OUT2D
989
990 //IN2D computation
991 TopoDS_Edge aSplitP = aSplitPart;
992 aSplitP.Orientation(EOR.Orientation());
993 TopoDS_Face aSDFace = TopoDS::Face(aSDShape);
994
995 Standard_Boolean keep = Standard_False;
996 PerformPieceIn2D(aSplitPart, TopoDS::Edge(EOR),
997 TopoDS::Face(mySDFaceToFill), aSDFace, G1, keep);
998
999 if(keep) {
1000 mySplitsONtoKeep.Add(aSplitPart);
1001
1002 //compute orientation of the future face
1003 Standard_Boolean stateOfFaceOri = Standard_False;
1004 OrientateEdgeOnFace(aSplitPart, TopoDS::Face(myBaseFaceToFill), aSDFace, G1, stateOfFaceOri);
1005 myMapOfEdgeWithFaceState.Bind(aSplitPart, (Standard_Integer)stateOfFaceOri);
1006
1007 if(myBaseFaceToFill == mySDFaceToFill) {
1008 mySourceShapes.Add(aSplitPart);
1009 }
1010
1011 WES.AddStartElement(aSplitPart);
1012 }
1013 }
1014} // GFillEdgeWES
1015
1016Standard_IMPORT Standard_Boolean TopOpeBRepBuild_FUN_aresamegeom(const TopoDS_Shape& S1,const TopoDS_Shape& S2);
1017
1018//=======================================================================
1019//function : PerformONParts
1020//purpose :
1021//=======================================================================
1022void TopOpeBRepBuild_Builder1::PerformONParts(const TopoDS_Shape& FOR1,
1023 const TopTools_IndexedMapOfShape& /*SDFaces*/,
1024 const TopOpeBRepBuild_GTopo& G1,
1025 TopOpeBRepBuild_WireEdgeSet& WES)
1026{
1027 TopAbs_State ETB1,ETB2, ETB; G1.StatesON(ETB1,ETB2);
1028 TopAbs_State FTB1,FTB2, FTB; G1.StatesON(FTB1,FTB2);
1029
1030 Standard_Integer iref = myDataStructure -> DS().AncestorRank(FOR1);
1031
1032 Standard_Boolean RevOri;
1033
1034 if(iref == 1) {//object
1035 FTB = FTB1;
1036 RevOri = G1.IsToReverse1();
1037 }
1038 else {//tool
1039 RevOri = G1.IsToReverse2();
1040 FTB = FTB2;
1041 }
1042
1043 //3 Process parts that can not be found on SD faces but must be included because they are ON the SD faces
1044 const TopOpeBRepDS_ListOfInterference& LI = myDataStructure -> DS().ShapeInterferences(FOR1);
1045 for (TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI);ILI.More();ILI.Next() ) {
1046 const Handle(TopOpeBRepDS_Interference)& I=ILI.Value();
1047 Handle(TopOpeBRepDS_ShapeShapeInterference) SSI
1048 = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I);
1049
1050 if (SSI.IsNull())
1051 continue;
1052
1053 TopOpeBRepDS_Kind GT,ST;
1054 Standard_Integer GI,SI;
1055 FDS_data(SSI,GT,GI,ST,SI);
1056 if (GT != TopOpeBRepDS_EDGE || ST != TopOpeBRepDS_FACE)
1057 continue;
1058
1059 const TopoDS_Edge& EG=TopoDS::Edge(myDataStructure -> DS().Shape(GI, Standard_False));
1060 //we process only the edges which are not from the current SD faces
1061 if(mySDEdgeMap.Contains(EG))
1062 continue;
1063
1064 //take ON splits of the edge
1065 const TopTools_ListOfShape& splON = myDataStructure -> DS().GetShapeWithState(EG).Part(TopAbs_ON);
1066 if(!splON.Extent())
1067 continue;
1068
1069 const TopOpeBRepDS_Transition& aTr = SSI -> Transition();
1070
1071 Standard_Integer irefE = myDataStructure -> DS().AncestorRank(EG);
1072
1073 Standard_Boolean RevOriE;
1074 if(irefE == 1) {//object
1075 ETB = ETB1;
1076 RevOriE = G1.IsToReverse1();
1077 }
1078 else {//tool
1079 RevOriE = G1.IsToReverse2();
1080 ETB = ETB2;
1081 }
1082
1083
1084 //take list of edge faces
1085 const TopTools_ListOfShape& EdgeFaces = myMapOfEdgeFaces.FindFromKey(EG);
1086 TopExp_Explorer Exp;
1087
1088 for(TopTools_ListIteratorOfListOfShape itON(splON); itON.More(); itON.Next()) {
1089 TopoDS_Shape newE = itON.Value();
1090
1091 TopoDS_Shape aSDShape = FOR1;
1092 TopAbs_State aState = TopAbs_UNKNOWN;
1093
1094 aState = ClassifyEdgeToFaceByOnePoint(TopoDS::Edge(newE), TopoDS::Face(FOR1));
1095 if(!(aState == TopAbs_IN || aState == TopAbs_ON))
1096 continue;
1097
1098 Standard_Boolean keep = Standard_False;
1099 TopoDS_Face aSDFace = TopoDS::Face(aSDShape);
1100
1101 TopAbs_Orientation oriE;
1102 TopAbs_Orientation neworiE;
1103
1104 for(TopTools_ListIteratorOfListOfShape it(EdgeFaces); it.More(); it.Next()) {
1105 const TopoDS_Shape& FOR = it.Value();
1106 Exp.Init(FOR, TopAbs_EDGE);
1107 TopoDS_Shape EOR;
1108 for(; Exp.More(); Exp.Next()) {
1109 EOR = Exp.Current();
1110 if(EG.IsSame(EOR))
1111 break;
1112 }
1113
1114 if(EOR.IsNull())
1115 continue;
1116
1117 //else we have found a face , we process it
1118 oriE = EOR.Orientation();
1119 neworiE = Orient(oriE,RevOriE);
1120
1121 newE.Orientation(oriE);
1122 gp_Vec aTg, aN2,aN3, aBiN;
1123 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(TopoDS::Face(FOR), TopoDS::Edge(newE), aN2);
1124 if(FOR.Orientation() == TopAbs_REVERSED)
1125 aN2.Reverse();
1126 TopOpeBRepBuild_Tools::GetTangentToEdge(TopoDS::Edge(newE), aTg);
1127 if (newE.Orientation() == TopAbs_REVERSED) {
1128 aTg.Reverse();
1129 }
1130 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(aSDFace, TopoDS::Edge(newE), aN3);
1131 if(aSDFace.Orientation() == TopAbs_REVERSED)
1132 aN3.Reverse();
1133 keep = Standard_False;
1134 aBiN = aTg^aN2;
1135 Standard_Real scalarPr = 0.;
1136 scalarPr = aBiN*aN3;
1137
1138 if(fabs(scalarPr) <= 1e-10) {//try to step inside
1139 TopOpeBRepBuild_Tools::GetNormalInNearestPoint(TopoDS::Face(FOR), TopoDS::Edge(newE), aN2);
1140 if(FOR.Orientation() == TopAbs_REVERSED)
1141 aN2.Reverse();
1142 aBiN = aTg^aN2;
1143 scalarPr = aBiN*aN3;
1144 if(fabs(scalarPr) <= 1e-10)
1145 continue;
1146 }
1147 TopAbs_State aPartState = (scalarPr > 0) ? TopAbs_IN : TopAbs_OUT;
1148 keep = (aPartState == ETB) ? Standard_True : Standard_False;
1149 if(keep)
1150 break;
1151 }
1152
1153 if(keep) {
1154 //compute orientation of the future face
1155 Standard_Boolean stateOfFaceOri = Standard_False;
1156 gp_Vec aNbf, aNsf , OrigNormalbf; //aTg, aBiN, aOut;
1157 TopoDS_Edge aLocalEdge = TopoDS::Edge(newE);
1158 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(aSDFace,aLocalEdge, aNsf);
1159 // TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(TopoDS::Face(aSDFace), TopoDS::Edge(newE), aNsf);
1160 if(aSDFace.Orientation() == TopAbs_REVERSED)
1161 aNsf.Reverse();
1162 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(TopoDS::Face(myBaseFaceToFill), TopoDS::Edge(newE), OrigNormalbf);
1163 aNbf = OrigNormalbf;
1164 if(myBaseFaceToFill.Orientation() == TopAbs_REVERSED)
1165 aNbf.Reverse();
1166
1167 if(aNsf*aNbf < 0) {
1168 stateOfFaceOri = Standard_True;
1169 }
1170
1171 if(myDataStructure -> DS().AncestorRank(aSDFace) == 2) {//for tool we need to reverse face in cut
1172 if(Opec12() || Opec21()) {
1173 stateOfFaceOri = !stateOfFaceOri;
1174 }
1175 }
1176
1177 //adjust orientation of the edge
1178 neworiE = aTr.Orientation(FTB);
1179 Standard_Boolean samegeom = TopOpeBRepBuild_FUN_aresamegeom(FOR1,myBaseFaceToFill);
1180 if (!samegeom) {
1181 neworiE = TopAbs::Complement(neworiE);
1182 }
1183 newE.Orientation(neworiE);
1184
1185 myMapOfEdgeWithFaceState.Bind(newE, (Standard_Integer)stateOfFaceOri);
1186 WES.AddStartElement(newE);
1187 }
1188 }//end iteration on splON
1189 }//end iteration of interferences
1190}
1191
1192//=======================================================================
1193//function : GWESMakeFaces
1194//purpose :
1195//=======================================================================
1196void TopOpeBRepBuild_Builder1::GWESMakeFaces(const TopoDS_Shape& FF,
1197 TopOpeBRepBuild_WireEdgeSet& WES,
1198 TopTools_ListOfShape& LOF)
1199{
1200 TopOpeBRepBuild_Builder::GWESMakeFaces(FF, WES, LOF);
1201 TopTools_ListIteratorOfListOfShape aLOFit(LOF);
1202 TopTools_ListOfShape corrLOF;
1203 if(myIsKPart == 4) {
1204 for(; aLOFit.More(); aLOFit.Next()) {
1205 const TopoDS_Shape& ff = aLOFit.Value();
1206 TopoDS_Shape corrFF;
1207 TopOpeBRepBuild_Tools::NormalizeFace(ff, corrFF);
1208 corrLOF.Append(corrFF);
1209 }
1210 }
1211 else
1212 corrLOF.Assign(LOF);
1213
1214 LOF.Clear(); LOF.Assign(corrLOF);
1215
1216 //corect face2d
1217 aLOFit.Initialize(corrLOF);
1218 TopTools_ListOfShape corrLOF1;
1219 for(; aLOFit.More(); aLOFit.Next()) {
1220 const TopoDS_Shape& ff = aLOFit.Value();
1221 TopoDS_Shape corrFF;
1222 TopOpeBRepBuild_Tools::CorrectFace2d(ff, corrFF, mySourceShapes, myMapOfCorrect2dEdges);
1223 corrLOF1.Append(corrFF);
1224 }
1225
1226 LOF.Clear(); LOF.Assign(corrLOF1);
1227}
1228
1229//=======================================================================
1230//function : PerformPieceIN2d
1231//purpose :
1232//=======================================================================
1233void TopOpeBRepBuild_Builder1::PerformPieceIn2D(const TopoDS_Edge& EdgeToPerform,
1234 const TopoDS_Edge& EOR,
1235 const TopoDS_Face& edgeFace,
1236 const TopoDS_Face& toFace,
1237 const TopOpeBRepBuild_GTopo& G1,
1238 Standard_Boolean& keep)
1239{
1240 keep = Standard_False;
1241
1242 TopAbs_State TB1,TB2, TB; G1.StatesON(TB1,TB2);
1243
1244 Standard_Integer iref = myDataStructure -> DS().AncestorRank(EOR);
1245
1246 TB = (iref == 1) ? TB1 : TB2;
1247
1248 gp_Vec aTg, aN1, aN2,aN3, aBiN;
1249
1250 TopAbs_Orientation O1 = edgeFace.Orientation();
1251 TopAbs_Orientation O2 = toFace.Orientation();
1252 TopAbs_Orientation oriE = EdgeToPerform.Orientation();
1253
1254 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(toFace, EdgeToPerform, aN2);
1255 if(O2 == TopAbs_REVERSED)
1256 aN2.Reverse();
1257
1258 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(edgeFace, EdgeToPerform, aN3);
1259 if(O1 == TopAbs_REVERSED)
1260 aN3.Reverse();
1261
1262 TopOpeBRepBuild_Tools::GetTangentToEdge(EdgeToPerform, aTg);
1263 if (oriE == TopAbs_REVERSED)
1264 aTg.Reverse();
1265 if(O1 == TopAbs_REVERSED)
1266 aTg.Reverse();
1267
1268
1269 aBiN = aTg^aN2;
1270 const TopTools_ListOfShape& aFEL = myMapOfEdgeFaces.FindFromKey(EOR);
1271 TopTools_ListIteratorOfListOfShape aEFIt(aFEL);
1272 Standard_Real scalarPr = 0.;
1273
1274 /// Why ????? Need to be checked
1275 if(aFEL.Extent() <= 2) { //we don't compute adjacent if we have more than one adjacent face
1276 for(; aEFIt.More(); aEFIt.Next()) {
1277 if(edgeFace.IsSame(aEFIt.Value()))
1278 continue;
1279 else { //compute bi-normal state
1280 TopoDS_Face aAdjF = TopoDS::Face(aEFIt.Value());
1281 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(aAdjF, EdgeToPerform, aN1);
1282 if(aAdjF.Orientation() == TopAbs_REVERSED)
1283 aN1.Reverse();
1284 scalarPr = aBiN*aN1;
1285
1286 if(fabs(scalarPr) <= 1e-10) { //try to step inside
1287 TopOpeBRepBuild_Tools::GetNormalInNearestPoint(aAdjF, EdgeToPerform, aN1);
1288 // TopOpeBRepBuild_Tools::GetNormalInNearestPoint(TopoDS::Face(aAdjF), EdgeToPerform, aN1);
1289 if(aAdjF.Orientation() == TopAbs_REVERSED)
1290 aN1.Reverse();
1291
1292 scalarPr = aBiN*aN1;
1293 if(fabs(scalarPr) <= 1e-10)
1294 continue;
1295 }
1296
1297 TopAbs_State aPartState = (scalarPr > 0) ? TopAbs_IN : TopAbs_OUT;
1298 keep = (aPartState == TB) ? Standard_True : Standard_False;
1299 if(keep)
1300 break;
1301 }
1302 }
1303 }
1304
1305 //if scalar can not be found that means that adjacent face doesn't exist
1306 //WARNING !!! May be this code is not good but for the moment it is only one solution
1307 if(fabs(scalarPr) <= 1e-10) {
1308 if(Opefus()) {
1309 keep = aN3*aN2 > 0;
1310 }
1311 if(Opec12() || Opec21())
1312 keep = aN3*aN2 < 0;
1313 if(Opecom())
1314 keep = aN3*aN2 > 0;
1315 }
1316}
1317
1318//=======================================================================
1319//function : PerformPieceOn2D
1320//purpose :
1321//=======================================================================
1322Standard_Integer TopOpeBRepBuild_Builder1::PerformPieceOn2D (const TopoDS_Shape& aPieceObj,
1323 const TopoDS_Shape& aFaceObj,
1324 const TopoDS_Shape& anEdgeObj,
1325 TopTools_ListOfShape& aListOfPieces,
1326 TopTools_ListOfShape& aListOfFaces,
1327 TopTools_ListOfShape& aListOfPiecesOut2d)
1328{
1329 // eap 30 May occ417, aCasesMap instead of aCase14 and aCase12
1330 Standard_Integer i, j, k, flag=0, priz;//, aCase14=0, aCase12=0;
1331 TColStd_MapOfInteger aCasesMap;
1332
1333 Standard_Integer iRef = myDataStructure -> DS().AncestorRank(aFaceObj);
1334
1335 if(!myDataStructure -> HasSameDomain(aFaceObj))
1336 return -1;
1337 // Main DataStructure
1338 TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
1339
1340 // Main Map for Tool (relative Tool)
1341 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateTool=
1342 (iRef == 1) ? aDS.ChangeMapOfShapeWithStateTool() : aDS.ChangeMapOfShapeWithStateObj();
1343 // Loop on faces same domain to aFaceObj
1344 TopTools_ListIteratorOfListOfShape anIt(myDataStructure->SameDomain(aFaceObj));
1345 for (i=1; anIt.More(); anIt.Next(), i++) {
1346 const TopoDS_Shape& aFaceTool=anIt.Value();
1347
1348 TopTools_IndexedMapOfShape anEdgesToolMap;
1349 TopExp::MapShapes(aFaceTool, TopAbs_EDGE, anEdgesToolMap);
1350
1351 if(myDataStructure -> HasSameDomain(anEdgeObj)) {
1352 TopTools_ListIteratorOfListOfShape anItE=myDataStructure->SameDomain(anEdgeObj);
1353 for (j=1; anItE.More(); anItE.Next(), j++) {
1354 TopoDS_Shape anEdgeTool=anItE.Value();
1355
1356 if (anEdgesToolMap.Contains (anEdgeTool)) {
1357
1358 TopExp_Explorer anExpEdges;
1359 for (anExpEdges.Init (aFaceTool, TopAbs_EDGE); anExpEdges.More(); anExpEdges.Next()) {
1360 const TopoDS_Shape& anExpEdgeTool=anExpEdges.Current();
1361 if (!anExpEdgeTool.IsSame(anEdgeTool)) continue;
1362
1363 anEdgeTool.Orientation(anExpEdgeTool.Orientation());
1364
1365 const TopOpeBRepDS_ShapeWithState& aSWSTool=
1366 aMapOfShapeWithStateTool.FindFromKey(anEdgeTool);
1367
1368 const TopTools_ListOfShape& aPartOnTool=aSWSTool.Part(TopAbs_ON);
1369
1370 // we are looking for the same piece as aPieceObj among aPartOnTool
1371 TopTools_ListIteratorOfListOfShape anItTool(aPartOnTool);
1372 for (k=1; anItTool.More(); anItTool.Next(), k++) {
1373 TopoDS_Shape& aPieceTool=anItTool.Value();
1374 aPieceTool.Orientation(anEdgeTool.Orientation());
1375
1376 Standard_Boolean aIsSameCnd, IsDegFlag;
1377
1378 IsDegFlag=
1379 BRep_Tool::Degenerated (TopoDS::Edge(aPieceObj)) &&
1380 BRep_Tool::Degenerated (TopoDS::Edge(aPieceTool)) ;
1381
1382 aIsSameCnd=IsDegFlag ? TopOpeBRepBuild_Tools::IsDegEdgesTheSame(aPieceObj, aPieceTool) : aPieceObj.IsSame(aPieceTool);
1383
1384 if (aIsSameCnd) {
1385
1386 TopTools_SequenceOfShape aSeq;
1387 aSeq.Append(aFaceObj) ; aSeq.Append(anEdgeObj) ; aSeq.Append(aPieceObj) ;
1388 aSeq.Append(aFaceTool); aSeq.Append(anEdgeTool); aSeq.Append(aPieceTool);
1389
1390 flag++;
1391 priz=TwoPiecesON (aSeq, aListOfPieces, aListOfFaces, aListOfPiecesOut2d);
1392
1393 //if (priz==14) aCase14=1;
1394 //if (priz==12) aCase12=1;
1395 aCasesMap.Add(priz);
1396 break;
1397 }
1398 }
1399
1400 if (!flag) {
1401 //printf("Warning : => aPieceTool is not found\n");
1402 //modified by NIZHNY-MZV Thu Dec 23 17:30:20 1999
1403 //return -2;
1404 }
1405 }
1406 }
1407 }
1408 }
1409 }
1410 //this case dedicated for the computation then edge has sim (F and R at one time) SD edge
1411 if ( flag>1 ) {
1412 if ( aCasesMap.Contains(14) && aCasesMap.Contains(12) && Opefus() )
1413 aListOfPieces.Clear();
1414 // eap 30 May occ417, add :
1415 if ( aCasesMap.Contains(11) && aCasesMap.Contains(13) && (Opec12() || Opec21()) )
1416 aListOfPieces.Clear();
1417 }
1418 return flag; //Ok
1419}
1420
1421//=======================================================================
1422//function : TwoPiecesON
1423//purpose :
1424//=======================================================================
1425Standard_Integer TopOpeBRepBuild_Builder1::TwoPiecesON (const TopTools_SequenceOfShape& aSeq,
1426 TopTools_ListOfShape& aListOfPieces,
1427 TopTools_ListOfShape& aListOfFaces,
1428 TopTools_ListOfShape& aListOfPiecesOut2d)
1429{
1430 // Restore Data
1431 if (aSeq.Length() < 6)
1432 return -2;
1433 TopoDS_Shape aFaceObj =aSeq(1);
1434 TopoDS_Shape anEObj =aSeq(2);
1435 TopoDS_Shape aPieceObj =aSeq(3);
1436 TopoDS_Shape aFaceTool =aSeq(4);
1437 TopoDS_Shape anETool =aSeq(5);
1438 TopoDS_Shape aPieceTool=aSeq(6);
1439
1440 // The two Maps for adjacent faces
1441 Standard_Integer iRef = myDataStructure -> DS().AncestorRank(aFaceObj);
1442
1443 TopTools_IndexedDataMapOfShapeListOfShape anEdgeFaceMapObj, anEdgeFaceMapTool;
1444
1445 if(iRef == 1) {
1446 TopExp::MapShapesAndAncestors(myShape1, TopAbs_EDGE, TopAbs_FACE, anEdgeFaceMapObj );
1447 TopExp::MapShapesAndAncestors(myShape2, TopAbs_EDGE, TopAbs_FACE, anEdgeFaceMapTool);
1448 }
1449 else {
1450 TopExp::MapShapesAndAncestors(myShape1, TopAbs_EDGE, TopAbs_FACE, anEdgeFaceMapObj );
1451 TopExp::MapShapesAndAncestors(myShape2, TopAbs_EDGE, TopAbs_FACE, anEdgeFaceMapTool);
1452 TopoDS_Shape tmpFace = aFaceObj, tmpPiece = aPieceObj, tmpEdge = anEObj;
1453 aFaceObj = aFaceTool; aPieceObj = aPieceTool; anEObj = anETool;
1454 aFaceTool = tmpFace; aPieceTool = tmpPiece; anETool = tmpEdge;
1455 }
1456 //
1457 Standard_Boolean IsFacesDifOriented , IsEdgesRevSense,
1458 anAd1=Standard_False , anAd2=Standard_False,
1459 aScPrFlag1=Standard_False, aScPrFlag2=Standard_False,
1460 Rejected1=Standard_True , Rejected2=Standard_True;
1461
1462 TopAbs_State aStateObj =TopAbs_UNKNOWN, aStateTool=TopAbs_UNKNOWN;
1463 Standard_Real aScProductObj =0. , aScProductTool=0.,
1464 aTol=1.e-5;
1465
1466
1467 Standard_Real aScPrObj=0., aScPrTool=0.;
1468 gp_Vec anyN;
1469
1470 TopoDS_Shape anAdjFaceObj, anAdjFaceTool;
1471
1472
1473 // Faces
1474 TopoDS_Face aFObj = TopoDS::Face(aFaceObj);
1475 TopoDS_Face aFTool = TopoDS::Face(aFaceTool);
1476 // Pieces
1477 TopoDS_Edge anEdgeObj = TopoDS::Edge(aPieceObj);
1478 TopoDS_Edge anEdgeTool= TopoDS::Edge(aPieceTool);
1479
1480 //OldEdges
1481 TopoDS_Edge aOriEObj = TopoDS::Edge(anEObj);
1482 TopoDS_Edge aOriETool = TopoDS::Edge(anETool);
1483
1484 // Normals to the Faces
1485 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge (aFObj, anEdgeObj, anyN);
1486 if(aFObj.Orientation() == TopAbs_REVERSED)
1487 anyN.Reverse();
1488 gp_Dir aDNObj(anyN);
1489
1490 //
1491 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge (aFTool, anEdgeTool, anyN);
1492 if(aFTool.Orientation() == TopAbs_REVERSED)
1493 anyN.Reverse();
1494 gp_Dir aDNTool (anyN);
1495
1496 // are aFaceObj & aFaceTool different oriented faces or not ?
1497 IsFacesDifOriented=aDNObj*aDNTool < 0.;
1498 // Sense of the Pieces
1499 Standard_Boolean RevObj = TopOpeBRepBuild_Tools::GetTangentToEdgeEdge (aFObj, anEdgeObj, aOriEObj, anyN);
1500 if(RevObj) {
1501 aPieceObj.Reverse();
1502 anEdgeObj.Reverse();
1503 }
1504
1505 gp_Dir aDTObj(anyN);
1506 Standard_Boolean RevTool = TopOpeBRepBuild_Tools::GetTangentToEdgeEdge (aFTool, anEdgeTool, aOriETool, anyN);
1507 if(RevTool) {
1508 aPieceTool.Reverse();
1509 anEdgeTool.Reverse();
1510 }
1511 gp_Dir aDTTool(anyN);
1512
1513 IsEdgesRevSense= aDTObj*aDTTool < 0.;
1514
1515 // try to get adjacent faces for Obj and Tool. Ad1, Ad2 indicate that the face exists.
1516 anAd1=TopOpeBRepBuild_Tools::GetAdjacentFace (aFaceObj, anEObj, anEdgeFaceMapObj, anAdjFaceObj);
1517 anAd2=TopOpeBRepBuild_Tools::GetAdjacentFace (aFaceTool, anETool, anEdgeFaceMapTool, anAdjFaceTool);
1518
1519 if (anAd1 && anAd2) {
1520 // both adjacents are found , so we can calculate the scalar products
1521 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge (TopoDS::Face(anAdjFaceObj), anEdgeObj, anyN);
1522 if(anAdjFaceObj.Orientation() == TopAbs_REVERSED)
1523 anyN.Reverse();
1524 gp_Dir aDNAObj (anyN);
1525
1526 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge (TopoDS::Face(anAdjFaceTool), anEdgeTool, anyN);
1527 if(anAdjFaceTool.Orientation() == TopAbs_REVERSED)
1528 anyN.Reverse();
1529 gp_Dir aDNATool (anyN);
1530
1531 aScPrObj =(aDTObj^aDNTool)*aDNAObj;
1532 aScPrTool=(aDTTool^aDNObj)*aDNATool;
1533
1534 if(fabs(aScPrObj) <= aTol) {//if scalar product is == 0 try to move a little from this point
1535 TopOpeBRepBuild_Tools::GetNormalInNearestPoint (TopoDS::Face(anAdjFaceObj), anEdgeObj, anyN);
1536 if(anAdjFaceObj.Orientation() == TopAbs_REVERSED)
1537 anyN.Reverse();
1538 aDNAObj.SetXYZ (anyN.XYZ());
1539 aScPrObj =(aDTObj^aDNTool)*aDNAObj;
1540 }
1541
1542 if(fabs(aScPrTool) <= aTol) {//if scalar product is == 0 try to move a little from this point
1543 TopOpeBRepBuild_Tools::GetNormalInNearestPoint (TopoDS::Face(anAdjFaceTool), anEdgeTool, anyN);
1544 if(anAdjFaceTool.Orientation() == TopAbs_REVERSED)
1545 anyN.Reverse();
1546 aDNATool.SetXYZ (anyN.XYZ());
1547 aScPrTool =(aDTTool^aDNObj)*aDNATool;
1548 }
1549
1550 // Scalar prouducts must not have too small value:
1551 aScProductObj=aScPrObj;
1552 aScProductTool=aScPrTool;
1553 /*
1554 // mine
1555 gp_Dir aDBNObj(aDNObj^aDTObj);
1556 aScProductObj=aDBNObj*aDNATool;
1557 gp_Dir aDBNTool(aDNTool^aDTTool);
1558 aScProductTool=aDBNTool*aDNAObj;
1559 */
1560 // Scalar prouducts must not have too small value:
1561 if (fabs(aScProductTool) > aTol) aScPrFlag1=Standard_True;
1562 if (fabs(aScProductObj ) > aTol) aScPrFlag2=Standard_True;
1563 }
1564
1565 // Management
1566 if (!anAd1 || !anAd2 || !aScPrFlag1 || !aScPrFlag2) {
1567 // manage without adjacents.
1568 // case a. No==Nt , To!=Tt
1569 if (IsEdgesRevSense && !IsFacesDifOriented ) {
1570 if (Opec12()) {
1571 Standard_Boolean poisc = BRep_Tool::IsClosed(anEdgeObj,aFObj);
1572 if(!poisc)
1573 {
1574 aListOfPieces.Append (aPieceObj);
1575 aListOfFaces.Append (aFaceObj);
1576 }
1577 }
1578 return 11;
1579 }
1580
1581 // case b. No!=Nt , To!=Tt
1582 if (IsEdgesRevSense && IsFacesDifOriented) {
1583 if (Opec12()) {
1584 aListOfPieces.Append (aPieceObj);
1585 aListOfFaces.Append (aFaceObj);
1586 }
1587 if(!anAd1 || !anAd2)
1588 return 12;
1589 else
1590 return 10; //10 doesn't mean anything just to retutn something
1591 }
1592
1593 // case c. No==Nt , To==Tt
1594 if (!IsEdgesRevSense && !IsFacesDifOriented) {
1595 //Begin modified by NIZHNY-MZV Mon Jan 24 10:03:58 2000
1596 // WRNG!!
1597 if(anAd1 && anAd2) {
1598 if(!Opecom()) {
1599 if(!aScPrFlag2) {
1600 aListOfPieces.Append (aPieceObj);
1601 aListOfFaces.Append (aFaceObj);
1602 }
1603 if(!aScPrFlag1) {
1604 aListOfPieces.Append (aPieceTool);
1605 aListOfFaces.Append (aFaceTool);
1606 }
1607 }
1608 }
1609 else {
1610 if(Opefus()) {
1611 aListOfPieces.Append (aPieceObj);
1612 aListOfFaces.Append (aFaceObj);
1613 }
1614 //End modified by NIZHNY-MZV Mon Jan 24 11:21:17 2000
1615 }
1616 return 13;
1617 }
1618
1619 // case d. No!=Nt , To==Tt
1620 if (!IsEdgesRevSense && IsFacesDifOriented) {
1621 //modified by NIZHNY-MZV Fri Jan 21 18:16:01 2000
1622 // WRNG!!
1623 if(anAd1 && anAd2) {
1624 if(!Opecom()) {
1625 if(!aScPrFlag2) {
1626 aListOfPieces.Append (aPieceObj);
1627 aListOfFaces.Append (aFaceObj);
1628 }
1629 if(!aScPrFlag1) {
1630 aListOfPieces.Append (aPieceTool);
1631 aListOfFaces.Append (aFaceTool);
1632 }
1633 }
1634 }
1635 else {
1636 if(Opefus()) {
1637 aListOfPieces.Append (aPieceObj);
1638 aListOfFaces.Append (aFaceObj);
1639 }
1640 }
1641 if(!anAd1 || !anAd2)
1642 return 14;
1643 else
1644 return 10; //10 doesn't mean anything just to retutn something
1645 }
1646 return 10;
1647 } // end of if (!anAd1 || !anAd2 || !aScPrFlag1 || !aScPrFlag2)
1648
1649 else {
1650 // We can use adjacents .
1651 // The States :
1652 /*
1653 aStateObj =aScProductObj < 0. ? TopAbs_IN: TopAbs_OUT ;
1654 aStateTool=aScProductTool < 0. ? TopAbs_IN: TopAbs_OUT ;
1655 */
1656 aStateObj =aScProductObj > 0. ? TopAbs_IN: TopAbs_OUT ;
1657 aStateTool=aScProductTool > 0. ? TopAbs_IN: TopAbs_OUT ;
1658 // case I RevSense && DifOriented
1659 if (IsEdgesRevSense && IsFacesDifOriented) {
1660 if (Opec12()) {
1661 aListOfPieces.Append (aPieceObj);
1662 aListOfFaces.Append (aFaceObj);
1663 }
1664 return 1;
1665 }
1666
1667 // case III SameSense && !DifOriented
1668 if (!IsEdgesRevSense && !IsFacesDifOriented) {
1669 if (!Opec12()) {
1670 aListOfPieces.Append (aPieceObj);
1671 aListOfFaces.Append (aFaceObj);
1672 }
1673 return 3;
1674 }
1675
1676 // case II RevSense && !DifOriented
1677 if (IsEdgesRevSense && !IsFacesDifOriented) {
1678 if (Opefus()) { // Fusion
1679 if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_IN) {
1680 Rejected1=Standard_False;
1681 }
1682 else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_OUT) {
1683 Rejected2=Standard_False;
1684 }
1685 //// ????
1686 else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_IN) {
1687 if(!myProcessedPartsON2d.Contains(aPieceObj)) {//we proceed IsSame only if we didn't it before
1688 myProcessedPartsON2d.Add(aPieceObj);
1689 IsSame2d (aSeq, aListOfPiecesOut2d); //Perform IsSame 2d and keep periodic parts
1690 }
1691 }
1692 else if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_OUT) {
1693 if(!myProcessedPartsON2d.Contains(aPieceObj)) {//we proceed IsSame only if we didn't it before
1694 myProcessedPartsON2d.Add(aPieceObj);
1695 IsSame2d (aSeq, aListOfPiecesOut2d); //Perform IsSame 2d and keep periodic parts
1696 }
1697 }
1698 }
1699
1700 if (Opecom()) {// Common
1701 if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_IN) {
1702 Rejected2=Standard_False;
1703 }
1704 else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_OUT) {
1705 Rejected1=Standard_False;
1706 }
1707 }
1708
1709 if (Opec12()) {// Cut
1710 if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_OUT) {
1711 Rejected2=Standard_False;
1712 }
1713 else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_IN) {
1714 Rejected1=Standard_False;
1715 }
1716 else if (aStateObj==TopAbs_OUT && aStateTool == TopAbs_IN) {
1717 Rejected1=Standard_False;
1718 Rejected2=Standard_False;
1719 }
1720 }
1721 if (!Rejected1) {
1722 aListOfPieces.Append(aPieceObj);
1723 aListOfFaces.Append (aFaceObj);
1724 }
1725 if (!Rejected2) {
1726 aListOfPieces.Append(aPieceTool);
1727 aListOfFaces.Append (aFaceTool);
1728 }
1729 return 2;
1730 }
1731
1732 // case IV !RevSense && DifOriented
1733 if (!IsEdgesRevSense && IsFacesDifOriented) {
1734 if (Opefus()) {// Fusion
1735 if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_OUT) {
1736 Rejected1=Standard_False;
1737 Rejected2=Standard_False;
1738 }
1739 else if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_IN) {
1740 Rejected2=Standard_False;
1741 }
1742 else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_OUT) {
1743 Rejected1=Standard_False;
1744 }
1745 else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_IN) {
1746 if(!myProcessedPartsON2d.Contains(aPieceObj)) {//we proceed IsSame only if we didn't it before
1747 myProcessedPartsON2d.Add(aPieceObj);
1748 IsSame2d (aSeq, aListOfPiecesOut2d); //Perform IsSame 2d and keep periodic parts
1749 }
1750 }
1751 }
1752
1753 if (Opecom()) {// Common
1754 if (aStateObj==TopAbs_IN && aStateTool==TopAbs_IN) {
1755 Rejected1=Standard_False;
1756 Rejected2=Standard_False;
1757 }
1758 else if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_IN) {
1759 Rejected1=Standard_False;
1760 }
1761 else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_OUT) {
1762 Rejected2=Standard_False;
1763 }
1764 }
1765
1766 if (Opec12()) { //Cut
1767 if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_OUT) {
1768 Rejected1=Standard_False;
1769 }
1770 else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_IN) {
1771 Rejected2=Standard_False;
1772 }
1773 }
1774 if (!Rejected1) {
1775 aListOfPieces.Append(aPieceObj);
1776 aListOfFaces.Append (aFaceObj);
1777 }
1778 if (!Rejected2) {
1779 aListOfPieces.Append(aPieceTool);
1780 aListOfFaces.Append (aFaceTool);
1781 }
1782 return 4;
1783 }
1784 // Unknowm case for existing adjacents
1785 return 0;
1786 }
1787 return -1;
1788}
1789
1790//=======================================================================
1791//function : IsSame2d
1792//purpose :
1793//=======================================================================
1794Standard_Integer TopOpeBRepBuild_Builder1::IsSame2d (const TopTools_SequenceOfShape& aSeq,
1795 TopTools_ListOfShape& aListOfPiecesOut2d)
1796{
1797 if (aSeq.Length() < 6) return 0;
1798
1799 TopoDS_Shape aFaceObj =aSeq(1); TopoDS_Shape anEdgeObj =aSeq(2);
1800 TopoDS_Shape aPieceObj =aSeq(3); TopoDS_Shape aFaceTool =aSeq(4);
1801 TopoDS_Shape anEdgeTool=aSeq(5); TopoDS_Shape aPieceTool=aSeq(6);
1802
1803 TopoDS_Face aFObj =TopoDS::Face(aFaceObj) ; TopoDS_Face aFTool =TopoDS::Face(aFaceTool) ;
1804 TopoDS_Edge anEObj =TopoDS::Edge(anEdgeObj) ; TopoDS_Edge anETool=TopoDS::Edge(anEdgeTool);
1805 TopoDS_Edge aPObj =TopoDS::Edge(aPieceObj) ; TopoDS_Edge aPTool =TopoDS::Edge(aPieceTool);
1806
1807 BRepAdaptor_Surface aBAS(aFObj);
1808 if (!(aBAS.IsUPeriodic() || aBAS.IsVPeriodic())) return 1;
1809
1810 //we process here only fully closed edges (Vf == Vl)
1811 if(!anEdgeObj.Closed() || !anEdgeTool.Closed())
1812 return 1;
1813
1814 Standard_Real f = 0., l = 0., tolpc = 0. ,
1815 par = 0., parOri = 0., f1 = 0., l1 = 0., parP = 0., gp_Resolution = 1.e-10;
1816 gp_Pnt2d aUV1;
1817
1818 Handle(Geom2d_Curve) C2D;
1819 // C2DPieceTool
1820 Handle(Geom2d_Curve) C2DPieceTool = FC2D_CurveOnSurface (aPTool, aFObj, f1, l1, tolpc, Standard_True);
1821
1822 parP= f1*PAR_T + (1 - PAR_T)*l1;
1823 gp_Pnt2d aPPiece;
1824 C2DPieceTool -> D0(parP, aPPiece);
1825
1826 // Tool Edge
1827 C2D=FC2D_CurveOnSurface (anETool, aFObj, f, l, tolpc, Standard_True);
1828 Geom2dAPI_ProjectPointOnCurve aPP2d(aPPiece, C2D);
1829 parOri = aPP2d.LowerDistanceParameter();
1830
1831 Standard_Boolean IsTrFirst = Standard_True;
1832 if(parOri < f ) {
c6541a0c 1833 parOri = 2*M_PI + parOri;
7fd59977 1834 }
1835 if(parOri > l ) {
c6541a0c 1836 parOri = parOri - 2*M_PI;
7fd59977 1837 }
1838
1839 gp_Pnt2d aUV2;
1840 C2D -> D0(parOri, aUV2);
1841 // C2DPieceObj
1842 Handle(Geom2d_Curve) C2DPieceObj=FC2D_CurveOnSurface (aPObj, aFObj, f, l, tolpc, Standard_True);
1843
1844 par=f*PAR_T + (1 - PAR_T)*l;
1845 C2DPieceObj->D0 (par, aUV1);
1846 gp_Vec2d aTranslateV (aUV1, aUV2);
1847 if(aTranslateV.Magnitude() >= gp_Resolution) {
1848
1849 Handle(Geom2d_Curve) aTrC2D = Handle(Geom2d_Curve)::DownCast(C2DPieceTool->Copy());
1850 aTrC2D->Translate(aTranslateV);
1851 gp_Pnt2d aTFuv, aTLuv;
1852 aTrC2D -> D0(f1, aTFuv);
1853 aTrC2D -> D0(l1, aTLuv);
1854 gp_Vec2d aTrVec (aTFuv, aTLuv);
1855
1856 Standard_Real fo = 0., lo = 0.;
1857 Handle(Geom2d_Curve) C2DEdgeObj = FC2D_CurveOnSurface(anEObj, aFObj, fo, lo, tolpc, Standard_True);
1858 gp_Pnt2d aOFuv, aOLuv;
1859 C2DEdgeObj -> D0(fo, aOFuv);
1860 C2DEdgeObj -> D0(lo, aOLuv);
1861 gp_Vec2d aOVec (aOFuv, aOLuv);
1862 if(anEObj.Orientation() == TopAbs_REVERSED)
1863 aOVec.Reverse();
1864 IsTrFirst = (aTrVec*aOVec > 0) ? Standard_False : Standard_True;
1865
1866 BRep_Builder BB;
1867 Standard_Real tolE = BRep_Tool::Tolerance(aPTool);
1868
1869 if(IsTrFirst)
1870 BB.UpdateEdge(aPTool , aTrC2D, C2DPieceTool, aFObj , tolE);
1871 else
1872 BB.UpdateEdge(aPTool ,C2DPieceTool, aTrC2D, aFObj , tolE);
1873
1874 aListOfPiecesOut2d.Append (aPTool);
1875 return 0;
1876 }
1877
1878 return 1;
1879}
1880
1881//=======================================================================
1882//function : OrientateEdgeOnFace
1883//purpose :
1884//=======================================================================
1885void TopOpeBRepBuild_Builder1::OrientateEdgeOnFace(TopoDS_Edge& EdgeToPerform,
1886 const TopoDS_Face& baseFace,
1887 const TopoDS_Face& edgeFace,
1888 const TopOpeBRepBuild_GTopo& G1,
1889 Standard_Boolean& stateOfFaceOri) const
1890{
1891 gp_Vec aN1, aN2;
1892
1893 stateOfFaceOri = Standard_False;
1894
1895 Standard_Integer currRef = myDataStructure -> DS().AncestorRank(mySDFaceToFill);
1896 Standard_Integer faceRef = myDataStructure -> DS().AncestorRank(edgeFace);
1897 Standard_Boolean RevOri = Standard_False;
1898
1899 if(currRef == 1) {//object
1900 RevOri = G1.IsToReverse1();
1901 }
1902 else {//tool
1903 RevOri = G1.IsToReverse2();
1904 }
1905
1906 TopAbs_Orientation oriE = EdgeToPerform.Orientation();
1907 TopAbs_Orientation neworiE = Orient(oriE, RevOri);
1908 TopAbs_Orientation faceOri = edgeFace.Orientation();
1909 TopAbs_Orientation baseOri = baseFace.Orientation();
1910 TopAbs_Orientation currOri = mySDFaceToFill.Orientation();
1911
1912 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(edgeFace, EdgeToPerform, aN1);
1913 if(faceOri == TopAbs_REVERSED)
1914 aN1.Reverse();
1915
1916 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(baseFace, EdgeToPerform, aN2);
1917 if(baseOri == TopAbs_REVERSED)
1918 aN2.Reverse();
1919
1920 if(aN1*aN2 < 0)
1921 stateOfFaceOri = Standard_True;
1922
1923 if(faceRef == 2) //for tool we need to reverse face in cut
1924 if(Opec12() || Opec21())
1925 stateOfFaceOri = !stateOfFaceOri;
1926
1927 //orientate edge with neworiE
1928 EdgeToPerform.Orientation(neworiE);
1929
1930 if(currOri != baseOri)
1931 EdgeToPerform.Reverse();
1932
1933 if(stateOfFaceOri)
1934 EdgeToPerform.Reverse();
1935}
1936
1937
1938
1939/////////////// STATIC FUNCTIONS
1940static TopAbs_State ClassifyEdgeToFaceByOnePoint(const TopoDS_Edge& E,
1941 const TopoDS_Face& F)
1942{
1943 Standard_Real f2 = 0., l2 = 0., tolpc = 0. , par = 0.;
1944 Handle(Geom2d_Curve) C2D = FC2D_CurveOnSurface(E, F, f2, l2, tolpc, Standard_True);
1945
1946 par = f2*PAR_T + (1 - PAR_T)*l2;
1947
1948 gp_Pnt2d aP2d;
1949
1950 if(C2D.IsNull())
1951 return TopAbs_UNKNOWN;
1952
1953 C2D -> D0(par, aP2d);
1954
1955 BRepTopAdaptor_FClass2d FC(F, 1e-7);
1956 TopAbs_State aState = FC.Perform(aP2d);
1957
1958 return aState;
1959}