0031007: Coding - eliminate warnings issued while compiling with -pedantic flag
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_Builder1_1.cxx
1 // Created on: 1999-10-07
2 // Created by: Peter KURNEV
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_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Curve.hxx>
21 #include <BRepTools.hxx>
22 #include <Geom_Curve.hxx>
23 #include <gp_Pnt.hxx>
24 #include <Precision.hxx>
25 #include <Standard_NoSuchObject.hxx>
26 #include <TCollection_AsciiString.hxx>
27 #include <TColStd_ListIteratorOfListOfInteger.hxx>
28 #include <TopExp.hxx>
29 #include <TopoDS.hxx>
30 #include <TopoDS_Edge.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <TopoDS_Shape.hxx>
33 #include <TopoDS_Vertex.hxx>
34 #include <TopoDS_Wire.hxx>
35 #include <TopOpeBRepBuild_Builder.hxx>
36 #include <TopOpeBRepBuild_EdgeBuilder.hxx>
37 #include <TopOpeBRepBuild_FaceBuilder.hxx>
38 #include <TopOpeBRepBuild_GTool.hxx>
39 #include <TopOpeBRepBuild_GTopo.hxx>
40 #include <TopOpeBRepBuild_HBuilder.hxx>
41 #include <TopOpeBRepBuild_ListOfListOfLoop.hxx>
42 #include <TopOpeBRepBuild_Loop.hxx>
43 #include <TopOpeBRepBuild_Pave.hxx>
44 #include <TopOpeBRepBuild_PaveSet.hxx>
45 #include <TopOpeBRepBuild_ShapeSet.hxx>
46 #include <TopOpeBRepBuild_ShellFaceSet.hxx>
47 #include <TopOpeBRepBuild_SolidBuilder.hxx>
48 #include <TopOpeBRepBuild_Tools.hxx>
49 #include <TopOpeBRepBuild_WireEdgeSet.hxx>
50 #include <TopOpeBRepDS_BuildTool.hxx>
51 #include <TopOpeBRepDS_CurveIterator.hxx>
52 #include <TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeState.hxx>
53 #include <TopOpeBRepDS_DataMapOfShapeState.hxx>
54 #include <TopOpeBRepDS_DataStructure.hxx>
55 #include <TopOpeBRepDS_HDataStructure.hxx>
56 #include <TopOpeBRepDS_IndexedDataMapOfShapeWithState.hxx>
57 #include <TopOpeBRepDS_Interference.hxx>
58 #include <TopOpeBRepDS_ListIteratorOfListOfInterference.hxx>
59 #include <TopOpeBRepDS_ListOfInterference.hxx>
60 #include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
61 #include <TopOpeBRepDS_PointIterator.hxx>
62 #include <TopOpeBRepDS_ShapeWithState.hxx>
63 #include <TopOpeBRepDS_SurfaceIterator.hxx>
64 #include <TopOpeBRepTool_ShapeExplorer.hxx>
65 #include <TopTools_DataMapOfShapeListOfInteger.hxx>
66 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
67 #include <TopTools_IndexedMapOfShape.hxx>
68 #include <TopTools_MapIteratorOfMapOfShape.hxx>
69 #include <TopTools_MapOfShape.hxx>
70
71 //define parameter division number as 10*e^(-PI) = 0.43213918
72 const Standard_Real PAR_T = 0.43213918;
73
74 static TopAbs_State ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E,
75                                                   TopOpeBRepTool_ShapeClassifier& SC);
76
77 //=======================================================================
78 //         : Definition the States of Shape's Entities for an Object
79 //         : and a Tool.                    Thu Oct  7 09:38:29 1999
80 //=======================================================================
81
82 static TopTools_IndexedMapOfShape processedEdges;
83 static TopTools_IndexedMapOfShape theUsedVertexMap;
84 static TopTools_MapOfShape theUnkStateVer;
85
86 extern Standard_Boolean GLOBAL_faces2d;
87
88 //=======================================================================
89 //function : ~TopOpeBRepBuild_Builder1
90 //purpose  : 
91 //=======================================================================
92 TopOpeBRepBuild_Builder1::~TopOpeBRepBuild_Builder1()
93 {
94   processedEdges.Clear();
95   theUsedVertexMap.Clear();
96   theUnkStateVer.Clear();
97 }
98
99 /*
100 namespace {
101
102 void DumpMapOfShapeWithState (const Standard_Integer iP,
103                               const TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState)
104 {
105   static Standard_Integer cnt=0;
106   TCollection_AsciiString aFName1 ("/DEBUG/TOPOPE/"), postfix;
107
108   Standard_CString ShapeType [9] = {"COMPO", "COMPS", "SOLID", "SHELL", "FACE ", "WIRE ", "EDGE ", "VERTX"};
109   Standard_CString ShapeState[4] = {"IN ", "OUT", "ON ", "UNKNOWN"};
110   
111   printf("\n\n********************************\n");
112   printf("*                              *\n");
113   Standard_Integer i, n=aMapOfShapeWithState.Extent();
114   if (!iP) {
115     printf("*  Object comparing with TOOL  *\n");
116     postfix=TCollection_AsciiString("Obj");
117   }
118     
119   else {
120     printf("*  Tool comparing with Object  *\n");
121     postfix=TCollection_AsciiString("Tool");
122   }
123   
124   printf("*                              *\n");
125   printf("********************************\n");
126   printf("***       aMapOfShapeWithState.Extent()=%d\n", n);
127   printf("                 C O N T E N T S\n"); 
128
129   TCollection_AsciiString aFName;
130   aFName+=aFName1; 
131   aFName+=postfix;
132
133   for (i=1; i<=n; i++) {
134     TCollection_AsciiString aI(i), aName;
135     aName+=aFName; aName+=aI;
136
137     const TopoDS_Shape& aShape=aMapOfShapeWithState.FindKey(i);
138     const TopOpeBRepDS_ShapeWithState& aShapeWithState=
139       aMapOfShapeWithState.FindFromIndex(i);
140     
141     BRepTools::Write (aShape, aName.ToCString());
142
143     TCollection_AsciiString ann;
144     ann+=postfix; ann+=aI;
145
146     printf("Key: %-8s , " , ann.ToCString());
147     printf("%s, ", ShapeType[aShape.ShapeType()]);
148     if (!iP) 
149       printf("State comp.with Tool=%s\n",  ShapeState[aShapeWithState.State()]);
150
151     else 
152       printf("State comp.with Obj =%s\n",  ShapeState[aShapeWithState.State()]);
153     
154     if (aShapeWithState.IsSplitted()) {
155       
156       const TopTools_ListOfShape& aListOfShape=aShapeWithState.Part(TopAbs_IN);
157       TopTools_ListIteratorOfListOfShape anIt(aListOfShape);
158       for (;anIt.More(); anIt.Next()) {
159         const TopoDS_Shape& aS=anIt.Value();
160         
161         TCollection_AsciiString cn(cnt), prefix("_S_"), sn;
162         sn+=aFName; sn+=prefix; sn+=cn;
163         BRepTools::Write (aS, sn.ToCString());
164         
165         TCollection_AsciiString an;//=postfix+prefix+cn;
166         an+=postfix; an+=prefix; an+=cn;
167         printf("  -> Splitted Part IN : %s\n",  an.ToCString());
168         cnt++;
169       }
170
171       const TopTools_ListOfShape& aListOfShapeOut=aShapeWithState.Part(TopAbs_OUT);
172       anIt.Initialize (aListOfShapeOut);
173       for (;anIt.More(); anIt.Next()) {
174         const TopoDS_Shape& aS=anIt.Value();
175
176         TCollection_AsciiString cn(cnt), prefix("_S_"), sn;//=aFName+prefix+cn;
177         sn+=aFName; sn+=prefix; sn+=cn;
178         BRepTools::Write (aS, sn.ToCString());
179         
180         TCollection_AsciiString an;//=postfix+prefix+cn;
181         an+=postfix; an+=prefix; an+=cn;
182         printf("  -> Splitted Part OUT: %-s\n",  an.ToCString());
183         cnt++;
184       }
185
186       const TopTools_ListOfShape& aListOfShapeOn=aShapeWithState.Part(TopAbs_ON);
187       anIt.Initialize (aListOfShapeOn);
188       for (;anIt.More(); anIt.Next()) {
189         const TopoDS_Shape& aS=anIt.Value();
190
191         TCollection_AsciiString cn(cnt), prefix("_S_"), sn;//=aFName+prefix+cn;
192         sn+=aFName; sn+=prefix; sn+=cn;
193         BRepTools::Write (aS, sn.ToCString());
194
195         TCollection_AsciiString an;//=postfix+prefix+cn;
196         an+=postfix; an+=prefix; an+=cn;
197         printf("  -> Splitted Part ON : %s\n",  an.ToCString());
198         cnt++;
199       } 
200     }
201   
202   }
203   cnt=0;
204 }
205
206 } // anonymous namespace
207 */
208
209 //=======================================================================
210 //function : PerformShapeWithStates
211 //purpose  : 
212 //=======================================================================
213   void TopOpeBRepBuild_Builder1::PerformShapeWithStates()
214 {
215   theUsedVertexMap.Clear();
216   theUnkStateVer.Clear();
217   myDataStructure -> ChangeDS().ChangeMapOfShapeWithStateObj().Clear();
218   myDataStructure -> ChangeDS().ChangeMapOfShapeWithStateTool().Clear();
219     //modified by NIZHNY-MZV  Mon Feb 21 13:30:05 2000
220   //process section curves 
221   Standard_Integer i, nbC = myDataStructure -> DS().NbCurves();
222   for(i = 1; i <= nbC; i++) {
223     TopTools_ListOfShape& LSE = ChangeNewEdges(i);
224     TopTools_ListIteratorOfListOfShape it(LSE);
225     for(; it.More(); it.Next())  {
226       const TopoDS_Shape& E = it.Value();
227       TopoDS_Vertex Vf, Vl;
228       TopExp::Vertices(TopoDS::Edge(E), Vf, Vl);
229       theUsedVertexMap.Add(Vf);
230       theUsedVertexMap.Add(Vl);
231     }
232   }
233   
234   //process section edges
235   const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
236   Standard_Integer n = BDS.NbSectionEdges();
237   for (i = 1; i <= n; i++) { 
238     TopTools_ListIteratorOfListOfShape anIt;
239     const TopoDS_Edge& E = TopoDS::Edge(BDS.SectionEdge(i));
240     if(E.IsNull()) continue;
241     
242     const TopTools_ListOfShape& SplitsON = Splits(E, TopAbs_ON);
243     anIt.Initialize (SplitsON);
244     for (; anIt.More(); anIt.Next()) {
245       TopoDS_Shape aNewEdge=anIt.Value();
246       TopoDS_Vertex Vf, Vl;
247       TopExp::Vertices(TopoDS::Edge(aNewEdge), Vf, Vl);
248       theUsedVertexMap.Add(Vf);
249       theUsedVertexMap.Add(Vl);
250     }
251       
252       // IN
253     const TopTools_ListOfShape& SplitsIN = Splits(E, TopAbs_IN);
254     anIt.Initialize (SplitsIN);
255     for (; anIt.More(); anIt.Next()) {
256       TopoDS_Shape aNewEdge=anIt.Value();
257       TopoDS_Vertex Vf, Vl;
258       TopExp::Vertices(TopoDS::Edge(aNewEdge), Vf, Vl);
259       theUsedVertexMap.Add(Vf);
260       theUsedVertexMap.Add(Vl);
261     }
262       
263     // OUT
264     const TopTools_ListOfShape& SplitsOUT = Splits(E, TopAbs_OUT);
265     anIt.Initialize (SplitsOUT);
266     for (; anIt.More(); anIt.Next()) {
267       TopoDS_Shape aNewEdge=anIt.Value();
268       TopoDS_Vertex Vf, Vl;
269       TopExp::Vertices(TopoDS::Edge(aNewEdge), Vf, Vl);
270       theUsedVertexMap.Add(Vf);
271       theUsedVertexMap.Add(Vl);
272     } 
273   } 
274
275   //modified by NIZHNY-MZV  Tue Apr 11 17:32:05 2000
276   //1) Add both arguments to facilitate the search
277   TopOpeBRepDS_ShapeWithState aShapeWithState;
278   TopOpeBRepDS_DataStructure& aDataStructure=myDataStructure->ChangeDS();
279   
280   TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateObj=
281     aDataStructure.ChangeMapOfShapeWithStateObj();
282   TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateTool=
283     aDataStructure.ChangeMapOfShapeWithStateTool();
284
285   aMapOfShapeWithStateObj.Add(myShape1, aShapeWithState);
286   aMapOfShapeWithStateTool.Add(myShape2, aShapeWithState);
287
288   //2) Add all rejected shapes as OUT
289
290   TopTools_IndexedMapOfShape& aMapOfRejectedShapesObj=
291     aDataStructure.ChangeMapOfRejectedShapesObj();
292   TopTools_IndexedMapOfShape& aMapOfRejectedShapesTool=
293     aDataStructure.ChangeMapOfRejectedShapesTool();
294
295   aShapeWithState.SetIsSplitted (Standard_False);
296   aShapeWithState.SetState (TopAbs_OUT);
297  
298   Standard_Integer iW, j, nW, nE, 
299                    nRSObj = aMapOfRejectedShapesObj.Extent(), 
300                    nRSTool = aMapOfRejectedShapesTool.Extent();
301   
302   for(i = 1; i <= nRSObj; i++) {
303     const TopoDS_Shape& aFace = aMapOfRejectedShapesObj(i);
304     if(aFace.ShapeType() != TopAbs_FACE)
305       continue; 
306     TopTools_IndexedMapOfShape aWiresMap;
307     
308     TopExp::MapShapes (aFace, TopAbs_WIRE, aWiresMap);
309     nW=aWiresMap.Extent ();
310     for (iW=1; iW<=nW; iW++) {
311       const TopoDS_Shape& aWire=aWiresMap(iW);
312       //
313       TopTools_IndexedMapOfShape anEdgesMap;
314       TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgesMap);
315       nE=anEdgesMap.Extent ();
316       for (j=1; j<=nE; j++) 
317         aMapOfShapeWithStateObj.Add(anEdgesMap(j), aShapeWithState); // add edge
318
319       aMapOfShapeWithStateObj.Add(aWire, aShapeWithState); // add wire 
320     }
321     aMapOfShapeWithStateObj.Add(aFace, aShapeWithState); // add face
322   }
323
324   for(i = 1; i <= nRSTool; i++) {
325     const TopoDS_Shape& aFace = aMapOfRejectedShapesTool(i);
326     //modified by NIZHNY-MZV  Wed Apr  5 10:27:18 2000
327     if(aFace.ShapeType() != TopAbs_FACE)
328       continue; 
329     TopTools_IndexedMapOfShape aWiresMap;
330     TopExp::MapShapes (aFace, TopAbs_WIRE, aWiresMap);
331     nW=aWiresMap.Extent ();
332     for (iW=1; iW<=nW; iW++) {
333       const TopoDS_Shape& aWire=aWiresMap(iW);
334       //
335       TopTools_IndexedMapOfShape anEdgesMap;
336       TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgesMap);
337       nE=anEdgesMap.Extent ();
338       for (j=1; j<=nE; j++) 
339         aMapOfShapeWithStateTool.Add(anEdgesMap(j), aShapeWithState); // add edge
340
341       aMapOfShapeWithStateTool.Add(aWire, aShapeWithState); // add wire 
342     }
343     aMapOfShapeWithStateTool.Add(aFace, aShapeWithState); // add face
344   }
345  
346   PerformShapeWithStates (myShape1, myShape2);
347   processedEdges.Clear();
348   PerformShapeWithStates (myShape2, myShape1);
349   processedEdges.Clear();
350   // Print Block
351 //  printf(" ..::PerformShapeWithStates() [Dump is off]\n");
352   
353 /*  printf(" ..::PerformShapeWithStates() [Dump is on]\n");
354   
355   TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
356   
357   TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateObj=
358     aDS.ChangeMapOfShapeWithStateObj();
359
360   TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithStateTool=
361     aDS.ChangeMapOfShapeWithStateTool();
362  
363   DumpMapOfShapeWithState(0, aMapOfShapeWithStateObj);
364   DumpMapOfShapeWithState(1, aMapOfShapeWithStateTool);
365 */  
366  
367   // Phase#2 Phase ON
368 //  PerformOn2D ();
369 }
370
371 //=======================================================================
372 //function :PerformShapeWithStates
373 //purpose  : 
374 //=======================================================================
375   void TopOpeBRepBuild_Builder1::PerformShapeWithStates (const TopoDS_Shape& anObj, 
376                                                         const TopoDS_Shape& aReference)
377 {
378   myShapeClassifier.SetReference(aReference);
379   TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
380   // Get aMapOfShapeWithState for Obj
381   Standard_Boolean aFlag;
382   TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=
383     aDS.ChangeMapOfShapeWithState(anObj, aFlag); 
384   if (!aFlag) return;
385   //
386   Standard_Integer i, j, k, nS, nF, nE;
387   
388   TopTools_IndexedMapOfShape aFacesMap, aFacesWithInterferencesMap, aFacesToRestMap;
389   TopOpeBRepDS_DataMapOfShapeState aSplFacesState;
390   
391   TopTools_IndexedMapOfShape aShellsMap;
392   TopExp::MapShapes(anObj, TopAbs_SHELL, aShellsMap);
393
394   nS=aShellsMap.Extent();
395   for (i=1; i<=nS; i++) {
396     const TopoDS_Shape& aShell = aShellsMap(i);
397
398     if (aMapOfShapeWithState.Contains (aShell)) continue;
399
400     else  if (!myDataStructure -> HasShape(aShell)) {
401       // Shell has no interference. 
402       // So, define its state and push into the Map as is.// A.1
403       TopOpeBRepBuild_Tools::FindStateThroughVertex (aShell, myShapeClassifier,
404                                                      aMapOfShapeWithState, theUnkStateVer);
405       continue;
406     }
407
408     else {// A.2
409       // Shell has interference. Try to separate it into FacesToRest and InterferredFace
410       aFacesMap.Clear();
411       aFacesWithInterferencesMap.Clear();
412       aFacesToRestMap.Clear();
413       aSplFacesState.Clear();
414       
415       TopExp::MapShapes (aShell, TopAbs_FACE, aFacesMap);
416       nF=aFacesMap.Extent();
417       for (j=1; j<=nF; j++) {
418         const TopoDS_Shape& aFace = aFacesMap(j);
419         
420         if (aMapOfShapeWithState.Contains (aFace)) {
421          
422           // if the face is known, its edges are also known.
423           // We just insert this info. into aSplFacesState in order to 
424           // propagate the state for faces with unknown states.
425           TopTools_IndexedMapOfShape anEdgesMap;
426           TopExp::MapShapes (aFace, TopAbs_EDGE, anEdgesMap);
427           nE=anEdgesMap.Extent();
428           for (k=1; k<=nE; k++) {
429             const TopoDS_Shape& anEdge=anEdgesMap(k);
430             const TopOpeBRepDS_ShapeWithState& aSWS=
431               aMapOfShapeWithState.FindFromKey(anEdge);
432             TopAbs_State aState=aSWS.State();
433             aSplFacesState.Bind (anEdge, aState);
434           }
435           continue;
436         } 
437         else if (myDataStructure -> HasShape(aFace))    
438           aFacesWithInterferencesMap.Add (aFace);  
439         else {  
440           aFacesToRestMap.Add (aFace);
441         }
442       } // ... next Face
443       // work with aFacesWithInterferencesMap
444       PerformFacesWithStates (anObj, aFacesWithInterferencesMap, aSplFacesState);
445                               
446       // Propagate the States  for all unknown faces from aFacesToRestMap  
447       TopTools_MapOfShape anUnkStateEdge;
448       TopOpeBRepBuild_Tools::PropagateState (aSplFacesState,aFacesToRestMap,
449                                              TopAbs_EDGE, TopAbs_FACE, myShapeClassifier,
450                                              aMapOfShapeWithState, anUnkStateEdge);
451       ///// Propagate on WIres from aFacesToRestMap  
452       TopOpeBRepBuild_Tools::PropagateStateForWires (aFacesToRestMap, aMapOfShapeWithState);
453     } // end of else A.2
454   } // next Shell 
455 }
456
457 //=======================================================================
458 //function :PerformFacesWithStates
459 //purpose  :
460 //=======================================================================
461   void TopOpeBRepBuild_Builder1::PerformFacesWithStates (const TopoDS_Shape& anObj,
462                                                         const TopTools_IndexedMapOfShape& aFacesWithInterferencesMap,
463                                                         TopOpeBRepDS_DataMapOfShapeState& aSplFacesState)
464 {
465   TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
466   // Get aMapOfShapeWithState for Obj
467   Standard_Boolean aFlag;
468   TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=aDS.ChangeMapOfShapeWithState(anObj, aFlag); 
469   if (!aFlag) return;
470   //
471
472   Standard_Integer i, j, k, nF, nW, nE;
473   
474   nF=aFacesWithInterferencesMap.Extent();
475   
476   for (i=1; i<=nF; i++) {
477     TopTools_IndexedMapOfShape anEdgesToSplitMap, anEdgesToRestMap;
478     
479     const TopoDS_Shape& aFace = aFacesWithInterferencesMap(i);
480     
481     TopTools_IndexedMapOfShape aWireMap;
482     TopExp::MapShapes (aFace, TopAbs_WIRE, aWireMap);
483     nW=aWireMap.Extent();
484     for (j=1; j<=nW; j++) {
485       const TopoDS_Shape& aWire=aWireMap(j);
486       
487       if (!myDataStructure -> HasShape(aWire)) {
488         // Wire has no interference. 
489         // So, define its state and push into the Map as is.
490         TopOpeBRepBuild_Tools::FindStateThroughVertex (aWire, myShapeClassifier,
491                                                        aMapOfShapeWithState, theUnkStateVer);
492         continue;
493       }
494       
495       else {
496         // Wire has an interferences 
497         TopTools_IndexedMapOfShape anEdgeMap;
498         TopExp::MapShapes (aWire, TopAbs_EDGE, anEdgeMap);
499         nE=anEdgeMap.Extent ();
500         for (k=1; k<=nE; k++) {
501           const TopoDS_Shape& anEdge=anEdgeMap(k);
502
503           if (myDataStructure -> HasShape(anEdge)) {
504             anEdgesToSplitMap.Add(anEdge);
505           }
506           else {
507             anEdgesToRestMap.Add(anEdge);
508           }
509         }
510         
511         // split edges and define the states for all edges and parts of edges
512         StatusEdgesToSplit (anObj, anEdgesToSplitMap, anEdgesToRestMap);
513       
514         ////// After StatusEdgesToSplit we can find  the status of each Rest Edge
515         ////// in aMapOfShapeWithState. So we can insert this info. into 
516         ////// aSplFacesState in order to propagate the state for faces.
517         nE=anEdgesToRestMap.Extent();
518         for (k=1; k<=nE; k++) {
519           const TopoDS_Shape anEdge=anEdgesToRestMap(k);
520           if (aMapOfShapeWithState.Contains (anEdge)) {
521             const TopOpeBRepDS_ShapeWithState& aSWS=aMapOfShapeWithState.FindFromKey(anEdge);
522             TopAbs_State aState=aSWS.State();
523             aSplFacesState.Bind (anEdge, aState);  
524           }
525         }
526       } //end of else {// Wire has an interferences 
527     } // next Wire
528   } // next interferred Face ... for (i=1; i<=nF; i++) ...
529 }
530
531 //=======================================================================
532 //function :StatusEdgesToSplit
533 //purpose  : 
534 //=======================================================================
535   void TopOpeBRepBuild_Builder1::StatusEdgesToSplit (const TopoDS_Shape& anObj,
536                                                     const TopTools_IndexedMapOfShape& anEdgesToSplitMap,
537                                                     const TopTools_IndexedMapOfShape& anEdgesToRestMap)
538 {
539  
540
541   TopOpeBRepDS_DataStructure& aDS= myDataStructure-> ChangeDS();
542   // Get aMapOfShapeWithState for Obj
543   Standard_Boolean aFlag;
544   TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState=aDS.ChangeMapOfShapeWithState(anObj, aFlag); 
545   if (!aFlag) return;
546   //
547
548   Standard_Integer i, nE=anEdgesToSplitMap.Extent();
549   if (!nE) return;
550
551   TopOpeBRepDS_DataMapOfShapeState aSplEdgesState;
552   TopTools_ListIteratorOfListOfShape anIt;
553   TopAbs_State aState;
554  
555   for (i=1; i<=nE; i++) {
556     const TopoDS_Shape& anEdge=anEdgesToSplitMap(i);
557     
558     if(processedEdges.Contains(anEdge)) {
559       if (aMapOfShapeWithState.Contains(anEdge)) {
560         const TopOpeBRepDS_ShapeWithState& aSWS=
561           aMapOfShapeWithState.FindFromKey(anEdge);
562         if (aSWS.IsSplitted()) {
563
564           const TopTools_ListOfShape& SplitsON=aSWS.Part(TopAbs_ON);
565           anIt.Initialize (SplitsON);
566           for (; anIt.More(); anIt.Next()) 
567             aSplEdgesState.Bind(anIt.Value(), TopAbs_ON);
568           
569           const TopTools_ListOfShape& SplitsOUT=aSWS.Part(TopAbs_OUT);
570           anIt.Initialize (SplitsOUT);
571           for (; anIt.More(); anIt.Next()) 
572             aSplEdgesState.Bind(anIt.Value(), TopAbs_OUT);
573           
574           const TopTools_ListOfShape& SplitsIN=aSWS.Part(TopAbs_IN);
575           anIt.Initialize (SplitsIN);
576           for (; anIt.More(); anIt.Next()) 
577             aSplEdgesState.Bind(anIt.Value(), TopAbs_IN);
578           
579         }
580       }
581       continue;
582     }
583
584     processedEdges.Add(anEdge);
585     
586     TopOpeBRepDS_ShapeWithState aShapeWithState;
587     
588     //  if IsSplit - it is the case of edges from SameDomain faces
589     Standard_Boolean IsSplitON = IsSplit(anEdge, TopAbs_ON);
590     if(IsSplitON) {
591       // ON
592       const TopTools_ListOfShape& SplitsON = Splits(anEdge, TopAbs_ON);
593       anIt.Initialize (SplitsON);
594       for (; anIt.More(); anIt.Next()) {
595         TopoDS_Shape aNewEdge=anIt.Value();
596         aNewEdge.Orientation (anEdge.Orientation());
597         aShapeWithState.AddPart (aNewEdge, TopAbs_ON);
598         aSplEdgesState.Bind(anIt.Value(), TopAbs_ON);
599       }
600       
601       // IN
602       const TopTools_ListOfShape& SplitsIN = Splits(anEdge, TopAbs_IN);
603       anIt.Initialize (SplitsIN);
604       for (; anIt.More(); anIt.Next()) {
605         TopoDS_Shape aNewEdge=anIt.Value();
606         aNewEdge.Orientation (anEdge.Orientation());
607         aShapeWithState.AddPart (aNewEdge, TopAbs_IN);
608         aSplEdgesState.Bind(anIt.Value(), TopAbs_IN);
609       }
610       
611       // OUT
612       const TopTools_ListOfShape& SplitsOUT = Splits(anEdge, TopAbs_OUT);
613       anIt.Initialize (SplitsOUT);
614       for (; anIt.More(); anIt.Next()) {
615         TopoDS_Shape aNewEdge=anIt.Value();
616         aNewEdge.Orientation (anEdge.Orientation());
617         aShapeWithState.AddPart (aNewEdge, TopAbs_OUT);
618         aSplEdgesState.Bind(anIt.Value(), TopAbs_OUT);
619       }
620       
621       aShapeWithState.SetIsSplitted(Standard_True);
622       aMapOfShapeWithState.Add(anEdge, aShapeWithState);
623       continue;
624     }
625     
626     //  Attempt to split the Edge (for all other edges (from non SameDomain Faces))
627     TopOpeBRepDS_DataMapOfShapeState aDataMapOfShapeState;
628     TopTools_ListOfShape aLNew;
629
630     Standard_Boolean oldState = GLOBAL_faces2d;
631
632     GLOBAL_faces2d = Standard_True;
633     SplitEdge (anEdge, aLNew, aDataMapOfShapeState);
634     GLOBAL_faces2d = oldState;
635
636     //
637     if (!aLNew.Extent()) {
638       // * It means that whole Edge is IN (see SplitEdge(...) at line 
639       // G1=TopOpeBRepBuild_GTool::GFusSame(tf,tf); Operation  Fuse 
640       // loses all parts of the Edge with IN  state, but  we  need 
641       // to have all parts. So, we have to rest the Edge as is ...
642       // ** But the edge itself will have UNKNOWN state and one split Part with state =IN.
643       TopoDS_Vertex Vf, Vl;
644       TopExp::Vertices(TopoDS::Edge(anEdge), Vf, Vl);
645       
646       Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(Vf);
647       Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(Vl);
648
649       TopoDS_Edge aNewEdge = TopoDS::Edge(anEdge);
650
651       //if edge has SD edges , it is error because it must be processed in SplitSectionEdges
652       //but if we here we don't do anything with it
653       if(myDataStructure -> HasSameDomain(aNewEdge)) {
654         HasSDV1 = Standard_False;
655         HasSDV2 = Standard_False;
656       }
657       //if vertices has SD we must update edge, so we copy it
658       if(HasSDV1 || HasSDV2) {
659         TopoDS_Shape EOR = anEdge; 
660         EOR.Orientation(TopAbs_FORWARD);
661
662         Standard_Real ParF = BRep_Tool::Parameter(Vf, TopoDS::Edge(EOR));
663         Standard_Real ParL = BRep_Tool::Parameter(Vl, TopoDS::Edge(EOR));
664         myBuildTool.CopyEdge (EOR, aNewEdge);
665
666         if (HasSDV1) { // on prend le vertex reference de V
667           Standard_Integer iref = myDataStructure->SameDomainReference(Vf);
668           Vf = TopoDS::Vertex(myDataStructure->Shape(iref));
669           Vf.Orientation(TopAbs_FORWARD);
670         }
671      
672         if (HasSDV2) { // on prend le vertex reference de V
673           Standard_Integer iref = myDataStructure->SameDomainReference(Vl);
674           Vl = TopoDS::Vertex(myDataStructure->Shape(iref));
675           Vl.Orientation(TopAbs_REVERSED);
676         }
677       
678         myBuildTool.AddEdgeVertex (aNewEdge, Vf);
679         myBuildTool.Parameter     (aNewEdge, Vf, ParF);
680         
681         myBuildTool.AddEdgeVertex (aNewEdge, Vl);
682         myBuildTool.Parameter     (aNewEdge, Vl, ParL);
683         
684         aNewEdge.Orientation (anEdge.Orientation()); 
685       }
686
687       aState= ClassifyEdgeToSolidByOnePoint(aNewEdge, myShapeClassifier);
688       aShapeWithState.SetIsSplitted (Standard_True);
689
690       aShapeWithState.AddPart (aNewEdge, aState);
691       aSplEdgesState.Bind(aNewEdge, aState);
692
693       TopExp::Vertices(aNewEdge, Vf, Vl);
694       theUsedVertexMap.Add(Vf);
695       theUsedVertexMap.Add(Vl);
696       if (!BRep_Tool::Degenerated(TopoDS::Edge(aNewEdge))) {
697         // MSV: it may be the case when an edge has one state but its vertex
698         //      has another state. We should clarify this to avoid incorrect
699         //      propagation of state.
700         myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vf));
701         if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
702           theUnkStateVer.Add(Vf);
703         if (!Vf.IsSame(Vl)) {
704           myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vl));
705           if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
706             theUnkStateVer.Add(Vl);
707         }
708       }
709     }
710     else {
711       // Usual case. The Edge was splitted onto several parts: 
712       TopTools_ListIteratorOfListOfShape aLIt(aLNew);
713       for (; aLIt.More(); aLIt.Next()) {
714         const TopoDS_Shape& aS = aLIt.Value();
715         aState = aDataMapOfShapeState(aS);
716         ////////////////////////////////////////////////////////////////////////////
717         // **  When aState==TopAbs_IN it is not evidence that it is realy so.
718         // There are some cases when JYL does not define ON parts completely.
719         // So,  as we want to have right states,  we have to do it ourselves.  
720         // PKV Mon 25 Oct 1999
721         Standard_Boolean isdegen = BRep_Tool::Degenerated(TopoDS::Edge(aS));
722         //if edge is degenerated we trust that it have IN state without classify 
723
724         if (aState==TopAbs_IN && !isdegen)  
725           aState= ClassifyEdgeToSolidByOnePoint(TopoDS::Edge(aS), myShapeClassifier);
726
727         ////////////////////////////////////////////////////////////////////////////
728         aShapeWithState.AddPart (aS, aState);
729         aShapeWithState.SetIsSplitted (Standard_True);
730           
731         aSplEdgesState.Bind(aS, aState);
732         TopoDS_Vertex Vf, Vl;
733         TopExp::Vertices(TopoDS::Edge(aS), Vf, Vl);
734         theUsedVertexMap.Add(Vf);
735         theUsedVertexMap.Add(Vl);
736         if (!isdegen) {
737           // MSV: clarify state of vertices (see my above comment)
738           myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vf));
739           if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
740             theUnkStateVer.Add(Vf);
741           if (!Vf.IsSame(Vl)) {
742             myShapeClassifier.StateP3DReference(BRep_Tool::Pnt(Vl));
743             if (myShapeClassifier.State() != aState && myShapeClassifier.State() != TopAbs_ON)
744               theUnkStateVer.Add(Vl);
745           }
746         }
747       }
748     }
749
750     const TopTools_ListOfShape& EspON = aShapeWithState.Part(TopAbs_ON);
751
752     Standard_Integer nON = EspON.Extent();
753     if(!IsSplitON  && nON) {
754       TopOpeBRepDS_ListOfShapeOn1State ONspl;
755       TopTools_ListOfShape& lON = ONspl.ChangeListOnState();
756       lON.Assign(EspON);
757       ONspl.Split(Standard_True);
758       mySplitON.Bind(anEdge, ONspl);
759       myDataStructure -> ChangeDS().AddSectionEdge(TopoDS::Edge(anEdge)); 
760     }
761
762     aMapOfShapeWithState.Add(anEdge, aShapeWithState);
763   } // end  for (i=1; i<=nE; i++) 
764
765   nE=anEdgesToRestMap.Extent();
766   for (i=1; i<=nE; i++) {
767     const TopoDS_Shape& anEdge=anEdgesToRestMap.FindKey(i);
768     if (aMapOfShapeWithState.Contains (anEdge)) {
769       const TopOpeBRepDS_ShapeWithState& aSWS= 
770         aMapOfShapeWithState.FindFromKey(anEdge);
771       if (!aSWS.IsSplitted()) {
772         // just in case
773         aState=aSWS.State();
774         aSplEdgesState.Bind (anEdge, aState);
775         continue;
776       }
777     }
778   }
779
780   if (nE)
781     //  Propagate the status for anEdgesToRestMap edges 
782     TopOpeBRepBuild_Tools::PropagateState (aSplEdgesState, anEdgesToRestMap,
783                                            TopAbs_VERTEX,  TopAbs_EDGE, myShapeClassifier,
784                                            aMapOfShapeWithState, theUnkStateVer);
785
786 }
787
788
789
790 //=======================================================================
791 //function : SplitEdge
792 //purpose  : 
793 //=======================================================================
794   void TopOpeBRepBuild_Builder1::SplitEdge (const TopoDS_Shape& anEdge, 
795                                            TopTools_ListOfShape& aLNew,
796                                            TopOpeBRepDS_DataMapOfShapeState& aDataMapOfShapeState)
797 {
798   Standard_Real aPar1, aPar2;
799   TopAbs_Orientation anOr1, anOr2;
800
801   // Attention! If you didn't do the orientation of the Edge =FORWARD,
802   // the GFillPointTopologyPVS() method will give you a garbage!  
803   TopoDS_Shape EdgeF=anEdge; 
804   EdgeF.Orientation(TopAbs_FORWARD);
805   
806   // Make a PaveSet PVS on edge EF
807   TopOpeBRepBuild_PaveSet PVS (EdgeF);
808   TopOpeBRepBuild_GTopo G1;
809   TopAbs_ShapeEnum tf = TopAbs_FACE;
810   G1=TopOpeBRepBuild_GTool::GFusSame(tf,tf); 
811   myEdgeReference = TopoDS::Edge(EdgeF);
812
813   GFillPointTopologyPVS(EdgeF, G1, PVS);
814
815   PVS.InitLoop();
816
817   //firstly we detect paves with equal params
818
819   // MSV Oct 23, 2001:
820   //  Add Paves to a standard list rather than to a PaveSet to avoid
821   //  possible sequence disturbance in InitLoop.
822   //  Check points for equality in both 3d and 1d spaces using maximum 
823   //  of tolerances of the edge and compared vertices, in 1d using resolution
824   //  on edge from that value
825
826   TopOpeBRepBuild_ListOfPave aPVSlist;
827   TopTools_DataMapOfShapeListOfInteger aVerOriMap;
828
829   BRepAdaptor_Curve aCurveAdaptor(TopoDS::Edge(anEdge));
830   Standard_Real tolEdge = BRep_Tool::Tolerance(TopoDS::Edge(anEdge));
831
832   while (PVS.MoreLoop()) {
833     Handle(TopOpeBRepBuild_Pave) aPave1=Handle(TopOpeBRepBuild_Pave)::DownCast(PVS.Loop());
834     const TopoDS_Vertex& aV1= TopoDS::Vertex(aPave1->Vertex());
835     aPar1    = aPave1->Parameter();
836     
837     PVS.NextLoop();
838     if (!PVS.MoreLoop()) {
839       aPVSlist.Append(aPave1);
840       break;
841     }
842       
843     Handle(TopOpeBRepBuild_Pave) aPave2=Handle(TopOpeBRepBuild_Pave)::DownCast(PVS.Loop());
844     const TopoDS_Vertex& aV2= TopoDS::Vertex(aPave2->Vertex());
845     aPar2    = aPave2->Parameter();
846
847     Standard_Real tolV1 = BRep_Tool::Tolerance(aV1);
848     Standard_Real tolV2 = BRep_Tool::Tolerance(aV2);
849     Standard_Real tolMax = Max(tolEdge,Max(tolV1,tolV2));
850     Standard_Real resol = aCurveAdaptor.Resolution(tolMax);
851     Standard_Real delta = Abs(aPar1 - aPar2);
852
853     if(delta < resol) {
854       Standard_Real dist = BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
855       if (dist < tolMax || delta < Precision::PConfusion()) {
856
857         TopOpeBRepDS_Kind IntType1 = aPave1 -> InterferenceType();
858         Standard_Boolean Int3d1 = (IntType1 == TopOpeBRepDS_FACE);
859         Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(aV1);
860         Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(aV2);
861         Standard_Boolean UsedV1 = theUsedVertexMap.Contains(aV1);
862         Standard_Boolean UsedV2 = theUsedVertexMap.Contains(aV2);
863
864         Standard_Boolean takeFirst = Standard_True;
865         if(HasSDV1)      ;
866         else if(HasSDV2) takeFirst = Standard_False;
867         else if(UsedV1)  ;
868         else if(UsedV2)  takeFirst = Standard_False;
869         else if(Int3d1)  ;
870         else             takeFirst = Standard_False;
871         TopoDS_Shape aVer;
872         Standard_Boolean HasSDV;
873         TopAbs_Orientation anOriOpp;
874         if (takeFirst) {
875           aPVSlist.Append(aPave1);
876           aVer = aV1; HasSDV = HasSDV1; anOriOpp = aV2.Orientation();
877         }
878         else {
879           aPVSlist.Append(aPave2);
880           aVer = aV2; HasSDV = HasSDV2; anOriOpp = aV1.Orientation();
881         }
882
883         if (aV1.Orientation() != aV2.Orientation()) {
884           // MSV: save orientation of removed vertex
885           TColStd_ListOfInteger thelist;
886           if (!aVerOriMap.IsBound(aVer)) aVerOriMap.Bind(aVer, thelist);
887           TColStd_ListOfInteger& anOriList = aVerOriMap(aVer);
888           anOriList.Append(takeFirst);
889           anOriList.Append(anOriOpp);
890           // mark this vertex as having unknown state
891           if (HasSDV) {
892             Standard_Integer iref = myDataStructure->SameDomainReference(aVer);
893             aVer = myDataStructure->Shape(iref);
894           }
895           theUnkStateVer.Add(aVer);
896         }
897
898         PVS.NextLoop();
899         continue;
900       }
901     }
902     aPVSlist.Append(aPave1);
903   }
904
905   TopOpeBRepBuild_ListIteratorOfListOfPave aPVSit(aPVSlist);
906   while (aPVSit.More()) {
907     Handle(TopOpeBRepBuild_Pave) aPave1 = aPVSit.Value();
908     TopoDS_Shape aV1= aPave1->Vertex();
909     aV1.Orientation(TopAbs_FORWARD);
910     aPar1    = aPave1->Parameter();
911     anOr1=(aPave1->Vertex()).Orientation();
912     if (aVerOriMap.IsBound(aV1)) {
913       // MSV: restore orientation of removed vertex
914       TColStd_ListOfInteger& anOriList = aVerOriMap(aV1);
915       if (!anOriList.IsEmpty()) {
916         if (anOriList.First()) {
917           TColStd_ListIteratorOfListOfInteger it(anOriList); it.Next();
918           anOr1 = (TopAbs_Orientation) it.Value();
919         }
920         anOriList.RemoveFirst(); anOriList.RemoveFirst();
921       }
922     }
923
924     aPVSit.Next();
925
926     if (!aPVSit.More()) break;
927
928     Handle(TopOpeBRepBuild_Pave) aPave2 = aPVSit.Value();
929     TopoDS_Shape aV2= aPave2->Vertex();
930     aV2.Orientation(TopAbs_REVERSED);
931     aPar2    = aPave2->Parameter();
932     anOr2=(aPave2->Vertex()).Orientation();
933     if (aVerOriMap.IsBound(aV2)) {
934       TColStd_ListOfInteger& anOriList = aVerOriMap(aV2);
935       if (!anOriList.IsEmpty()) {
936         if (!anOriList.First()) {
937           TColStd_ListIteratorOfListOfInteger it(anOriList); it.Next();
938           anOr2 = (TopAbs_Orientation) it.Value();
939         }
940       }
941     }
942
943     // MSV: avoid creation of an edge with invalid range
944     if (aPar1 > aPar2) continue;
945
946     Standard_Boolean HasSDV1 = myDataStructure->HasSameDomain(aV1);
947     Standard_Boolean HasSDV2 = myDataStructure->HasSameDomain(aV2);
948     if (HasSDV1) { // on prend le vertex reference de V
949       Standard_Integer iref = myDataStructure->SameDomainReference(aV1);
950       aV1 = myDataStructure->Shape(iref);
951       aV1.Orientation(TopAbs_FORWARD);
952     }
953
954     if (HasSDV2) { // on prend le vertex reference de V
955       Standard_Integer iref = myDataStructure->SameDomainReference(aV2);
956       aV2 = myDataStructure->Shape(iref);
957       aV2.Orientation(TopAbs_REVERSED);
958     }
959
960     // Make new edge from EdgeF
961     TopoDS_Edge aNewEdge;
962     myBuildTool.CopyEdge (EdgeF, aNewEdge);
963
964     myBuildTool.AddEdgeVertex (aNewEdge, aV1);
965     myBuildTool.Parameter     (aNewEdge, aV1, aPar1);
966     
967     myBuildTool.AddEdgeVertex (aNewEdge, aV2);
968     myBuildTool.Parameter     (aNewEdge, aV2, aPar2);
969     // State of piece
970     
971     
972     TopAbs_State aState=TopAbs_IN;
973  
974     if (anOr1==TopAbs_FORWARD  && anOr2==TopAbs_REVERSED) aState=TopAbs_OUT;
975     if (anOr1==TopAbs_FORWARD  && anOr2==TopAbs_INTERNAL) aState=TopAbs_OUT;
976     if (anOr1==TopAbs_INTERNAL && anOr2==TopAbs_REVERSED) aState=TopAbs_OUT;
977     ///* Added
978     if (anOr1==TopAbs_INTERNAL && anOr2==TopAbs_INTERNAL) aState=TopAbs_OUT;
979     //printf(" anOr1=%d, anOr2=%d\n", anOr1, anOr2);
980
981     // set old orientation to new edge;
982     aNewEdge.Orientation (anEdge.Orientation()); 
983     aLNew.Append(aNewEdge);
984     aDataMapOfShapeState.Bind(aNewEdge, aState);
985   }
986   //GEDBUMakeEdges(EdgeF,EDBU,aListOfShape);
987 }
988
989 static TopAbs_State ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E,
990                                                   TopOpeBRepTool_ShapeClassifier& SC)
991 {
992   Standard_Real f2 = 0., l2 = 0., par = 0.;
993
994   Handle(Geom_Curve) C3D = BRep_Tool::Curve(E, f2, l2);
995   gp_Pnt aP3d;
996
997   if(C3D.IsNull()) {
998     //it means that we are in degenerated edge
999     const TopoDS_Vertex& fv = TopExp::FirstVertex(E);
1000     if(fv.IsNull())
1001       return TopAbs_UNKNOWN;
1002     aP3d = BRep_Tool::Pnt(fv);
1003   }
1004   else {//usual case
1005     par = f2*PAR_T + (1 - PAR_T)*l2;
1006     C3D -> D0(par, aP3d);
1007   }
1008     
1009   SC.StateP3DReference(aP3d);
1010
1011   return SC.State();
1012 }