Loading files
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
// #76 rln 11.03.99 S4135: compute average without weights according to tolerances
// szv#4 S4163
#include <BRep_Tool.hxx>
#include <ShapeAnalysis_ShapeTolerance.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_ShapeMapHasher.hxx>
#include <NCollection_Map.hxx>
//=================================================================================================
ShapeAnalysis_ShapeTolerance::ShapeAnalysis_ShapeTolerance()
: myNbTol(0)
{
}
static void AddTol(const double tol, int& nbt, double& cmin, double& cmoy, double& cmax)
{
nbt++;
if (nbt == 1)
{
cmin = cmoy = cmax = tol;
}
else
{
if (cmin > tol)
{
cmin = tol;
}
if (cmax < tol)
{
cmax = tol;
}
// cmoy += tol;
// Calcul en moyenne geometrique entre 1 et 1e-7
int mult = 1;
// #76 rln 11.03.99 S4135: compute average without weights according to tolerances
/* if (tol < 1.e-07) mult = 10000;
else if (tol < 1.e-06) mult = 3000;
else if (tol < 1.e-05) mult = 1000;
else if (tol < 1.e-04) mult = 300;
else if (tol < 1.e-03) mult = 100;
else if (tol < 1.e-02) mult = 30;
else if (tol < 1.e-01) mult = 10;
else if (tol < 1. ) mult = 3;
*/
nbt += (mult - 1);
cmoy += (tol * mult);
}
}
//=================================================================================================
double ShapeAnalysis_ShapeTolerance::Tolerance(const TopoDS_Shape& shape,
const int mode,
const TopAbs_ShapeEnum type)
{
InitTolerance();
AddTolerance(shape, type);
return GlobalTolerance(mode);
}
//=================================================================================================
occ::handle<NCollection_HSequence<TopoDS_Shape>> ShapeAnalysis_ShapeTolerance::OverTolerance(
const TopoDS_Shape& shape,
const double value,
const TopAbs_ShapeEnum type) const
{
if (value >= 0)
{
return InTolerance(shape, value, 0., type);
}
else
{
return InTolerance(shape, 0., value, type);
}
}
//=================================================================================================
occ::handle<NCollection_HSequence<TopoDS_Shape>> ShapeAnalysis_ShapeTolerance::InTolerance(
const TopoDS_Shape& shape,
const double valmin,
const double valmax,
const TopAbs_ShapeEnum type) const
{
double tol;
bool over = (valmax < valmin); // pas de liminite max
occ::handle<NCollection_HSequence<TopoDS_Shape>> sl = new NCollection_HSequence<TopoDS_Shape>();
TopExp_Explorer myExp;
// Iteration sur les Faces
if (type == TopAbs_FACE || type == TopAbs_SHAPE)
{
myExp.Init(shape, TopAbs_FACE);
while (myExp.More())
{
tol = BRep_Tool::Tolerance(TopoDS::Face(myExp.Current()));
if (tol >= valmin && (over || (tol <= valmax)))
{
sl->Append(myExp.Current());
}
myExp.Next();
}
}
// Iteration sur les Edges
if (type == TopAbs_EDGE || type == TopAbs_SHAPE)
{
myExp.Init(shape, TopAbs_EDGE);
while (myExp.More())
{
tol = BRep_Tool::Tolerance(TopoDS::Edge(myExp.Current()));
if (tol >= valmin && (over || (tol <= valmax)))
{
sl->Append(myExp.Current());
}
myExp.Next();
}
}
// Iteration sur les Vertex
if (type == TopAbs_VERTEX || type == TopAbs_SHAPE)
{
myExp.Init(shape, TopAbs_VERTEX);
while (myExp.More())
{
tol = BRep_Tool::Tolerance(TopoDS::Vertex(myExp.Current()));
if (tol >= valmin && (over || (tol >= valmax)))
{
sl->Append(myExp.Current());
}
myExp.Next();
}
}
// Iteration combinee (cumul) SHELL+FACE+EDGE+VERTEX, on retourne SHELL+FACE
if (type == TopAbs_SHELL)
{
// Exploration des shells
NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> mapface;
myExp.Init(shape, TopAbs_SHELL);
while (myExp.More())
{
bool iashell = false;
TopoDS_Shape ash = myExp.Current();
for (TopExp_Explorer face(ash, TopAbs_FACE); face.More(); face.Next())
{
mapface.Add(face.Current());
occ::handle<NCollection_HSequence<TopoDS_Shape>> fc =
InTolerance(face.Current(), valmin, valmax, type);
if (fc->Length() > 0)
{
sl->Append(fc);
iashell = true;
}
}
if (iashell)
{
sl->Append(ash);
}
myExp.Next();
}
// Les faces (libres ou sous shell)
myExp.Init(shape, TopAbs_FACE);
for (; myExp.More(); myExp.Next())
{
bool iaface = false;
if (mapface.Contains(myExp.Current()))
{
continue;
}
tol = BRep_Tool::Tolerance(TopoDS::Face(myExp.Current()));
if (tol >= valmin && (over || (tol <= valmax)))
{
iaface = true;
}
else
{
// les edges contenues ?
occ::handle<NCollection_HSequence<TopoDS_Shape>> fl =
InTolerance(myExp.Current(), valmin, valmax, TopAbs_EDGE);
if (fl->Length() > 0)
{
iaface = true;
}
else
{
fl = InTolerance(myExp.Current(), valmin, valmax, TopAbs_VERTEX);
if (fl->Length() > 0)
{
iaface = true;
}
}
}
if (iaface)
{
sl->Append(myExp.Current());
}
}
}
return sl;
}
//=================================================================================================
void ShapeAnalysis_ShapeTolerance::InitTolerance()
{
myNbTol = 0;
myTols[1] = 0;
}
//=================================================================================================
void ShapeAnalysis_ShapeTolerance::AddTolerance(const TopoDS_Shape& shape,
const TopAbs_ShapeEnum type)
{
int nbt = 0;
double tol, cmin = 0., cmoy = 0., cmax = 0.;
TopExp_Explorer myExp;
// Iteration sur les Faces
if (type == TopAbs_FACE || type == TopAbs_SHAPE)
{
myExp.Init(shape, TopAbs_FACE);
while (myExp.More())
{
tol = BRep_Tool::Tolerance(TopoDS::Face(myExp.Current()));
AddTol(tol, nbt, cmin, cmoy, cmax);
myExp.Next();
}
}
// Iteration sur les Edges
if (type == TopAbs_EDGE || type == TopAbs_SHAPE)
{
myExp.Init(shape, TopAbs_EDGE);
while (myExp.More())
{
tol = BRep_Tool::Tolerance(TopoDS::Edge(myExp.Current()));
AddTol(tol, nbt, cmin, cmoy, cmax);
myExp.Next();
}
}
// Iteration sur les Vertices
if (type == TopAbs_VERTEX || type == TopAbs_SHAPE)
{
myExp.Init(shape, TopAbs_VERTEX);
while (myExp.More())
{
tol = BRep_Tool::Tolerance(TopoDS::Vertex(myExp.Current()));
AddTol(tol, nbt, cmin, cmoy, cmax);
myExp.Next();
}
}
// Resultat : attention en mode cumul
if (nbt == 0)
{
return;
}
if (myNbTol == 0 || myTols[0] > cmin)
{
myTols[0] = cmin;
}
if (myNbTol == 0 || myTols[2] < cmax)
{
myTols[2] = cmax;
}
myTols[1] += cmoy;
myNbTol += nbt;
}
//=================================================================================================
double ShapeAnalysis_ShapeTolerance::GlobalTolerance(const int mode) const
{
// szv#4:S4163:12Mar99 optimized
double result = 0.;
if (myNbTol != 0.)
{
if (mode < 0)
{
result = myTols[0];
}
else if (mode == 0)
{
if (myTols[0] == myTols[2])
{
result = myTols[0];
}
else
{
result = myTols[1] / myNbTol;
}
}
else
{
result = myTols[2];
}
}
return result;
}