0028883: Invalid result of Section operation
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_SplitShapes.hxx
1 // Created on: 1996-03-01
2 // Created by: Modelistation
3 // Copyright (c) 1996-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 #ifndef _TopOpeBRepBuild_SplitShapes_HeaderFile
18 #define _TopOpeBRepBuild_SplitShapes_HeaderFile
19
20 #include <Standard_ProgramError.hxx>
21
22
23 static Standard_Boolean FUN_touched(const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Edge& EOR)
24 {
25   TopoDS_Vertex vf,vl; TopExp::Vertices(EOR,vf,vl);
26   Standard_Boolean hvf = BDS.HasShape(vf);
27   Standard_Boolean hvl = BDS.HasShape(vl);
28   return (hvf || hvl);
29 }
30
31 //=======================================================================
32 //function : SplitShapes
33 //purpose  : 
34 //=======================================================================
35 void TopOpeBRepBuild_Builder::SplitShapes(TopOpeBRepTool_ShapeExplorer& Ex,
36                                           const TopAbs_State ToBuild1, 
37                                           const TopAbs_State ToBuild2,
38                                           TopOpeBRepBuild_ShapeSet& aSet,
39                                           const Standard_Boolean RevOri)
40 {
41   TopoDS_Shape aShape;
42   TopAbs_Orientation newori;
43
44   for (; Ex.More(); Ex.Next()) {
45     aShape = Ex.Current();
46
47     // compute new orientation <newori> to give to the new shapes
48     newori = Orient(myBuildTool.Orientation(aShape),RevOri);
49
50     TopAbs_ShapeEnum t = aShape.ShapeType();
51
52 #ifdef OCCT_DEBUG
53     if (TopOpeBRepBuild_GettraceSHEX()) GdumpEXP(Ex);
54 #endif
55
56     if      ( t == TopAbs_SOLID || t == TopAbs_SHELL )
57       SplitSolid(aShape,ToBuild1,ToBuild2);
58     else if ( t == TopAbs_FACE  ) SplitFace(aShape,ToBuild1,ToBuild2);
59     else if ( t == TopAbs_EDGE  ) SplitEdge(aShape,ToBuild1,ToBuild2);
60     else continue;
61
62     if ( IsSplit(aShape,ToBuild1) ) {
63       TopoDS_Shape newShape;
64       TopTools_ListIteratorOfListOfShape It;
65       //----------------------- IFV
66       Standard_Boolean IsLSon = Standard_False;
67       //----------------------- IFV
68       const TopTools_ListOfShape& LS = Splits(aShape,ToBuild1);
69       //----------------------- IFV
70       if(t == TopAbs_EDGE && ToBuild1 == TopAbs_IN && LS.Extent() == 0) {
71         const TopTools_ListOfShape& LSon = Splits(aShape,TopAbs_ON);
72         It.Initialize(LSon);
73         IsLSon = Standard_True;
74       }
75       else {
76         It.Initialize(LS);
77       }
78       //----------------------- IFV
79       for (; It.More(); It.Next()) {
80         newShape = It.Value();
81         myBuildTool.Orientation(newShape,newori);
82 #ifdef OCCT_DEBUG
83 //      TopAbs_ShapeEnum tns = TopType(newShape);
84 #endif
85         //----------------------- IFV
86         if(IsLSon) {
87           Standard_Boolean add = Standard_True;
88           if ( !myListOfFace.IsEmpty()) { // 2d pur
89             add = KeepShape(newShape,myListOfFace,ToBuild1);
90           }
91           if(add) aSet.AddStartElement(newShape);
92
93         }
94         else {
95         //----------------------- IFV
96           aSet.AddStartElement(newShape);
97         }
98       }
99     }
100     else {
101       // aShape n'a pas de devenir de split par ToBuild1
102       // on construit les parties ToBuild1 de aShape (de S1)
103       Standard_Boolean add = Standard_True;
104       Standard_Boolean testkeep = Standard_False;
105       Standard_Boolean isedge = (t == TopAbs_EDGE);
106       Standard_Boolean hs = (myDataStructure->HasShape(aShape));
107       Standard_Boolean hg = (myDataStructure->HasGeometry(aShape));
108       
109       testkeep = isedge && hs && (!hg);
110       
111       // xpu010399 : USA60299 (!hs)&&(!hg), but vertex on bound is touched (v7)
112       //             -> testkeep
113       Standard_Boolean istouched = isedge && (!hs) && (!hg);
114       if (istouched) istouched = FUN_touched(myDataStructure->DS(),TopoDS::Edge(aShape));
115       testkeep = testkeep || istouched;
116
117       if (testkeep) { 
118         if ( !myListOfFace.IsEmpty()) { // 2d pur
119           Standard_Boolean keep = KeepShape(aShape,myListOfFace,ToBuild1);
120           add = keep;
121         }
122         else { // 3d
123           // on classifie en solide uniqt si 
124           // E dans la DS et E a ete purgee de ses interfs car en bout
125           TopoDS_Shape sol;
126           if (STATIC_SOLIDINDEX == 1) sol = myShape2;
127           else                        sol = myShape1;
128           if ( !sol.IsNull() ) {            
129             Standard_Real first,last;
130             Handle(Geom_Curve) C3D;
131             C3D = BRep_Tool::Curve(TopoDS::Edge(aShape),first,last);
132             if ( !C3D.IsNull() ) {
133               Standard_Real tt = 0.127956477;
134               Standard_Real par = (1-tt)*first + tt*last;
135               gp_Pnt P3D = C3D->Value(par);
136               Standard_Real tol3d = Precision::Confusion();
137               BRepClass3d_SolidClassifier SCL(sol,P3D,tol3d); 
138               TopAbs_State state = SCL.State();
139               add = (state == ToBuild1);
140             }
141             else {
142               throw Standard_ProgramError("SplitShapes no 3D curve on edge");
143               // NYI pas de courbe 3d : prendre un point sur (courbe 2d,face)
144             }
145           }
146           else { //  sol.IsNull
147             add = Standard_True;
148           }
149         }
150       }
151       if ( add ) {
152         myBuildTool.Orientation(aShape,newori);
153         aSet.AddElement(aShape);
154       }
155     }
156
157   } // Ex.More
158
159 } // SplitShapes
160
161 #endif