0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / ShapeAnalysis / ShapeAnalysis_ShapeTolerance.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 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
973c2be1 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.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
7fd59977 14//#76 rln 11.03.99 S4135: compute average without weights according to tolerances
15//szv#4 S4163
7fd59977 16
17#include <BRep_Tool.hxx>
42cf5bc1 18#include <ShapeAnalysis_ShapeTolerance.hxx>
19#include <TopExp_Explorer.hxx>
7fd59977 20#include <TopoDS.hxx>
7fd59977 21#include <TopoDS_Edge.hxx>
22#include <TopoDS_Face.hxx>
42cf5bc1 23#include <TopoDS_Shape.hxx>
24#include <TopoDS_Vertex.hxx>
7fd59977 25#include <TopTools_MapOfShape.hxx>
26
7fd59977 27//=======================================================================
28//function : ShapeAnalysis_ShapeTolerance
29//purpose :
30//=======================================================================
7fd59977 31ShapeAnalysis_ShapeTolerance::ShapeAnalysis_ShapeTolerance() : myNbTol (0)
32{
33}
34
35static void AddTol (const Standard_Real tol, Standard_Integer& nbt,
36 Standard_Real& cmin, Standard_Real& cmoy, Standard_Real& cmax)
37{
38 nbt ++;
39 if (nbt == 1) cmin = cmoy = cmax = tol;
40 else {
41 if (cmin > tol) cmin = tol;
42 if (cmax < tol) cmax = tol;
43// cmoy += tol;
44// Calcul en moyenne geometrique entre 1 et 1e-7
45 Standard_Integer mult = 1;
46 //#76 rln 11.03.99 S4135: compute average without weights according to tolerances
47/* if (tol < 1.e-07) mult = 10000;
48 else if (tol < 1.e-06) mult = 3000;
49 else if (tol < 1.e-05) mult = 1000;
50 else if (tol < 1.e-04) mult = 300;
51 else if (tol < 1.e-03) mult = 100;
52 else if (tol < 1.e-02) mult = 30;
53 else if (tol < 1.e-01) mult = 10;
54 else if (tol < 1. ) mult = 3;
55*/
56 nbt += (mult-1);
57 cmoy += (tol * mult);
58 }
59}
60
61
62//=======================================================================
63//function : Tolerance
64//purpose :
65//=======================================================================
66
67Standard_Real ShapeAnalysis_ShapeTolerance::Tolerance(const TopoDS_Shape& shape,const Standard_Integer mode,const TopAbs_ShapeEnum type)
68{
69 InitTolerance();
70 AddTolerance (shape, type);
71 return GlobalTolerance (mode);
72}
73
74//=======================================================================
75//function : OverTolerance
76//purpose :
77//=======================================================================
78
79 Handle(TopTools_HSequenceOfShape) ShapeAnalysis_ShapeTolerance::OverTolerance(const TopoDS_Shape& shape,const Standard_Real value,const TopAbs_ShapeEnum type) const
80{
81 if (value >= 0) return InTolerance (shape,value,0.,type);
82 else return InTolerance (shape,0.,value,type);
83}
84
85//=======================================================================
86//function : InTolerance
87//purpose :
88//=======================================================================
89
90 Handle(TopTools_HSequenceOfShape) ShapeAnalysis_ShapeTolerance::InTolerance(const TopoDS_Shape& shape,const Standard_Real valmin,const Standard_Real valmax,const TopAbs_ShapeEnum type) const
91{
92 Standard_Real tol;
93 Standard_Boolean over = (valmax < valmin); // pas de liminite max
94 Handle(TopTools_HSequenceOfShape) sl = new TopTools_HSequenceOfShape ();
95
96 TopExp_Explorer myExp;
97
98 // Iteration sur les Faces
99
100 if (type == TopAbs_FACE || type == TopAbs_SHAPE) {
101 myExp.Init(shape, TopAbs_FACE);
102 while(myExp.More()) {
103 tol = BRep_Tool::Tolerance(TopoDS::Face(myExp.Current()));
104 if (tol >= valmin && (over || (tol <= valmax)) ) sl->Append (myExp.Current());
105 myExp.Next();
106 }
107 }
108
109 // Iteration sur les Edges
110
111 if (type == TopAbs_EDGE || type == TopAbs_SHAPE) {
112 myExp.Init(shape, TopAbs_EDGE);
113 while(myExp.More()) {
114 tol = BRep_Tool::Tolerance(TopoDS::Edge(myExp.Current()));
115 if (tol >= valmin && (over || (tol <= valmax)) ) sl->Append (myExp.Current());
116 myExp.Next();
117 }
118 }
119
120 // Iteration sur les Vertex
121
122 if (type == TopAbs_VERTEX || type == TopAbs_SHAPE) {
123 myExp.Init(shape, TopAbs_VERTEX);
124 while(myExp.More()) {
125 tol = BRep_Tool::Tolerance(TopoDS::Vertex(myExp.Current()));
126 if (tol >= valmin && (over || (tol >= valmax)) ) sl->Append (myExp.Current());
127 myExp.Next();
128 }
129 }
130
131 // Iteration combinee (cumul) SHELL+FACE+EDGE+VERTEX, on retourne SHELL+FACE
132
133 if (type == TopAbs_SHELL) {
134 // Exploration des shells
135 TopTools_MapOfShape mapface;
136 myExp.Init (shape, TopAbs_SHELL);
137 while(myExp.More()) {
138 Standard_Boolean iashell = Standard_False;
139 TopoDS_Shape ash = myExp.Current();
140 for (TopExp_Explorer face (ash,TopAbs_FACE); face.More(); face.Next()) {
141 mapface.Add (face.Current());
142 Handle(TopTools_HSequenceOfShape) fc =
143 InTolerance (face.Current(),valmin,valmax,type);
144 if (fc->Length() > 0) {
145 sl->Append(fc);
146 iashell = Standard_True;
147 }
148 }
149 if (iashell) sl->Append (ash);
150 myExp.Next();
151 }
152
153 // Les faces (libres ou sous shell)
154 myExp.Init (shape, TopAbs_FACE);
155 for (; myExp.More(); myExp.Next()) {
156 Standard_Boolean iaface = Standard_False;
157 if (mapface.Contains (myExp.Current()) ) continue;
158 tol = BRep_Tool::Tolerance(TopoDS::Face(myExp.Current()));
159 if (tol >= valmin && (over || (tol <= valmax)) ) iaface = Standard_True;
160 else {
161 // les edges contenues ?
162 Handle(TopTools_HSequenceOfShape) fl =
163 InTolerance (myExp.Current(),valmin,valmax,TopAbs_EDGE);
164 if (fl->Length() > 0) iaface = Standard_True;
165 else {
166 fl = InTolerance (myExp.Current(),valmin,valmax,TopAbs_VERTEX);
167 if (fl->Length() > 0) iaface = Standard_True;
168 }
169 }
170 if (iaface) sl->Append (myExp.Current());
171 }
172
173 }
174
175 return sl;
176}
177
178//=======================================================================
179//function : InitTolerance
180//purpose :
181//=======================================================================
182
183 void ShapeAnalysis_ShapeTolerance::InitTolerance()
184{
185 myNbTol = 0;
186 myTols[1] = 0;
187}
188
189//=======================================================================
190//function : AddTolerance
191//purpose :
192//=======================================================================
193
194 void ShapeAnalysis_ShapeTolerance::AddTolerance(const TopoDS_Shape& shape,const TopAbs_ShapeEnum type)
195{
196 Standard_Integer nbt = 0;
1d47d8d0 197 Standard_Real tol, cmin = 0.,cmoy = 0.,cmax = 0.;
7fd59977 198
199 TopExp_Explorer myExp;
200
201 // Iteration sur les Faces
202
203 if (type == TopAbs_FACE || type == TopAbs_SHAPE) {
204 myExp.Init(shape, TopAbs_FACE);
205 while(myExp.More()) {
206 tol = BRep_Tool::Tolerance(TopoDS::Face(myExp.Current()));
207 AddTol (tol,nbt,cmin,cmoy,cmax);
208 myExp.Next();
209 }
210 }
211
212 // Iteration sur les Edges
213
214 if (type == TopAbs_EDGE || type == TopAbs_SHAPE) {
215 myExp.Init(shape, TopAbs_EDGE);
216 while(myExp.More()) {
217 tol = BRep_Tool::Tolerance(TopoDS::Edge(myExp.Current()));
218 AddTol (tol,nbt,cmin,cmoy,cmax);
219 myExp.Next();
220 }
221 }
222
223 // Iteration sur les Vertices
224
225 if (type == TopAbs_VERTEX || type == TopAbs_SHAPE) {
226 myExp.Init(shape, TopAbs_VERTEX);
227 while(myExp.More()) {
228 tol = BRep_Tool::Tolerance(TopoDS::Vertex(myExp.Current()));
229 AddTol (tol,nbt,cmin,cmoy,cmax);
230 myExp.Next();
231 }
232 }
233
234// Resultat : attention en mode cumul
235 if (nbt == 0) return;
236 if (myNbTol == 0 || myTols[0] > cmin) myTols[0] = cmin;
237 if (myNbTol == 0 || myTols[2] < cmax) myTols[2] = cmax;
238 myTols[1] += cmoy;
239 myNbTol += nbt;
240}
241
242//=======================================================================
243//function : GlobalTolerance
244//purpose :
245//=======================================================================
246
247 Standard_Real ShapeAnalysis_ShapeTolerance::GlobalTolerance(const Standard_Integer mode) const
248{
249 //szv#4:S4163:12Mar99 optimized
250 Standard_Real result = 0.;
251 if (myNbTol != 0.) {
252 if (mode < 0) result = myTols[0];
253 else if (mode == 0) {
254 if (myTols[0] == myTols[2]) result = myTols[0];
255 else result = myTols[1] / myNbTol;
256 }
257 else result = myTols[2];
258 }
259
260 return result;
261}