1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
18 //#76 rln 11.03.99 S4135: compute average without weights according to tolerances
20 #include <ShapeAnalysis_ShapeTolerance.ixx>
22 #include <BRep_Tool.hxx>
25 #include <TopoDS_Vertex.hxx>
26 #include <TopoDS_Edge.hxx>
27 #include <TopoDS_Face.hxx>
29 #include <TopExp_Explorer.hxx>
31 #include <TopTools_MapOfShape.hxx>
34 //=======================================================================
35 //function : ShapeAnalysis_ShapeTolerance
37 //=======================================================================
39 ShapeAnalysis_ShapeTolerance::ShapeAnalysis_ShapeTolerance() : myNbTol (0)
43 static void AddTol (const Standard_Real tol, Standard_Integer& nbt,
44 Standard_Real& cmin, Standard_Real& cmoy, Standard_Real& cmax)
47 if (nbt == 1) cmin = cmoy = cmax = tol;
49 if (cmin > tol) cmin = tol;
50 if (cmax < tol) cmax = tol;
52 // Calcul en moyenne geometrique entre 1 et 1e-7
53 Standard_Integer mult = 1;
54 //#76 rln 11.03.99 S4135: compute average without weights according to tolerances
55 /* if (tol < 1.e-07) mult = 10000;
56 else if (tol < 1.e-06) mult = 3000;
57 else if (tol < 1.e-05) mult = 1000;
58 else if (tol < 1.e-04) mult = 300;
59 else if (tol < 1.e-03) mult = 100;
60 else if (tol < 1.e-02) mult = 30;
61 else if (tol < 1.e-01) mult = 10;
62 else if (tol < 1. ) mult = 3;
70 //=======================================================================
71 //function : Tolerance
73 //=======================================================================
75 Standard_Real ShapeAnalysis_ShapeTolerance::Tolerance(const TopoDS_Shape& shape,const Standard_Integer mode,const TopAbs_ShapeEnum type)
78 AddTolerance (shape, type);
79 return GlobalTolerance (mode);
82 //=======================================================================
83 //function : OverTolerance
85 //=======================================================================
87 Handle(TopTools_HSequenceOfShape) ShapeAnalysis_ShapeTolerance::OverTolerance(const TopoDS_Shape& shape,const Standard_Real value,const TopAbs_ShapeEnum type) const
89 if (value >= 0) return InTolerance (shape,value,0.,type);
90 else return InTolerance (shape,0.,value,type);
93 //=======================================================================
94 //function : InTolerance
96 //=======================================================================
98 Handle(TopTools_HSequenceOfShape) ShapeAnalysis_ShapeTolerance::InTolerance(const TopoDS_Shape& shape,const Standard_Real valmin,const Standard_Real valmax,const TopAbs_ShapeEnum type) const
101 Standard_Boolean over = (valmax < valmin); // pas de liminite max
102 Handle(TopTools_HSequenceOfShape) sl = new TopTools_HSequenceOfShape ();
104 TopExp_Explorer myExp;
106 // Iteration sur les Faces
108 if (type == TopAbs_FACE || type == TopAbs_SHAPE) {
109 myExp.Init(shape, TopAbs_FACE);
110 while(myExp.More()) {
111 tol = BRep_Tool::Tolerance(TopoDS::Face(myExp.Current()));
112 if (tol >= valmin && (over || (tol <= valmax)) ) sl->Append (myExp.Current());
117 // Iteration sur les Edges
119 if (type == TopAbs_EDGE || type == TopAbs_SHAPE) {
120 myExp.Init(shape, TopAbs_EDGE);
121 while(myExp.More()) {
122 tol = BRep_Tool::Tolerance(TopoDS::Edge(myExp.Current()));
123 if (tol >= valmin && (over || (tol <= valmax)) ) sl->Append (myExp.Current());
128 // Iteration sur les Vertex
130 if (type == TopAbs_VERTEX || type == TopAbs_SHAPE) {
131 myExp.Init(shape, TopAbs_VERTEX);
132 while(myExp.More()) {
133 tol = BRep_Tool::Tolerance(TopoDS::Vertex(myExp.Current()));
134 if (tol >= valmin && (over || (tol >= valmax)) ) sl->Append (myExp.Current());
139 // Iteration combinee (cumul) SHELL+FACE+EDGE+VERTEX, on retourne SHELL+FACE
141 if (type == TopAbs_SHELL) {
142 // Exploration des shells
143 TopTools_MapOfShape mapface;
144 myExp.Init (shape, TopAbs_SHELL);
145 while(myExp.More()) {
146 Standard_Boolean iashell = Standard_False;
147 TopoDS_Shape ash = myExp.Current();
148 for (TopExp_Explorer face (ash,TopAbs_FACE); face.More(); face.Next()) {
149 mapface.Add (face.Current());
150 Handle(TopTools_HSequenceOfShape) fc =
151 InTolerance (face.Current(),valmin,valmax,type);
152 if (fc->Length() > 0) {
154 iashell = Standard_True;
157 if (iashell) sl->Append (ash);
161 // Les faces (libres ou sous shell)
162 myExp.Init (shape, TopAbs_FACE);
163 for (; myExp.More(); myExp.Next()) {
164 Standard_Boolean iaface = Standard_False;
165 if (mapface.Contains (myExp.Current()) ) continue;
166 tol = BRep_Tool::Tolerance(TopoDS::Face(myExp.Current()));
167 if (tol >= valmin && (over || (tol <= valmax)) ) iaface = Standard_True;
169 // les edges contenues ?
170 Handle(TopTools_HSequenceOfShape) fl =
171 InTolerance (myExp.Current(),valmin,valmax,TopAbs_EDGE);
172 if (fl->Length() > 0) iaface = Standard_True;
174 fl = InTolerance (myExp.Current(),valmin,valmax,TopAbs_VERTEX);
175 if (fl->Length() > 0) iaface = Standard_True;
178 if (iaface) sl->Append (myExp.Current());
186 //=======================================================================
187 //function : InitTolerance
189 //=======================================================================
191 void ShapeAnalysis_ShapeTolerance::InitTolerance()
197 //=======================================================================
198 //function : AddTolerance
200 //=======================================================================
202 void ShapeAnalysis_ShapeTolerance::AddTolerance(const TopoDS_Shape& shape,const TopAbs_ShapeEnum type)
204 Standard_Integer nbt = 0;
205 Standard_Real tol, cmin,cmoy,cmax;
207 TopExp_Explorer myExp;
209 // Iteration sur les Faces
211 if (type == TopAbs_FACE || type == TopAbs_SHAPE) {
212 myExp.Init(shape, TopAbs_FACE);
213 while(myExp.More()) {
214 tol = BRep_Tool::Tolerance(TopoDS::Face(myExp.Current()));
215 AddTol (tol,nbt,cmin,cmoy,cmax);
220 // Iteration sur les Edges
222 if (type == TopAbs_EDGE || type == TopAbs_SHAPE) {
223 myExp.Init(shape, TopAbs_EDGE);
224 while(myExp.More()) {
225 tol = BRep_Tool::Tolerance(TopoDS::Edge(myExp.Current()));
226 AddTol (tol,nbt,cmin,cmoy,cmax);
231 // Iteration sur les Vertices
233 if (type == TopAbs_VERTEX || type == TopAbs_SHAPE) {
234 myExp.Init(shape, TopAbs_VERTEX);
235 while(myExp.More()) {
236 tol = BRep_Tool::Tolerance(TopoDS::Vertex(myExp.Current()));
237 AddTol (tol,nbt,cmin,cmoy,cmax);
242 // Resultat : attention en mode cumul
243 if (nbt == 0) return;
244 if (myNbTol == 0 || myTols[0] > cmin) myTols[0] = cmin;
245 if (myNbTol == 0 || myTols[2] < cmax) myTols[2] = cmax;
250 //=======================================================================
251 //function : GlobalTolerance
253 //=======================================================================
255 Standard_Real ShapeAnalysis_ShapeTolerance::GlobalTolerance(const Standard_Integer mode) const
257 //szv#4:S4163:12Mar99 optimized
258 Standard_Real result = 0.;
260 if (mode < 0) result = myTols[0];
261 else if (mode == 0) {
262 if (myTols[0] == myTols[2]) result = myTols[0];
263 else result = myTols[1] / myNbTol;
265 else result = myTols[2];