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