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