0023948: Wrong intersection between a surface of revolution and a plane.
[occt.git] / src / ShapeFix / ShapeFix_ShapeTolerance.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 // 25.12.98 pdn: adding empty constructor
15
16 #include <ShapeFix_ShapeTolerance.ixx>
17
18 #include <BRep_Tool.hxx>
19 #include <BRep_TVertex.hxx>
20 #include <BRep_TEdge.hxx>
21 #include <BRep_TFace.hxx>
22
23 #include <TopoDS.hxx>
24 #include <TopoDS_Vertex.hxx>
25 #include <TopoDS_Edge.hxx>
26 #include <TopoDS_Face.hxx>
27
28 #include <TopExp.hxx>
29 #include <TopExp_Explorer.hxx>
30
31 //=======================================================================
32 //function : Constructor
33 //purpose  : 
34 //=======================================================================
35
36 ShapeFix_ShapeTolerance::ShapeFix_ShapeTolerance()
37 {
38 }  
39
40 //=======================================================================
41 //function : LimitTolerance
42 //purpose  : 
43 //=======================================================================
44
45 Standard_Boolean ShapeFix_ShapeTolerance::LimitTolerance(const TopoDS_Shape& shape,
46                                                          const Standard_Real tmin,
47                                                          const Standard_Real tmax,
48                                                          const TopAbs_ShapeEnum styp) const
49 {
50   if (shape.IsNull() || tmin < 0) return Standard_False;
51   Standard_Boolean iamax = (tmax >= tmin);
52   Standard_Real prec;
53   Standard_Boolean fait = Standard_False;
54   if (styp == TopAbs_VERTEX || styp == TopAbs_EDGE || styp == TopAbs_FACE) {
55     for (TopExp_Explorer ex(shape,styp); ex.More(); ex.Next()) {
56       TopoDS_Shape sh = ex.Current();
57       int newtol = 0;
58       if        (styp == TopAbs_VERTEX) {
59         TopoDS_Vertex V = TopoDS::Vertex (sh);
60         prec = BRep_Tool::Tolerance (V);
61         if (iamax && prec > tmax) newtol = 1;
62         else if     (prec < tmin) newtol = -1;
63         if (newtol) {
64           const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*)&V.TShape());
65           TV->Tolerance( (newtol > 0 ? tmax : tmin) );
66           fait = Standard_True;
67         }
68      } else if (styp == TopAbs_EDGE) {
69         TopoDS_Edge   E = TopoDS::Edge   (sh);
70         prec = BRep_Tool::Tolerance (E);
71         if (iamax && prec > tmax) newtol = 1;
72         else if     (prec < tmin) newtol = -1;
73         if (newtol) {
74           const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
75           TE->Tolerance( (newtol > 0 ? tmax : tmin) );
76           fait = Standard_True;
77         }
78       } else if (styp == TopAbs_FACE) {
79         TopoDS_Face   F = TopoDS::Face   (sh);
80         prec = BRep_Tool::Tolerance (F);
81         if (iamax && prec > tmax) newtol = 1;
82         else if     (prec < tmin) newtol = -1;
83         if (newtol) {
84           const Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*)&F.TShape());
85           TF->Tolerance( (newtol > 0 ? tmax : tmin) );
86           fait = Standard_True;
87         }
88       }
89     }
90   } else if (styp == TopAbs_WIRE) {
91     for (TopExp_Explorer ex(shape,TopAbs_EDGE); ex.More(); ex.Next()) {
92       TopoDS_Shape sh = ex.Current();
93       TopoDS_Edge   E = TopoDS::Edge   (sh);
94       LimitTolerance (E,tmin,tmax,TopAbs_EDGE);
95       TopoDS_Vertex V1,V2;
96       TopExp::Vertices (E,V1,V2);
97       if (!V1.IsNull()) fait |= LimitTolerance (V1,tmin,tmax,TopAbs_VERTEX);
98       if (!V2.IsNull()) fait |= LimitTolerance (V2,tmin,tmax,TopAbs_VERTEX);
99     }
100   } else {
101     fait |= LimitTolerance (shape,tmin,tmax,TopAbs_VERTEX);
102     fait |= LimitTolerance (shape,tmin,tmax,TopAbs_EDGE);
103     fait |= LimitTolerance (shape,tmin,tmax,TopAbs_FACE);
104   }
105   return fait;
106 }
107
108 //=======================================================================
109 //function : SetTolerance
110 //purpose  : 
111 //=======================================================================
112
113 void ShapeFix_ShapeTolerance::SetTolerance(const TopoDS_Shape& shape,
114                                            const Standard_Real preci,
115                                            const TopAbs_ShapeEnum styp) const
116 {
117 //   VERTEX ou EDGE ou FACE : ces types seulement
118 //   WIRE : EDGE + VERTEX
119 //   Autres : TOUT (donc == WIRE + FACE)
120   if (shape.IsNull() || preci <= 0) return;
121   if (styp == TopAbs_VERTEX || styp == TopAbs_EDGE || styp == TopAbs_FACE) {
122     for (TopExp_Explorer ex(shape,styp); ex.More(); ex.Next()) {
123       TopoDS_Shape sh = ex.Current();
124       if        (styp == TopAbs_VERTEX) {
125         TopoDS_Vertex V = TopoDS::Vertex (sh);
126 //      B.UpdateVertex (V,preci);
127         const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*)&V.TShape());
128         TV->Tolerance(preci);
129       } else if (styp == TopAbs_EDGE) {
130         TopoDS_Edge   E = TopoDS::Edge   (sh);
131 //      B.UpdateEdge   (E,preci);
132         const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
133         TE->Tolerance(preci);
134       } else if (styp == TopAbs_FACE) {
135         TopoDS_Face   F = TopoDS::Face   (sh);
136 //      B.UpdateFace   (F,preci);
137         const Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*)&F.TShape());
138         TF->Tolerance(preci);
139       }
140     }
141   }
142   else if (styp == TopAbs_WIRE) {
143     for (TopExp_Explorer ex(shape,TopAbs_EDGE); ex.More(); ex.Next()) {
144       TopoDS_Shape sh = ex.Current();
145       TopoDS_Edge   E = TopoDS::Edge   (sh);
146 //      B.UpdateEdge   (E,preci);
147       const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
148       TE->Tolerance(preci);
149       TopoDS_Vertex V1,V2;
150       TopExp::Vertices (E,V1,V2);
151       if (!V1.IsNull()) {
152 //      B.UpdateVertex (V1,preci);
153         const Handle(BRep_TVertex)& TV= *((Handle(BRep_TVertex)*)&V1.TShape());
154         TV->Tolerance(preci);
155       }
156       if (!V2.IsNull()) {
157 //      B.UpdateVertex (V2,preci);
158         const Handle(BRep_TVertex)& TV= *((Handle(BRep_TVertex)*)&V2.TShape());
159         TV->Tolerance(preci);
160       }
161     }
162   }
163   else {
164     SetTolerance (shape,preci,TopAbs_VERTEX);
165     SetTolerance (shape,preci,TopAbs_EDGE);
166     SetTolerance (shape,preci,TopAbs_FACE);
167   }
168 }