72f1f242655a89063c3442a054df7b13c12200f6
[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           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, 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, stateOfFaceOri);
1006
1007       if(myBaseFaceToFill == mySDFaceToFill) {
1008         mySourceShapes.Add(aSplitPart);
1009       }
1010
1011       WES.AddStartElement(aSplitPart);
1012     }
1013   }
1014 } // GFillEdgeWES
1015
1016 extern Standard_Boolean TopOpeBRepBuild_FUN_aresamegeom(const TopoDS_Shape& S1,const TopoDS_Shape& S2);
1017
1018 //=======================================================================
1019 //function : PerformONParts
1020 //purpose  : 
1021 //=======================================================================  
1022 void 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   if(iref == 1) {//object
1033     FTB = FTB1;
1034   }
1035   else {//tool
1036     FTB = FTB2;
1037   }
1038
1039   //3 Process parts that can not be found on SD faces but must be included because they are ON the SD faces
1040   const TopOpeBRepDS_ListOfInterference& LI = myDataStructure -> DS().ShapeInterferences(FOR1); 
1041   for (TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI);ILI.More();ILI.Next() ) {
1042     const Handle(TopOpeBRepDS_Interference)& I=ILI.Value();
1043     Handle(TopOpeBRepDS_ShapeShapeInterference) SSI
1044       = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I);
1045
1046     if (SSI.IsNull()) 
1047       continue;
1048
1049     TopOpeBRepDS_Kind GT,ST;
1050     Standard_Integer GI,SI;
1051     FDS_data(SSI,GT,GI,ST,SI);
1052     if (GT != TopOpeBRepDS_EDGE || ST != TopOpeBRepDS_FACE) 
1053       continue;
1054
1055     const TopoDS_Edge& EG=TopoDS::Edge(myDataStructure -> DS().Shape(GI, Standard_False));
1056     //we process only the edges which are not from the current SD faces
1057     if(mySDEdgeMap.Contains(EG))
1058       continue;
1059
1060     //take ON splits of the edge
1061     const TopTools_ListOfShape& splON = myDataStructure -> DS().GetShapeWithState(EG).Part(TopAbs_ON);
1062     if(!splON.Extent())
1063       continue;
1064
1065     const TopOpeBRepDS_Transition& aTr = SSI -> Transition();
1066
1067     Standard_Integer irefE = myDataStructure -> DS().AncestorRank(EG);
1068     
1069     Standard_Boolean RevOriE;
1070     if(irefE == 1) {//object
1071       ETB = ETB1;
1072       RevOriE = G1.IsToReverse1();
1073     }
1074     else {//tool
1075       RevOriE = G1.IsToReverse2();
1076       ETB = ETB2;
1077     }
1078
1079       
1080     //take list of edge faces
1081     const TopTools_ListOfShape& EdgeFaces = myMapOfEdgeFaces.FindFromKey(EG); 
1082     TopExp_Explorer Exp;
1083     
1084     for(TopTools_ListIteratorOfListOfShape itON(splON); itON.More(); itON.Next()) {
1085       TopoDS_Shape newE = itON.Value();
1086
1087       TopoDS_Shape aSDShape = FOR1;
1088       TopAbs_State aState = TopAbs_UNKNOWN;
1089   
1090       aState = ClassifyEdgeToFaceByOnePoint(TopoDS::Edge(newE), TopoDS::Face(FOR1));
1091       if(!(aState == TopAbs_IN || aState == TopAbs_ON)) 
1092         continue;
1093     
1094       Standard_Boolean keep = Standard_False;
1095       TopoDS_Face aSDFace = TopoDS::Face(aSDShape);
1096       
1097       TopAbs_Orientation oriE;
1098       TopAbs_Orientation neworiE;
1099
1100       for(TopTools_ListIteratorOfListOfShape it(EdgeFaces); it.More(); it.Next()) {
1101         const TopoDS_Shape& FOR = it.Value();
1102         Exp.Init(FOR, TopAbs_EDGE);
1103         TopoDS_Shape EOR; 
1104         for(; Exp.More(); Exp.Next()) {
1105           EOR = Exp.Current();
1106           if(EG.IsSame(EOR))
1107             break;
1108         }
1109          
1110         if(EOR.IsNull())
1111           continue;
1112  
1113         //else we have found a face , we process it
1114         oriE = EOR.Orientation();
1115         neworiE = Orient(oriE,RevOriE);
1116
1117         newE.Orientation(oriE);
1118         gp_Vec aTg, aN2,aN3, aBiN;
1119         TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(TopoDS::Face(FOR), TopoDS::Edge(newE), aN2);
1120         if(FOR.Orientation() == TopAbs_REVERSED)
1121           aN2.Reverse();
1122         TopOpeBRepBuild_Tools::GetTangentToEdge(TopoDS::Edge(newE), aTg);
1123         if (newE.Orientation() == TopAbs_REVERSED) {
1124           aTg.Reverse();
1125         }
1126         TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(aSDFace, TopoDS::Edge(newE), aN3);
1127         if(aSDFace.Orientation() == TopAbs_REVERSED)
1128           aN3.Reverse();
1129         keep = Standard_False;
1130         aBiN = aTg^aN2;
1131         Standard_Real scalarPr = 0.;
1132         scalarPr = aBiN*aN3;
1133         
1134         if(fabs(scalarPr) <= 1e-10) {//try to step inside
1135           TopOpeBRepBuild_Tools::GetNormalInNearestPoint(TopoDS::Face(FOR), TopoDS::Edge(newE), aN2);
1136           if(FOR.Orientation() == TopAbs_REVERSED)
1137             aN2.Reverse();
1138           aBiN = aTg^aN2;
1139           scalarPr = aBiN*aN3;
1140           if(fabs(scalarPr) <= 1e-10) 
1141             continue;
1142         }
1143         TopAbs_State aPartState = (scalarPr > 0) ? TopAbs_IN : TopAbs_OUT;
1144         keep = (aPartState == ETB) ? Standard_True : Standard_False;
1145         if(keep)
1146           break;
1147       }
1148
1149       if(keep) {
1150         //compute orientation of the future face
1151         Standard_Boolean stateOfFaceOri = Standard_False;
1152         gp_Vec aNbf, aNsf , OrigNormalbf; //aTg, aBiN, aOut;
1153         TopoDS_Edge aLocalEdge  = TopoDS::Edge(newE);
1154         TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(aSDFace,aLocalEdge, aNsf);
1155         //      TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(TopoDS::Face(aSDFace), TopoDS::Edge(newE), aNsf);
1156         if(aSDFace.Orientation() == TopAbs_REVERSED)
1157           aNsf.Reverse();
1158         TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(TopoDS::Face(myBaseFaceToFill), TopoDS::Edge(newE), OrigNormalbf);
1159         aNbf = OrigNormalbf;
1160         if(myBaseFaceToFill.Orientation() == TopAbs_REVERSED)
1161           aNbf.Reverse();
1162
1163         if(aNsf*aNbf < 0) {
1164           stateOfFaceOri = Standard_True;
1165         }
1166         
1167         if(myDataStructure -> DS().AncestorRank(aSDFace) == 2) {//for tool we need to reverse face in cut
1168           if(Opec12() || Opec21()) {
1169             stateOfFaceOri = !stateOfFaceOri;
1170           }
1171         }
1172
1173         //adjust orientation of the edge
1174         neworiE = aTr.Orientation(FTB);
1175         Standard_Boolean samegeom = TopOpeBRepBuild_FUN_aresamegeom(FOR1,myBaseFaceToFill);
1176         if (!samegeom) {
1177           neworiE = TopAbs::Complement(neworiE);
1178         }
1179         newE.Orientation(neworiE);
1180
1181         myMapOfEdgeWithFaceState.Bind (newE, stateOfFaceOri);
1182         WES.AddStartElement(newE);
1183       }
1184     }//end iteration on splON
1185   }//end iteration of interferences
1186 }
1187
1188 //=======================================================================
1189 //function : GWESMakeFaces
1190 //purpose  : 
1191 //=======================================================================
1192 void TopOpeBRepBuild_Builder1::GWESMakeFaces(const TopoDS_Shape& FF,
1193                                              TopOpeBRepBuild_WireEdgeSet& WES,
1194                                              TopTools_ListOfShape& LOF)  
1195 {
1196   TopOpeBRepBuild_Builder::GWESMakeFaces(FF, WES, LOF);
1197   TopTools_ListIteratorOfListOfShape aLOFit(LOF);
1198   TopTools_ListOfShape corrLOF;
1199   if(myIsKPart == 4) {
1200     for(; aLOFit.More(); aLOFit.Next()) {
1201       const TopoDS_Shape& ff = aLOFit.Value();
1202       TopoDS_Shape corrFF;
1203       TopOpeBRepBuild_Tools::NormalizeFace(ff, corrFF);
1204       corrLOF.Append(corrFF);
1205     }
1206   }
1207   else
1208     corrLOF.Assign(LOF);
1209
1210   LOF.Clear(); LOF.Assign(corrLOF);
1211
1212   //corect face2d
1213   aLOFit.Initialize(corrLOF);
1214   TopTools_ListOfShape corrLOF1;
1215   for(; aLOFit.More(); aLOFit.Next()) {
1216     const TopoDS_Shape& ff = aLOFit.Value();
1217     TopoDS_Shape corrFF;
1218     TopOpeBRepBuild_Tools::CorrectFace2d(ff, corrFF, mySourceShapes, myMapOfCorrect2dEdges);
1219     corrLOF1.Append(corrFF);
1220   }
1221
1222   LOF.Clear(); LOF.Assign(corrLOF1);
1223 }
1224
1225 //=======================================================================
1226 //function : PerformPieceIN2d
1227 //purpose  : 
1228 //=======================================================================
1229 void TopOpeBRepBuild_Builder1::PerformPieceIn2D(const TopoDS_Edge& EdgeToPerform,
1230                                                 const TopoDS_Edge& EOR,
1231                                                 const TopoDS_Face& edgeFace,
1232                                                 const TopoDS_Face& toFace,
1233                                                 const TopOpeBRepBuild_GTopo& G1,
1234                                                 Standard_Boolean& keep)
1235 {
1236   keep = Standard_False;
1237
1238   TopAbs_State TB1,TB2, TB; G1.StatesON(TB1,TB2);
1239
1240   Standard_Integer iref = myDataStructure -> DS().AncestorRank(EOR);
1241
1242   TB = (iref == 1) ? TB1 : TB2;
1243   
1244   gp_Vec aTg, aN1, aN2,aN3, aBiN;
1245
1246   TopAbs_Orientation O1 = edgeFace.Orientation();
1247   TopAbs_Orientation O2 = toFace.Orientation();
1248   TopAbs_Orientation oriE = EdgeToPerform.Orientation();
1249
1250   TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(toFace, EdgeToPerform, aN2);  
1251   if(O2 == TopAbs_REVERSED)
1252     aN2.Reverse();
1253     
1254   TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(edgeFace, EdgeToPerform, aN3);
1255   if(O1 == TopAbs_REVERSED)
1256     aN3.Reverse();
1257
1258   TopOpeBRepBuild_Tools::GetTangentToEdge(EdgeToPerform, aTg);
1259   if (oriE == TopAbs_REVERSED) 
1260     aTg.Reverse();
1261   if(O1 == TopAbs_REVERSED)
1262     aTg.Reverse();
1263
1264   
1265   aBiN = aTg^aN2;
1266   const TopTools_ListOfShape& aFEL = myMapOfEdgeFaces.FindFromKey(EOR);
1267   TopTools_ListIteratorOfListOfShape aEFIt(aFEL);
1268   Standard_Real scalarPr = 0.;
1269
1270   /// Why ????? Need to be checked
1271   if(aFEL.Extent() <= 2) { //we don't compute adjacent if we have more than one adjacent face
1272     for(; aEFIt.More(); aEFIt.Next()) {
1273       if(edgeFace.IsSame(aEFIt.Value()))
1274         continue;
1275       else { //compute bi-normal state
1276         TopoDS_Face aAdjF = TopoDS::Face(aEFIt.Value());
1277         TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(aAdjF, EdgeToPerform, aN1);
1278         if(aAdjF.Orientation() == TopAbs_REVERSED)
1279           aN1.Reverse();
1280         scalarPr = aBiN*aN1;
1281           
1282         if(fabs(scalarPr) <= 1e-10) { //try to step inside
1283           TopOpeBRepBuild_Tools::GetNormalInNearestPoint(aAdjF, EdgeToPerform, aN1);
1284           //      TopOpeBRepBuild_Tools::GetNormalInNearestPoint(TopoDS::Face(aAdjF), EdgeToPerform, aN1);
1285           if(aAdjF.Orientation() == TopAbs_REVERSED)
1286             aN1.Reverse();
1287             
1288           scalarPr = aBiN*aN1;
1289           if(fabs(scalarPr) <= 1e-10) 
1290             continue;
1291         }           
1292             
1293         TopAbs_State aPartState = (scalarPr > 0) ? TopAbs_IN : TopAbs_OUT;
1294         keep = (aPartState == TB) ? Standard_True : Standard_False;
1295         if(keep)
1296           break;
1297       }
1298     }
1299   }
1300       
1301   //if scalar can not be found that means that adjacent face doesn't exist
1302   //WARNING !!! May be this code is not good but for the moment it is only one solution
1303   if(fabs(scalarPr) <= 1e-10) {
1304     if(Opefus())  {
1305       keep = aN3*aN2 > 0;
1306     }
1307     if(Opec12() || Opec21())
1308       keep = aN3*aN2 < 0;
1309     if(Opecom())
1310       keep = aN3*aN2 > 0;
1311   } 
1312 }
1313
1314 //=======================================================================
1315 //function : PerformPieceOn2D
1316 //purpose  : 
1317 //=======================================================================  
1318 Standard_Integer TopOpeBRepBuild_Builder1::PerformPieceOn2D (const TopoDS_Shape& aPieceObj, 
1319                                                              const TopoDS_Shape& aFaceObj,
1320                                                              const TopoDS_Shape& anEdgeObj,
1321                                                              TopTools_ListOfShape& aListOfPieces,
1322                                                              TopTools_ListOfShape& aListOfFaces,
1323                                                              TopTools_ListOfShape& aListOfPiecesOut2d)
1324 {
1325   // eap 30 May occ417, aCasesMap instead of aCase14 and aCase12
1326   Standard_Integer i, j, k, flag=0, priz;//, aCase14=0, aCase12=0;
1327   TColStd_MapOfInteger aCasesMap;
1328
1329   Standard_Integer iRef = myDataStructure -> DS().AncestorRank(aFaceObj);
1330
1331   if(!myDataStructure -> HasSameDomain(aFaceObj)) 
1332     return -1;
1333   // Main DataStructure
1334   TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
1335
1336   // Main Map for Tool (relative Tool)
1337   TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateTool=
1338     (iRef == 1) ? aDS.ChangeMapOfShapeWithStateTool() : aDS.ChangeMapOfShapeWithStateObj();
1339   // Loop on faces same domain to aFaceObj
1340   TopTools_ListIteratorOfListOfShape anIt(myDataStructure->SameDomain(aFaceObj));
1341   for (i=1; anIt.More(); anIt.Next(), i++) {
1342     const TopoDS_Shape& aFaceTool=anIt.Value();
1343     
1344     TopTools_IndexedMapOfShape anEdgesToolMap;
1345     TopExp::MapShapes(aFaceTool, TopAbs_EDGE, anEdgesToolMap);
1346
1347     if(myDataStructure -> HasSameDomain(anEdgeObj)) {
1348       TopTools_ListIteratorOfListOfShape anItE=myDataStructure->SameDomain(anEdgeObj);
1349       for (j=1; anItE.More(); anItE.Next(), j++) {
1350         TopoDS_Shape anEdgeTool=anItE.Value();
1351
1352         if (anEdgesToolMap.Contains (anEdgeTool)) {
1353           
1354           TopExp_Explorer anExpEdges;
1355           for (anExpEdges.Init (aFaceTool, TopAbs_EDGE); anExpEdges.More(); anExpEdges.Next()) {
1356             const TopoDS_Shape& anExpEdgeTool=anExpEdges.Current();
1357             if (!anExpEdgeTool.IsSame(anEdgeTool)) continue;
1358             
1359             anEdgeTool.Orientation(anExpEdgeTool.Orientation());
1360
1361             const TopOpeBRepDS_ShapeWithState& aSWSTool=
1362               aMapOfShapeWithStateTool.FindFromKey(anEdgeTool);
1363             
1364             const TopTools_ListOfShape& aPartOnTool=aSWSTool.Part(TopAbs_ON);
1365             
1366             // we are looking for the same piece as aPieceObj among aPartOnTool
1367             TopTools_ListIteratorOfListOfShape anItTool(aPartOnTool);
1368             for (k=1; anItTool.More(); anItTool.Next(), k++) {
1369               TopoDS_Shape& aPieceTool=anItTool.Value();
1370               aPieceTool.Orientation(anEdgeTool.Orientation());
1371
1372               Standard_Boolean aIsSameCnd, IsDegFlag;
1373               
1374               IsDegFlag=
1375                 BRep_Tool::Degenerated (TopoDS::Edge(aPieceObj)) &&
1376                   BRep_Tool::Degenerated (TopoDS::Edge(aPieceTool)) ;
1377               
1378               aIsSameCnd=IsDegFlag ? TopOpeBRepBuild_Tools::IsDegEdgesTheSame(aPieceObj, aPieceTool) : aPieceObj.IsSame(aPieceTool);
1379               
1380               if (aIsSameCnd) { 
1381
1382                 TopTools_SequenceOfShape aSeq;
1383                 aSeq.Append(aFaceObj) ; aSeq.Append(anEdgeObj) ; aSeq.Append(aPieceObj) ;  
1384                 aSeq.Append(aFaceTool); aSeq.Append(anEdgeTool); aSeq.Append(aPieceTool);
1385
1386                 flag++;
1387                 priz=TwoPiecesON (aSeq, aListOfPieces, aListOfFaces, aListOfPiecesOut2d);
1388
1389                 //if (priz==14) aCase14=1;
1390                 //if (priz==12) aCase12=1;
1391                 aCasesMap.Add(priz);
1392                 break;
1393               }
1394             }
1395             
1396             if (!flag) {
1397               //printf("Warning : => aPieceTool is not found\n");
1398               //modified by NIZHNY-MZV  Thu Dec 23 17:30:20 1999
1399               //return -2;
1400             }
1401           }
1402         }
1403       }
1404     }
1405   }
1406   //this case dedicated for the computation then edge has sim (F and R at one time) SD edge 
1407   if ( flag>1 ) {
1408     if ( aCasesMap.Contains(14) && aCasesMap.Contains(12) && Opefus() )
1409       aListOfPieces.Clear();
1410     // eap 30 May occ417, add :
1411     if ( aCasesMap.Contains(11) && aCasesMap.Contains(13) && (Opec12() || Opec21()) )
1412       aListOfPieces.Clear();
1413   }
1414   return flag; //Ok
1415 }
1416
1417 //=======================================================================
1418 //function :  TwoPiecesON
1419 //purpose  : 
1420 //=======================================================================  
1421 Standard_Integer TopOpeBRepBuild_Builder1::TwoPiecesON (const TopTools_SequenceOfShape& aSeq,
1422                                                         TopTools_ListOfShape& aListOfPieces,
1423                                                         TopTools_ListOfShape& aListOfFaces,
1424                                                         TopTools_ListOfShape& aListOfPiecesOut2d)
1425 {
1426   // Restore Data
1427   if (aSeq.Length() < 6) 
1428     return -2;
1429   TopoDS_Shape aFaceObj  =aSeq(1); 
1430   TopoDS_Shape anEObj    =aSeq(2); 
1431   TopoDS_Shape aPieceObj =aSeq(3); 
1432   TopoDS_Shape aFaceTool =aSeq(4); 
1433   TopoDS_Shape anETool   =aSeq(5); 
1434   TopoDS_Shape aPieceTool=aSeq(6); 
1435  
1436   // The two Maps for adjacent faces
1437   Standard_Integer iRef = myDataStructure -> DS().AncestorRank(aFaceObj);
1438
1439   TopTools_IndexedDataMapOfShapeListOfShape anEdgeFaceMapObj, anEdgeFaceMapTool;
1440
1441   if(iRef == 1) {
1442     TopExp::MapShapesAndAncestors(myShape1, TopAbs_EDGE, TopAbs_FACE, anEdgeFaceMapObj );
1443     TopExp::MapShapesAndAncestors(myShape2, TopAbs_EDGE, TopAbs_FACE, anEdgeFaceMapTool);
1444   }
1445   else {
1446     TopExp::MapShapesAndAncestors(myShape1, TopAbs_EDGE, TopAbs_FACE, anEdgeFaceMapObj );
1447     TopExp::MapShapesAndAncestors(myShape2, TopAbs_EDGE, TopAbs_FACE, anEdgeFaceMapTool);
1448     TopoDS_Shape tmpFace = aFaceObj, tmpPiece = aPieceObj, tmpEdge = anEObj;
1449     aFaceObj = aFaceTool; aPieceObj = aPieceTool; anEObj = anETool;
1450     aFaceTool = tmpFace; aPieceTool = tmpPiece; anETool = tmpEdge;
1451   }
1452   //  
1453   Standard_Boolean IsFacesDifOriented       , IsEdgesRevSense,
1454                    anAd1=Standard_False     , anAd2=Standard_False,
1455                    aScPrFlag1=Standard_False, aScPrFlag2=Standard_False,
1456                    Rejected1=Standard_True  , Rejected2=Standard_True;
1457
1458   TopAbs_State     aStateObj =TopAbs_UNKNOWN, aStateTool=TopAbs_UNKNOWN;
1459   Standard_Real    aScProductObj =0.        , aScProductTool=0.,
1460                    aTol=1.e-5;
1461
1462   
1463   Standard_Real    aScPrObj=0.,   aScPrTool=0.;              
1464   gp_Vec anyN;
1465   
1466   TopoDS_Shape anAdjFaceObj, anAdjFaceTool;
1467   
1468   
1469   // Faces
1470   TopoDS_Face aFObj     = TopoDS::Face(aFaceObj);
1471   TopoDS_Face aFTool    = TopoDS::Face(aFaceTool);
1472   // Pieces
1473   TopoDS_Edge anEdgeObj = TopoDS::Edge(aPieceObj);
1474   TopoDS_Edge anEdgeTool= TopoDS::Edge(aPieceTool);
1475
1476   //OldEdges
1477   TopoDS_Edge aOriEObj = TopoDS::Edge(anEObj);
1478   TopoDS_Edge aOriETool = TopoDS::Edge(anETool);
1479  
1480   // Normals to the Faces 
1481   TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge (aFObj, anEdgeObj, anyN);
1482   if(aFObj.Orientation() == TopAbs_REVERSED)
1483     anyN.Reverse();
1484   gp_Dir aDNObj(anyN); 
1485  
1486   //  
1487   TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge (aFTool, anEdgeTool, anyN);
1488   if(aFTool.Orientation() == TopAbs_REVERSED)
1489     anyN.Reverse();
1490   gp_Dir aDNTool (anyN);
1491
1492   // are aFaceObj & aFaceTool different oriented faces or not ?
1493   IsFacesDifOriented=aDNObj*aDNTool < 0.;
1494   // Sense of the Pieces
1495   Standard_Boolean RevObj = TopOpeBRepBuild_Tools::GetTangentToEdgeEdge (aFObj, anEdgeObj, aOriEObj, anyN);
1496   if(RevObj) {
1497     aPieceObj.Reverse();
1498     anEdgeObj.Reverse();
1499   }
1500
1501   gp_Dir aDTObj(anyN);
1502   Standard_Boolean RevTool = TopOpeBRepBuild_Tools::GetTangentToEdgeEdge (aFTool, anEdgeTool, aOriETool, anyN);
1503   if(RevTool) {
1504     aPieceTool.Reverse();
1505     anEdgeTool.Reverse();
1506   }
1507   gp_Dir aDTTool(anyN);
1508   
1509   IsEdgesRevSense= aDTObj*aDTTool < 0.; 
1510
1511   // try to get adjacent faces for Obj and Tool. Ad1, Ad2 indicate that the face exists.
1512   anAd1=TopOpeBRepBuild_Tools::GetAdjacentFace (aFaceObj, anEObj, anEdgeFaceMapObj, anAdjFaceObj);
1513   anAd2=TopOpeBRepBuild_Tools::GetAdjacentFace (aFaceTool, anETool, anEdgeFaceMapTool, anAdjFaceTool);
1514  
1515   if (anAd1 && anAd2)   {
1516     // both adjacents are found , so we can calculate the scalar products
1517     TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge (TopoDS::Face(anAdjFaceObj), anEdgeObj, anyN);
1518     if(anAdjFaceObj.Orientation() == TopAbs_REVERSED)
1519       anyN.Reverse();
1520     gp_Dir aDNAObj (anyN);
1521    
1522     TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge (TopoDS::Face(anAdjFaceTool), anEdgeTool, anyN);
1523     if(anAdjFaceTool.Orientation() == TopAbs_REVERSED)
1524       anyN.Reverse();
1525     gp_Dir aDNATool (anyN);
1526    
1527     aScPrObj =(aDTObj^aDNTool)*aDNAObj;
1528     aScPrTool=(aDTTool^aDNObj)*aDNATool;
1529
1530     if(fabs(aScPrObj) <= aTol) {//if scalar product is == 0 try to move a little from this point
1531       TopOpeBRepBuild_Tools::GetNormalInNearestPoint (TopoDS::Face(anAdjFaceObj), anEdgeObj, anyN);
1532       if(anAdjFaceObj.Orientation() == TopAbs_REVERSED)
1533         anyN.Reverse();
1534       aDNAObj.SetXYZ (anyN.XYZ());
1535       aScPrObj =(aDTObj^aDNTool)*aDNAObj;
1536     }
1537
1538     if(fabs(aScPrTool) <= aTol) {//if scalar product is == 0 try to move a little from this point
1539       TopOpeBRepBuild_Tools::GetNormalInNearestPoint (TopoDS::Face(anAdjFaceTool), anEdgeTool, anyN);
1540       if(anAdjFaceTool.Orientation() == TopAbs_REVERSED)
1541         anyN.Reverse();
1542       aDNATool.SetXYZ (anyN.XYZ());
1543       aScPrTool =(aDTTool^aDNObj)*aDNATool;
1544     }
1545
1546     // Scalar prouducts must not have too small value: 
1547     aScProductObj=aScPrObj;
1548     aScProductTool=aScPrTool;
1549     /*
1550     // mine
1551     gp_Dir aDBNObj(aDNObj^aDTObj);
1552     aScProductObj=aDBNObj*aDNATool;
1553     gp_Dir aDBNTool(aDNTool^aDTTool);
1554     aScProductTool=aDBNTool*aDNAObj; 
1555     */
1556     // Scalar prouducts must not have too small value: 
1557     if (fabs(aScProductTool) > aTol) aScPrFlag1=Standard_True;
1558     if (fabs(aScProductObj ) > aTol) aScPrFlag2=Standard_True; 
1559   }
1560
1561   // Management 
1562   if (!anAd1 || !anAd2 || !aScPrFlag1 || !aScPrFlag2) {
1563     // manage without adjacents.
1564     //  case a.  No==Nt , To!=Tt
1565     if (IsEdgesRevSense && !IsFacesDifOriented ) { 
1566       if (Opec12()) {
1567         Standard_Boolean poisc = BRep_Tool::IsClosed(anEdgeObj,aFObj);
1568         if(!poisc)
1569           {
1570             aListOfPieces.Append (aPieceObj);
1571             aListOfFaces.Append (aFaceObj);
1572           }
1573       }
1574       return 11; 
1575     }
1576     
1577     // case b.  No!=Nt , To!=Tt
1578     if (IsEdgesRevSense && IsFacesDifOriented) {
1579       if (Opec12()) {
1580         aListOfPieces.Append (aPieceObj);
1581         aListOfFaces.Append (aFaceObj);
1582       }
1583       if(!anAd1 || !anAd2)
1584         return 12;
1585       else
1586         return 10; //10 doesn't mean anything just to retutn something
1587     }
1588     
1589     // case c.  No==Nt , To==Tt
1590     if (!IsEdgesRevSense && !IsFacesDifOriented) {
1591       //Begin modified by NIZHNY-MZV  Mon Jan 24 10:03:58 2000
1592       // WRNG!!
1593       if(anAd1 && anAd2) {
1594         if(!Opecom()) {
1595           if(!aScPrFlag2) {
1596             aListOfPieces.Append (aPieceObj);
1597             aListOfFaces.Append (aFaceObj);
1598           }
1599           if(!aScPrFlag1) {
1600             aListOfPieces.Append (aPieceTool);
1601             aListOfFaces.Append (aFaceTool);
1602           }
1603         }
1604       }
1605       else {
1606         if(Opefus()) {
1607           aListOfPieces.Append (aPieceObj);
1608           aListOfFaces.Append (aFaceObj);
1609         }
1610         //End modified by NIZHNY-MZV  Mon Jan 24 11:21:17 2000
1611       }
1612       return 13; 
1613     }
1614     
1615     // case d.  No!=Nt , To==Tt
1616     if (!IsEdgesRevSense && IsFacesDifOriented) {
1617       //modified by NIZHNY-MZV  Fri Jan 21 18:16:01 2000
1618       // WRNG!!
1619       if(anAd1 && anAd2) {
1620         if(!Opecom()) {
1621           if(!aScPrFlag2) {
1622             aListOfPieces.Append (aPieceObj);
1623             aListOfFaces.Append (aFaceObj);
1624           }
1625           if(!aScPrFlag1) {
1626             aListOfPieces.Append (aPieceTool);
1627             aListOfFaces.Append (aFaceTool);
1628           }
1629         }
1630       }
1631       else {
1632         if(Opefus()) {
1633           aListOfPieces.Append (aPieceObj);
1634           aListOfFaces.Append (aFaceObj);
1635         }
1636       }
1637       if(!anAd1 || !anAd2) 
1638          return 14;
1639        else
1640          return 10; //10 doesn't mean anything just to retutn something
1641     }
1642     return 10;
1643   } // end of if (!anAd1 || !anAd2 || !aScPrFlag1 || !aScPrFlag2)
1644
1645   else {
1646     // We can use adjacents .
1647     // The States :
1648     /*
1649     aStateObj =aScProductObj  < 0. ? TopAbs_IN: TopAbs_OUT ;
1650     aStateTool=aScProductTool < 0. ? TopAbs_IN: TopAbs_OUT ; 
1651     */
1652     aStateObj =aScProductObj  > 0. ? TopAbs_IN: TopAbs_OUT ;
1653     aStateTool=aScProductTool > 0. ? TopAbs_IN: TopAbs_OUT ; 
1654     //  case I  RevSense && DifOriented    
1655     if (IsEdgesRevSense && IsFacesDifOriented) {
1656       if (Opec12())       {
1657         aListOfPieces.Append (aPieceObj);
1658         aListOfFaces.Append (aFaceObj);
1659       }
1660       return 1;
1661     }
1662     
1663     //  case III SameSense && !DifOriented      
1664     if (!IsEdgesRevSense && !IsFacesDifOriented) {
1665       if (!Opec12())  {
1666         aListOfPieces.Append (aPieceObj);
1667         aListOfFaces.Append (aFaceObj);
1668       }
1669       return 3;
1670     }
1671     
1672     // case II  RevSense && !DifOriented         
1673     if (IsEdgesRevSense && !IsFacesDifOriented) {
1674       if (Opefus()) { // Fusion
1675         if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_IN) {
1676           Rejected1=Standard_False;
1677         }
1678         else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_OUT) {
1679           Rejected2=Standard_False;
1680         }
1681         //// ????
1682         else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_IN) {
1683           if(!myProcessedPartsON2d.Contains(aPieceObj)) {//we proceed IsSame only if we didn't it before
1684             myProcessedPartsON2d.Add(aPieceObj);
1685             IsSame2d (aSeq, aListOfPiecesOut2d); //Perform IsSame 2d and keep periodic parts
1686           }
1687         }
1688         else if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_OUT) {
1689           if(!myProcessedPartsON2d.Contains(aPieceObj)) {//we proceed IsSame only if we didn't it before
1690             myProcessedPartsON2d.Add(aPieceObj);
1691             IsSame2d (aSeq, aListOfPiecesOut2d); //Perform IsSame 2d and keep periodic parts
1692           }
1693         }
1694       }
1695       
1696       if (Opecom()) {// Common
1697         if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_IN) {
1698           Rejected2=Standard_False;
1699         }
1700         else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_OUT) {
1701           Rejected1=Standard_False;
1702         }
1703       }
1704       
1705       if (Opec12()) {// Cut
1706         if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_OUT) {
1707           Rejected2=Standard_False;
1708         }
1709         else if  (aStateObj==TopAbs_IN && aStateTool==TopAbs_IN) {
1710           Rejected1=Standard_False;
1711         }
1712         else if (aStateObj==TopAbs_OUT && aStateTool == TopAbs_IN) {
1713           Rejected1=Standard_False;
1714           Rejected2=Standard_False;
1715         }
1716       }
1717       if (!Rejected1) {
1718         aListOfPieces.Append(aPieceObj);
1719         aListOfFaces.Append (aFaceObj);
1720       }
1721       if (!Rejected2) {
1722         aListOfPieces.Append(aPieceTool);
1723         aListOfFaces.Append (aFaceTool);
1724       }
1725       return 2;
1726     }
1727     
1728     // case IV   !RevSense && DifOriented         
1729     if (!IsEdgesRevSense && IsFacesDifOriented) {
1730       if (Opefus()) {// Fusion
1731         if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_OUT) {
1732           Rejected1=Standard_False;
1733           Rejected2=Standard_False;
1734         }
1735         else if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_IN) {
1736           Rejected2=Standard_False;
1737         }
1738         else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_OUT) {
1739           Rejected1=Standard_False;
1740         }
1741         else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_IN) {
1742           if(!myProcessedPartsON2d.Contains(aPieceObj)) {//we proceed IsSame only if we didn't it before
1743             myProcessedPartsON2d.Add(aPieceObj);
1744             IsSame2d (aSeq, aListOfPiecesOut2d); //Perform IsSame 2d and keep periodic parts
1745           }
1746         }
1747       }
1748       
1749       if (Opecom()) {// Common
1750         if (aStateObj==TopAbs_IN && aStateTool==TopAbs_IN) {
1751           Rejected1=Standard_False;
1752           Rejected2=Standard_False;
1753         }
1754         else if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_IN) {
1755           Rejected1=Standard_False;
1756         }
1757         else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_OUT) {
1758           Rejected2=Standard_False;
1759         }
1760       }
1761       
1762       if (Opec12()) { //Cut
1763         if (aStateObj==TopAbs_OUT && aStateTool==TopAbs_OUT) {
1764           Rejected1=Standard_False;
1765         }
1766         else if (aStateObj==TopAbs_IN && aStateTool==TopAbs_IN) {
1767           Rejected2=Standard_False;
1768         }
1769       }
1770       if (!Rejected1) {
1771         aListOfPieces.Append(aPieceObj);
1772         aListOfFaces.Append (aFaceObj);
1773       }
1774       if (!Rejected2) {
1775         aListOfPieces.Append(aPieceTool); 
1776         aListOfFaces.Append (aFaceTool);
1777       }
1778       return 4;
1779     }
1780     // Unknowm case for existing adjacents
1781     return 0;
1782   }
1783 }
1784
1785 //=======================================================================
1786 //function : IsSame2d
1787 //purpose  : 
1788 //=======================================================================
1789 Standard_Integer TopOpeBRepBuild_Builder1::IsSame2d (const TopTools_SequenceOfShape& aSeq,
1790                                                      TopTools_ListOfShape& aListOfPiecesOut2d)
1791 {
1792   if (aSeq.Length() < 6)  return 0;
1793
1794   TopoDS_Shape aFaceObj  =aSeq(1);   TopoDS_Shape anEdgeObj =aSeq(2); 
1795   TopoDS_Shape aPieceObj =aSeq(3);   TopoDS_Shape aFaceTool =aSeq(4); 
1796   TopoDS_Shape anEdgeTool=aSeq(5);   TopoDS_Shape aPieceTool=aSeq(6); 
1797
1798   TopoDS_Face aFObj  =TopoDS::Face(aFaceObj)  ;  TopoDS_Face aFTool =TopoDS::Face(aFaceTool) ;
1799   TopoDS_Edge anEObj =TopoDS::Edge(anEdgeObj) ;  TopoDS_Edge anETool=TopoDS::Edge(anEdgeTool);
1800   TopoDS_Edge aPObj  =TopoDS::Edge(aPieceObj) ;  TopoDS_Edge aPTool =TopoDS::Edge(aPieceTool);
1801
1802   BRepAdaptor_Surface aBAS(aFObj);
1803   if (!(aBAS.IsUPeriodic() || aBAS.IsVPeriodic())) return 1;
1804
1805   //we process here only fully closed edges (Vf == Vl)
1806   if(!BRep_Tool::IsClosed(anEdgeObj) || !BRep_Tool::IsClosed(anEdgeTool))
1807     return 1;
1808   
1809   Standard_Real f = 0., l = 0., tolpc = 0. ,  
1810                 par = 0., parOri = 0., f1 = 0., l1 = 0., parP = 0., gp_Resolution = 1.e-10;
1811   gp_Pnt2d aUV1;
1812
1813   Handle(Geom2d_Curve) C2D;
1814   // C2DPieceTool
1815   Handle(Geom2d_Curve) C2DPieceTool = FC2D_CurveOnSurface (aPTool, aFObj, f1, l1, tolpc, Standard_True);
1816
1817   parP= f1*PAR_T + (1 - PAR_T)*l1;
1818   gp_Pnt2d aPPiece;
1819   C2DPieceTool -> D0(parP, aPPiece);
1820
1821   // Tool Edge
1822   C2D=FC2D_CurveOnSurface (anETool, aFObj, f, l, tolpc, Standard_True);
1823   Geom2dAPI_ProjectPointOnCurve aPP2d(aPPiece, C2D);
1824   parOri = aPP2d.LowerDistanceParameter();
1825
1826   Standard_Boolean IsTrFirst = Standard_True;
1827   if(parOri < f ) { 
1828     parOri = 2*M_PI +  parOri;
1829   }
1830   if(parOri > l ) {
1831     parOri = parOri - 2*M_PI;
1832   }
1833
1834   gp_Pnt2d aUV2; 
1835   C2D -> D0(parOri, aUV2);
1836   // C2DPieceObj
1837   Handle(Geom2d_Curve) C2DPieceObj=FC2D_CurveOnSurface (aPObj, aFObj, f, l, tolpc, Standard_True);
1838
1839   par=f*PAR_T + (1 - PAR_T)*l;
1840   C2DPieceObj->D0 (par, aUV1);
1841   gp_Vec2d aTranslateV (aUV1, aUV2);
1842   if(aTranslateV.Magnitude() >= gp_Resolution) {
1843
1844     Handle(Geom2d_Curve) aTrC2D = Handle(Geom2d_Curve)::DownCast(C2DPieceTool->Copy());
1845     aTrC2D->Translate(aTranslateV);
1846     gp_Pnt2d aTFuv, aTLuv;
1847     aTrC2D -> D0(f1, aTFuv);
1848     aTrC2D -> D0(l1, aTLuv);
1849     gp_Vec2d aTrVec (aTFuv, aTLuv);
1850
1851     Standard_Real fo = 0., lo = 0.;
1852     Handle(Geom2d_Curve) C2DEdgeObj = FC2D_CurveOnSurface(anEObj, aFObj, fo, lo, tolpc, Standard_True);
1853     gp_Pnt2d aOFuv, aOLuv;
1854     C2DEdgeObj -> D0(fo, aOFuv);
1855     C2DEdgeObj -> D0(lo, aOLuv);
1856     gp_Vec2d aOVec (aOFuv, aOLuv);
1857     if(anEObj.Orientation() == TopAbs_REVERSED)
1858       aOVec.Reverse();
1859     IsTrFirst = (aTrVec*aOVec > 0) ? Standard_False : Standard_True;
1860
1861     BRep_Builder BB; 
1862     Standard_Real tolE = BRep_Tool::Tolerance(aPTool);
1863
1864     if(IsTrFirst)
1865       BB.UpdateEdge(aPTool , aTrC2D,  C2DPieceTool, aFObj , tolE);
1866     else
1867       BB.UpdateEdge(aPTool ,C2DPieceTool, aTrC2D, aFObj , tolE);
1868
1869     aListOfPiecesOut2d.Append (aPTool);
1870     return 0;
1871   }
1872
1873   return 1;
1874 }
1875
1876 //=======================================================================
1877 //function : OrientateEdgeOnFace
1878 //purpose  : 
1879 //=======================================================================
1880 void TopOpeBRepBuild_Builder1::OrientateEdgeOnFace(TopoDS_Edge& EdgeToPerform,
1881                                                    const TopoDS_Face& baseFace,
1882                                                    const TopoDS_Face& edgeFace,
1883                                                    const TopOpeBRepBuild_GTopo& G1,
1884                                                    Standard_Boolean& stateOfFaceOri) const
1885 {
1886   gp_Vec aN1, aN2;
1887
1888   stateOfFaceOri = Standard_False;
1889
1890   Standard_Integer currRef = myDataStructure -> DS().AncestorRank(mySDFaceToFill);
1891   Standard_Integer faceRef = myDataStructure -> DS().AncestorRank(edgeFace);
1892   Standard_Boolean RevOri = Standard_False;
1893   
1894   if(currRef == 1) {//object
1895     RevOri = G1.IsToReverse1();      
1896   }
1897   else {//tool
1898     RevOri = G1.IsToReverse2();
1899   }
1900
1901   TopAbs_Orientation oriE = EdgeToPerform.Orientation();
1902   TopAbs_Orientation neworiE = Orient(oriE, RevOri);
1903   TopAbs_Orientation faceOri = edgeFace.Orientation();
1904   TopAbs_Orientation baseOri = baseFace.Orientation();
1905   TopAbs_Orientation currOri = mySDFaceToFill.Orientation();
1906   
1907   TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(edgeFace, EdgeToPerform, aN1);
1908   if(faceOri == TopAbs_REVERSED)
1909     aN1.Reverse();
1910
1911   TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(baseFace, EdgeToPerform, aN2);
1912   if(baseOri == TopAbs_REVERSED)
1913     aN2.Reverse();
1914         
1915   if(aN1*aN2 < 0)
1916     stateOfFaceOri = Standard_True;
1917
1918   if(faceRef == 2) //for tool we need to reverse face in cut
1919     if(Opec12() || Opec21())
1920       stateOfFaceOri = !stateOfFaceOri;
1921
1922   //orientate edge with neworiE
1923   EdgeToPerform.Orientation(neworiE);
1924
1925   if(currOri != baseOri)
1926     EdgeToPerform.Reverse();
1927
1928   if(stateOfFaceOri)
1929     EdgeToPerform.Reverse();
1930 }
1931
1932
1933
1934 /////////////// STATIC FUNCTIONS
1935 static TopAbs_State ClassifyEdgeToFaceByOnePoint(const TopoDS_Edge& E,
1936                                                  const TopoDS_Face& F)
1937 {
1938   Standard_Real  f2 = 0., l2 = 0., tolpc = 0. , par = 0.;
1939   Handle(Geom2d_Curve) C2D = FC2D_CurveOnSurface(E, F, f2, l2, tolpc, Standard_True);
1940
1941   par = f2*PAR_T + (1 - PAR_T)*l2;
1942         
1943   gp_Pnt2d aP2d;
1944
1945   if(C2D.IsNull())
1946     return TopAbs_UNKNOWN;
1947
1948   C2D -> D0(par, aP2d);
1949
1950   BRepTopAdaptor_FClass2d FC(F, 1e-7);
1951   TopAbs_State aState = FC.Perform(aP2d);
1952
1953   return aState;
1954 }