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