0021866: [CEA 670] Returning exact coordinates of the bounding box

This commit is contained in:
skv 2013-05-23 12:53:40 +00:00
parent 18129b41a4
commit e6a58b5819
14 changed files with 465 additions and 393 deletions

View File

@ -14,9 +14,10 @@ faces (by iterating through all faces of a shape).
This functionallity is implemented in such a way to have This functionallity is implemented in such a way to have
a satisfactory performance. a satisfactory performance.
\n <b>TUI Commands:</b> <em>[Xmin,Xmax, Ymin,Ymax, Zmin,Zmax] = geompy.BoundingBox(Shape)</em>, \n <b>TUI Commands:</b> <em>[Xmin,Xmax, Ymin,Ymax, Zmin,Zmax] = geompy.BoundingBox(Shape, precise)</em>,
<em>BBox = geompy.MakeBoundingBox(Shape)</em>, where \em Shape <em>BBox = geompy.MakeBoundingBox(Shape, precise)</em>, where \em Shape
is the shape for which the bounding box is computed. is the shape for which the bounding box is computed. \em precise TRUE
for precise computation; FALSE for fast one. Default value is False.
See also a \ref tui_bounding_box_page "TUI example". See also a \ref tui_bounding_box_page "TUI example".

View File

@ -3640,12 +3640,14 @@ module GEOM
/*! /*!
* \brief Get parameters of bounding box of the given shape * \brief Get parameters of bounding box of the given shape
* \param theShape Shape to obtain bounding box of. * \param theShape Shape to obtain bounding box of.
* \param precise TRUE for precise computation; FALSE for fast one.
* \param Xmin,Xmax Output. Limits of shape along OX axis. * \param Xmin,Xmax Output. Limits of shape along OX axis.
* \param Ymin,Ymax Output. Limits of shape along OY axis. * \param Ymin,Ymax Output. Limits of shape along OY axis.
* \param Zmin,Zmax Output. Limits of shape along OZ axis. * \param Zmin,Zmax Output. Limits of shape along OZ axis.
* \return Returns parameters of bounding box through the last six arguments. * \return Returns parameters of bounding box through the last six arguments.
*/ */
void GetBoundingBox (in GEOM_Object theShape, void GetBoundingBox (in GEOM_Object theShape,
in boolean precise,
out double Xmin, out double Xmax, out double Xmin, out double Xmax,
out double Ymin, out double Ymax, out double Ymin, out double Ymax,
out double Zmin, out double Zmax); out double Zmin, out double Zmax);
@ -3653,9 +3655,11 @@ module GEOM
/*! /*!
* \brief Get bounding box of the given shape * \brief Get bounding box of the given shape
* \param theShape Shape to obtain bounding box of. * \param theShape Shape to obtain bounding box of.
* \param precise TRUE for precise computation; FALSE for fast one.
* \return New GEOM_Object, containing the created bounding box. * \return New GEOM_Object, containing the created bounding box.
*/ */
GEOM_Object MakeBoundingBox (in GEOM_Object theShape); GEOM_Object MakeBoundingBox (in GEOM_Object theShape,
in boolean precise);
/*! /*!
* \brief Get min and max tolerances of sub-shapes of theShape * \brief Get min and max tolerances of sub-shapes of theShape

View File

@ -91,27 +91,14 @@
#include <ShapeAnalysis.hxx> #include <ShapeAnalysis.hxx>
#include <ShapeAnalysis_Surface.hxx> #include <ShapeAnalysis_Surface.hxx>
#include <ShapeFix_Shape.hxx>
#include <GeomAPI_IntSS.hxx> #include <GeomAPI_IntSS.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx> #include <GeomAPI_ProjectPointOnCurve.hxx>
#include <GeomAbs_SurfaceType.hxx> #include <GeomAbs_SurfaceType.hxx>
#include <Geom_BezierSurface.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_Circle.hxx>
#include <Geom_ConicalSurface.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_Line.hxx> #include <Geom_Line.hxx>
#include <Geom_OffsetSurface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_Surface.hxx> #include <Geom_Surface.hxx>
#include <Geom_SurfaceOfLinearExtrusion.hxx>
#include <Geom_SurfaceOfRevolution.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <GeomLProp_CLProps.hxx> #include <GeomLProp_CLProps.hxx>
#include <GeomLProp_SLProps.hxx> #include <GeomLProp_SLProps.hxx>
@ -1120,6 +1107,7 @@ void GEOMImpl_IMeasureOperations::GetInertia
//============================================================================= //=============================================================================
void GEOMImpl_IMeasureOperations::GetBoundingBox void GEOMImpl_IMeasureOperations::GetBoundingBox
(Handle(GEOM_Object) theShape, (Handle(GEOM_Object) theShape,
const Standard_Boolean precise,
Standard_Real& Xmin, Standard_Real& Xmax, Standard_Real& Xmin, Standard_Real& Xmax,
Standard_Real& Ymin, Standard_Real& Ymax, Standard_Real& Ymin, Standard_Real& Ymax,
Standard_Real& Zmin, Standard_Real& Zmax) Standard_Real& Zmin, Standard_Real& Zmax)
@ -1156,6 +1144,14 @@ void GEOMImpl_IMeasureOperations::GetBoundingBox
BRepTools::Clean(aShape); BRepTools::Clean(aShape);
BRepBndLib::Add(aShape, B); BRepBndLib::Add(aShape, B);
if (precise) {
if (!GEOMUtils::PreciseBoundingBox(aShape, B)) {
SetErrorCode("GetBoundingBox Error: Bounding box cannot be precised");
return;
}
}
B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
} }
catch (Standard_Failure) { catch (Standard_Failure) {
@ -1173,7 +1169,8 @@ void GEOMImpl_IMeasureOperations::GetBoundingBox
*/ */
//============================================================================= //=============================================================================
Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
(Handle(GEOM_Object) theShape) (Handle(GEOM_Object) theShape,
const Standard_Boolean precise)
{ {
SetErrorCode(KO); SetErrorCode(KO);
@ -1183,8 +1180,9 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
Handle(GEOM_Object) aBnd = GetEngine()->AddObject(GetDocID(), GEOM_BOX); Handle(GEOM_Object) aBnd = GetEngine()->AddObject(GetDocID(), GEOM_BOX);
//Add a new BoundingBox function //Add a new BoundingBox function
const int aType = (precise ? BND_BOX_MEASURE_PRECISE : BND_BOX_MEASURE);
Handle(GEOM_Function) aFunction = Handle(GEOM_Function) aFunction =
aBnd->AddFunction(GEOMImpl_MeasureDriver::GetID(), BND_BOX_MEASURE); aBnd->AddFunction(GEOMImpl_MeasureDriver::GetID(), aType);
if (aFunction.IsNull()) return NULL; if (aFunction.IsNull()) return NULL;
//Check if the function is set correctly //Check if the function is set correctly
@ -1214,7 +1212,15 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
} }
//Make a Python command //Make a Python command
GEOM::TPythonDump(aFunction) << aBnd << " = geompy.MakeBoundingBox(" << theShape << ")"; GEOM::TPythonDump aPd(aFunction);
aPd << aBnd << " = geompy.MakeBoundingBox(" << theShape;
if (precise) {
aPd << ", True";
}
aPd << ")";
SetErrorCode(OK); SetErrorCode(OK);
return aBnd; return aBnd;
@ -1584,308 +1590,6 @@ std::vector<bool> GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Objec
return res; return res;
} }
//=======================================================================
//function : CheckSingularCase
//purpose : auxilary for GetMinDistance()
// workaround for bugs 19899, 19908 and 19910 from Mantis
//=======================================================================
static double CheckSingularCase(const TopoDS_Shape& aSh1,
const TopoDS_Shape& aSh2,
gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
{
bool IsChange1 = false;
double AddDist1 = 0.0;
TopExp_Explorer anExp;
TopoDS_Shape tmpSh1, tmpSh2;
int nbf = 0;
for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
nbf++;
tmpSh1 = anExp.Current();
}
if(nbf==1) {
TopoDS_Shape sh = aSh1;
while(sh.ShapeType()==TopAbs_COMPOUND) {
TopoDS_Iterator it(sh);
sh = it.Value();
}
Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
// non solid case
double U1,U2,V1,V2;
// changes for 0020677: EDF 1219 GEOM: MinDistance gives 0 instead of 20.88
//S->Bounds(U1,U2,V1,V2); changed by
ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh1),U1,U2,V1,V2);
// end of changes for 020677 (dmv)
Handle(Geom_RectangularTrimmedSurface) TrS1 =
new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
Handle(Geom_RectangularTrimmedSurface) TrS2 =
new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
BRep_Builder B;
TopoDS_Face F1,F2;
TopoDS_Compound Comp;
B.MakeCompound(Comp);
B.MakeFace(F1,TrS1,1.e-7);
B.Add(Comp,F1);
B.MakeFace(F2,TrS2,1.e-7);
B.Add(Comp,F2);
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
sfs->Init(Comp);
sfs->SetPrecision(1.e-6);
sfs->SetMaxTolerance(1.0);
sfs->Perform();
tmpSh1 = sfs->Shape();
IsChange1 = true;
}
else {
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
gp_Pnt PC = SS->Location();
BRep_Builder B;
TopoDS_Vertex V;
B.MakeVertex(V,PC,1.e-7);
tmpSh1 = V;
AddDist1 = SS->Radius();
IsChange1 = true;
}
else {
Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
gp_Ax3 ax3 = TS->Position();
Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
BRep_Builder B;
TopoDS_Edge E;
B.MakeEdge(E,C,1.e-7);
tmpSh1 = E;
AddDist1 = TS->MinorRadius();
IsChange1 = true;
}
}
}
else
tmpSh1 = aSh1;
}
else
tmpSh1 = aSh1;
bool IsChange2 = false;
double AddDist2 = 0.0;
nbf = 0;
for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
nbf++;
tmpSh2 = anExp.Current();
}
if(nbf==1) {
TopoDS_Shape sh = aSh2;
while(sh.ShapeType()==TopAbs_COMPOUND) {
TopoDS_Iterator it(sh);
sh = it.Value();
}
Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
// non solid case
double U1,U2,V1,V2;
//S->Bounds(U1,U2,V1,V2);
ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh2),U1,U2,V1,V2);
Handle(Geom_RectangularTrimmedSurface) TrS1 =
new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
Handle(Geom_RectangularTrimmedSurface) TrS2 =
new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
BRep_Builder B;
TopoDS_Face F1,F2;
TopoDS_Compound Comp;
B.MakeCompound(Comp);
B.MakeFace(F1,TrS1,1.e-7);
B.Add(Comp,F1);
B.MakeFace(F2,TrS2,1.e-7);
B.Add(Comp,F2);
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
sfs->Init(Comp);
sfs->SetPrecision(1.e-6);
sfs->SetMaxTolerance(1.0);
sfs->Perform();
tmpSh2 = sfs->Shape();
IsChange2 = true;
}
else {
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
gp_Pnt PC = SS->Location();
BRep_Builder B;
TopoDS_Vertex V;
B.MakeVertex(V,PC,1.e-7);
tmpSh2 = V;
AddDist2 = SS->Radius();
IsChange2 = true;
}
else if( S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
gp_Ax3 ax3 = TS->Position();
Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
BRep_Builder B;
TopoDS_Edge E;
B.MakeEdge(E,C,1.e-7);
tmpSh2 = E;
AddDist2 = TS->MinorRadius();
IsChange2 = true;
}
}
}
else
tmpSh2 = aSh2;
}
else
tmpSh2 = aSh2;
if( !IsChange1 && !IsChange2 )
return -2.0;
BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2);
if (dst.IsDone()) {
double MinDist = 1.e9;
gp_Pnt PMin1, PMin2, P1, P2;
for (int i = 1; i <= dst.NbSolution(); i++) {
P1 = dst.PointOnShape1(i);
P2 = dst.PointOnShape2(i);
Standard_Real Dist = P1.Distance(P2);
if (MinDist > Dist) {
MinDist = Dist;
PMin1 = P1;
PMin2 = P2;
}
}
if(MinDist<1.e-7) {
Ptmp1 = PMin1;
Ptmp2 = PMin2;
}
else {
gp_Dir aDir(gp_Vec(PMin1,PMin2));
if( MinDist > (AddDist1+AddDist2) ) {
Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
PMin1.Y() + aDir.Y()*AddDist1,
PMin1.Z() + aDir.Z()*AddDist1 );
Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
PMin2.Y() - aDir.Y()*AddDist2,
PMin2.Z() - aDir.Z()*AddDist2 );
return (MinDist - AddDist1 - AddDist2);
}
else {
if( AddDist1 > 0 ) {
Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
PMin1.Y() + aDir.Y()*AddDist1,
PMin1.Z() + aDir.Z()*AddDist1 );
Ptmp2 = Ptmp1;
}
else {
Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
PMin2.Y() - aDir.Y()*AddDist2,
PMin2.Z() - aDir.Z()*AddDist2 );
Ptmp1 = Ptmp2;
}
}
}
double res = MinDist - AddDist1 - AddDist2;
if(res<0.) res = 0.0;
return res;
}
return -2.0;
}
/* old variant
static bool CheckSingularCase(const TopoDS_Shape& aSh1,
const TopoDS_Shape& aSh2,
gp_Pnt& Ptmp)
{
TopExp_Explorer anExp;
TopoDS_Shape tmpSh1, tmpSh2;
int nbf = 0;
for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
nbf++;
tmpSh1 = anExp.Current();
}
if(nbf==1) {
Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
nbf = 0;
for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
nbf++;
tmpSh2 = anExp.Current();
Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
GeomAPI_IntSS ISS(S1,S2,1.e-7);
if(ISS.IsDone()) {
for(int i=1; i<=ISS.NbLines(); i++) {
Handle(Geom_Curve) C3d = ISS.Line(i);
BRep_Builder B;
TopoDS_Edge E;
B.MakeEdge(E,C3d,1.e-7);
BRepExtrema_DistShapeShape dst(tmpSh2,E);
if (dst.IsDone()) {
gp_Pnt PMin1, PMin2, P1, P2;
double MinDist = 1.e9;
for (int i = 1; i <= dst.NbSolution(); i++) {
P1 = dst.PointOnShape1(i);
P2 = dst.PointOnShape2(i);
Standard_Real Dist = P1.Distance(P2);
if (MinDist > Dist) {
MinDist = Dist;
Ptmp = P1;
}
}
if(MinDist<1.e-7)
return true;
}
}
}
}
}
}
nbf = 0;
for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
nbf++;
tmpSh1 = anExp.Current();
}
if(nbf==1) {
Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
nbf = 0;
for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
nbf++;
tmpSh2 = anExp.Current();
Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
GeomAPI_IntSS ISS(S1,S2,1.e-7);
if(ISS.IsDone()) {
for(int i=1; i<=ISS.NbLines(); i++) {
Handle(Geom_Curve) C3d = ISS.Line(i);
BRep_Builder B;
TopoDS_Edge E;
B.MakeEdge(E,C3d,1.e-7);
BRepExtrema_DistShapeShape dst(tmpSh2,E);
if (dst.IsDone()) {
gp_Pnt P1,P2;
double MinDist = 1.e9;
for (int i = 1; i <= dst.NbSolution(); i++) {
P1 = dst.PointOnShape1(i);
P2 = dst.PointOnShape2(i);
Standard_Real Dist = P1.Distance(P2);
if (MinDist > Dist) {
MinDist = Dist;
Ptmp = P1;
}
}
if(MinDist<1.e-7)
return true;
}
}
}
}
}
}
return false;
}
*/
//============================================================================= //=============================================================================
/*! /*!
* GetMinDistance * GetMinDistance
@ -1918,63 +1622,15 @@ Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance
OCC_CATCH_SIGNALS; OCC_CATCH_SIGNALS;
#endif #endif
// Issue 0020231: A min distance bug with torus and vertex. gp_Pnt aPnt1, aPnt2;
// Make GetMinDistance() return zero if a sole VERTEX is inside any of SOLIDs
// which of shapes consists of only one vertex? MinDist = GEOMUtils::GetMinDistance(aShape1, aShape2, aPnt1, aPnt2);
TopExp_Explorer exp1(aShape1,TopAbs_VERTEX), exp2(aShape2,TopAbs_VERTEX);
TopoDS_Shape V1 = exp1.More() ? exp1.Current() : TopoDS_Shape();
TopoDS_Shape V2 = exp2.More() ? exp2.Current() : TopoDS_Shape();
exp1.Next(); exp2.Next();
if ( exp1.More() ) V1.Nullify();
if ( exp2.More() ) V2.Nullify();
// vertex and container of solids
TopoDS_Shape V = V1.IsNull() ? V2 : V1;
TopoDS_Shape S = V1.IsNull() ? aShape1 : aShape2;
if ( !V.IsNull() ) {
// classify vertex against solids
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( V ) );
for ( exp1.Init( S, TopAbs_SOLID ); exp1.More(); exp1.Next() ) {
BRepClass3d_SolidClassifier classifier( exp1.Current(), p, 1e-6);
if ( classifier.State() == TopAbs_IN ) {
p.Coord(X1, Y1, Z1);
p.Coord(X2, Y2, Z2);
SetErrorCode(OK);
return 0.0;
}
}
}
// End Issue 0020231
// skl 30.06.2008 if (MinDist >= 0.0) {
// additional workaround for bugs 19899, 19908 and 19910 from Mantis aPnt1.Coord(X1, Y1, Z1);
gp_Pnt Ptmp1, Ptmp2; aPnt2.Coord(X2, Y2, Z2);
double dist = CheckSingularCase(aShape1, aShape2, Ptmp1, Ptmp2); } else {
if (dist > -1.0) { return MinDist;
Ptmp1.Coord(X1, Y1, Z1);
Ptmp2.Coord(X2, Y2, Z2);
SetErrorCode(OK);
return dist;
}
BRepExtrema_DistShapeShape dst (aShape1, aShape2);
if (dst.IsDone()) {
gp_Pnt PMin1, PMin2, P1, P2;
for (int i = 1; i <= dst.NbSolution(); i++) {
P1 = dst.PointOnShape1(i);
P2 = dst.PointOnShape2(i);
Standard_Real Dist = P1.Distance(P2);
if (MinDist > Dist) {
MinDist = Dist;
PMin1 = P1;
PMin2 = P2;
}
}
PMin1.Coord(X1, Y1, Z1);
PMin2.Coord(X2, Y2, Z2);
} }
} }
catch (Standard_Failure) { catch (Standard_Failure) {
@ -2021,7 +1677,7 @@ Standard_Integer GEOMImpl_IMeasureOperations::ClosestPoints (Handle(GEOM_Object)
// skl 30.06.2008 // skl 30.06.2008
// additional workaround for bugs 19899, 19908 and 19910 from Mantis // additional workaround for bugs 19899, 19908 and 19910 from Mantis
gp_Pnt P1, P2; gp_Pnt P1, P2;
double dist = CheckSingularCase(aShape1, aShape2, P1, P2); double dist = GEOMUtils::GetMinDistanceSingular(aShape1, aShape2, P1, P2);
if (dist > -1.0) { if (dist > -1.0) {
nbSolutions = 1; nbSolutions = 1;

View File

@ -114,11 +114,13 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
Standard_Real& Ix , Standard_Real& Iy , Standard_Real& Iz); Standard_Real& Ix , Standard_Real& Iy , Standard_Real& Iz);
Standard_EXPORT void GetBoundingBox (Handle(GEOM_Object) theShape, Standard_EXPORT void GetBoundingBox (Handle(GEOM_Object) theShape,
const Standard_Boolean precise,
Standard_Real& Xmin, Standard_Real& Xmax, Standard_Real& Xmin, Standard_Real& Xmax,
Standard_Real& Ymin, Standard_Real& Ymax, Standard_Real& Ymin, Standard_Real& Ymax,
Standard_Real& Zmin, Standard_Real& Zmax); Standard_Real& Zmin, Standard_Real& Zmax);
Standard_EXPORT Handle(GEOM_Object) GetBoundingBox (Handle(GEOM_Object) theShape); Standard_EXPORT Handle(GEOM_Object) GetBoundingBox (Handle(GEOM_Object) theShape,
const Standard_Boolean precise);
Standard_EXPORT void GetTolerance (Handle(GEOM_Object) theShape, Standard_EXPORT void GetTolerance (Handle(GEOM_Object) theShape,
Standard_Real& FaceMin, Standard_Real& FaceMax, Standard_Real& FaceMin, Standard_Real& FaceMax,

View File

@ -105,7 +105,7 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
gp_Pnt aCenterMass = aPos.Location(); gp_Pnt aCenterMass = aPos.Location();
aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape(); aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
} }
else if (aType == BND_BOX_MEASURE) else if (aType == BND_BOX_MEASURE || aType == BND_BOX_MEASURE_PRECISE)
{ {
Handle(GEOM_Function) aRefBase = aCI.GetBase(); Handle(GEOM_Function) aRefBase = aCI.GetBase();
TopoDS_Shape aShapeBase = aRefBase->GetValue(); TopoDS_Shape aShapeBase = aRefBase->GetValue();
@ -124,6 +124,12 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
Bnd_Box B; Bnd_Box B;
BRepBndLib::Add(aShapeBase, B); BRepBndLib::Add(aShapeBase, B);
if (aType == BND_BOX_MEASURE_PRECISE) {
if (!GEOMUtils::PreciseBoundingBox(aShapeBase, B)) {
Standard_NullObject::Raise("Bounding box cannot be precised");
}
}
Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax; Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);

View File

@ -319,6 +319,7 @@
// Measures // Measures
#define CDG_MEASURE 1 #define CDG_MEASURE 1
#define BND_BOX_MEASURE 2 #define BND_BOX_MEASURE 2
#define BND_BOX_MEASURE_PRECISE 3
#define VECTOR_FACE_NORMALE 4 #define VECTOR_FACE_NORMALE 4
#define VERTEX_BY_INDEX 5 #define VERTEX_BY_INDEX 5

View File

@ -41,6 +41,10 @@
#include <BRepGProp.hxx> #include <BRepGProp.hxx>
#include <BRepTools.hxx> #include <BRepTools.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <Bnd_Box.hxx> #include <Bnd_Box.hxx>
#include <TopAbs.hxx> #include <TopAbs.hxx>
@ -58,8 +62,12 @@
#include <TopTools_ListIteratorOfListOfShape.hxx> #include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_Array1OfShape.hxx> #include <TopTools_Array1OfShape.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Surface.hxx> #include <Geom_Surface.hxx>
#include <Geom_Plane.hxx> #include <Geom_Plane.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <GeomLProp_CLProps.hxx> #include <GeomLProp_CLProps.hxx>
#include <GeomLProp_SLProps.hxx> #include <GeomLProp_SLProps.hxx>
@ -72,6 +80,9 @@
#include <gp_Pln.hxx> #include <gp_Pln.hxx>
#include <gp_Lin.hxx> #include <gp_Lin.hxx>
#include <ShapeAnalysis.hxx>
#include <ShapeFix_Shape.hxx>
#include <vector> #include <vector>
#include <Standard_Failure.hxx> #include <Standard_Failure.hxx>
@ -600,3 +611,343 @@ TopoDS_Shape GEOMUtils::GetEdgeNearPoint (const TopoDS_Shape& theShape,
return aResult; return aResult;
} }
//=======================================================================
//function : PreciseBoundingBox
//purpose :
//=======================================================================
Standard_Boolean GEOMUtils::PreciseBoundingBox
(const TopoDS_Shape &theShape, Bnd_Box &theBox)
{
Standard_Real aBound[6];
theBox.Get(aBound[0], aBound[2], aBound[4], aBound[1], aBound[3], aBound[5]);
Standard_Integer i;
const gp_Pnt aMid(0.5*(aBound[1] + aBound[0]), // XMid
0.5*(aBound[3] + aBound[2]), // YMid
0.5*(aBound[5] + aBound[4])); // ZMid
const gp_XYZ aSize(aBound[1] - aBound[0], // DX
aBound[3] - aBound[2], // DY
aBound[5] - aBound[4]); // DZ
const gp_Pnt aPnt[6] =
{
gp_Pnt(aBound[0] - (aBound[1] - aBound[0]), aMid.Y(), aMid.Z()), // XMin
gp_Pnt(aBound[1] + (aBound[1] - aBound[0]), aMid.Y(), aMid.Z()), // XMax
gp_Pnt(aMid.X(), aBound[2] - (aBound[3] - aBound[2]), aMid.Z()), // YMin
gp_Pnt(aMid.X(), aBound[3] + (aBound[3] - aBound[2]), aMid.Z()), // YMax
gp_Pnt(aMid.X(), aMid.Y(), aBound[4] - (aBound[5] - aBound[4])), // ZMin
gp_Pnt(aMid.X(), aMid.Y(), aBound[5] + (aBound[5] - aBound[4])) // ZMax
};
const gp_Dir aDir[3] = { gp::DX(), gp::DY(), gp::DZ() };
const Standard_Real aPlnSize[3] =
{
0.5*Max(aSize.Y(), aSize.Z()), // XMin, XMax planes
0.5*Max(aSize.X(), aSize.Z()), // YMin, YMax planes
0.5*Max(aSize.X(), aSize.Y()) // ZMin, ZMax planes
};
gp_Pnt aPMin[2];
for (i = 0; i < 6; i++) {
const Standard_Integer iHalf = i/2;
const gp_Pln aPln(aPnt[i], aDir[iHalf]);
BRepBuilderAPI_MakeFace aMkFace(aPln, -aPlnSize[iHalf], aPlnSize[iHalf],
-aPlnSize[iHalf], aPlnSize[iHalf]);
if (!aMkFace.IsDone()) {
return Standard_False;
}
TopoDS_Shape aFace = aMkFace.Shape();
// Get minimal distance between planar face and shape.
Standard_Real aMinDist =
GEOMUtils::GetMinDistance(aFace, theShape, aPMin[0], aPMin[1]);
if (aMinDist < 0.) {
return Standard_False;
}
aBound[i] = aPMin[1].Coord(iHalf + 1);
}
// Update Bounding box with the new values.
theBox.SetVoid();
theBox.Update(aBound[0], aBound[2], aBound[4], aBound[1], aBound[3], aBound[5]);
return Standard_True;
}
//=======================================================================
//function : GetMinDistanceSingular
//purpose :
//=======================================================================
double GEOMUtils::GetMinDistanceSingular(const TopoDS_Shape& aSh1,
const TopoDS_Shape& aSh2,
gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
{
bool IsChange1 = false;
double AddDist1 = 0.0;
TopExp_Explorer anExp;
TopoDS_Shape tmpSh1, tmpSh2;
int nbf = 0;
for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
nbf++;
tmpSh1 = anExp.Current();
}
if(nbf==1) {
TopoDS_Shape sh = aSh1;
while(sh.ShapeType()==TopAbs_COMPOUND) {
TopoDS_Iterator it(sh);
sh = it.Value();
}
Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
// non solid case
double U1,U2,V1,V2;
// changes for 0020677: EDF 1219 GEOM: MinDistance gives 0 instead of 20.88
//S->Bounds(U1,U2,V1,V2); changed by
ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh1),U1,U2,V1,V2);
// end of changes for 020677 (dmv)
Handle(Geom_RectangularTrimmedSurface) TrS1 =
new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
Handle(Geom_RectangularTrimmedSurface) TrS2 =
new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
BRep_Builder B;
TopoDS_Face F1,F2;
TopoDS_Compound Comp;
B.MakeCompound(Comp);
B.MakeFace(F1,TrS1,1.e-7);
B.Add(Comp,F1);
B.MakeFace(F2,TrS2,1.e-7);
B.Add(Comp,F2);
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
sfs->Init(Comp);
sfs->SetPrecision(1.e-6);
sfs->SetMaxTolerance(1.0);
sfs->Perform();
tmpSh1 = sfs->Shape();
IsChange1 = true;
}
else {
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
gp_Pnt PC = SS->Location();
BRep_Builder B;
TopoDS_Vertex V;
B.MakeVertex(V,PC,1.e-7);
tmpSh1 = V;
AddDist1 = SS->Radius();
IsChange1 = true;
}
else {
Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
gp_Ax3 ax3 = TS->Position();
Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
BRep_Builder B;
TopoDS_Edge E;
B.MakeEdge(E,C,1.e-7);
tmpSh1 = E;
AddDist1 = TS->MinorRadius();
IsChange1 = true;
}
}
}
else
tmpSh1 = aSh1;
}
else
tmpSh1 = aSh1;
bool IsChange2 = false;
double AddDist2 = 0.0;
nbf = 0;
for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
nbf++;
tmpSh2 = anExp.Current();
}
if(nbf==1) {
TopoDS_Shape sh = aSh2;
while(sh.ShapeType()==TopAbs_COMPOUND) {
TopoDS_Iterator it(sh);
sh = it.Value();
}
Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
// non solid case
double U1,U2,V1,V2;
//S->Bounds(U1,U2,V1,V2);
ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh2),U1,U2,V1,V2);
Handle(Geom_RectangularTrimmedSurface) TrS1 =
new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
Handle(Geom_RectangularTrimmedSurface) TrS2 =
new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
BRep_Builder B;
TopoDS_Face F1,F2;
TopoDS_Compound Comp;
B.MakeCompound(Comp);
B.MakeFace(F1,TrS1,1.e-7);
B.Add(Comp,F1);
B.MakeFace(F2,TrS2,1.e-7);
B.Add(Comp,F2);
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
sfs->Init(Comp);
sfs->SetPrecision(1.e-6);
sfs->SetMaxTolerance(1.0);
sfs->Perform();
tmpSh2 = sfs->Shape();
IsChange2 = true;
}
else {
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
gp_Pnt PC = SS->Location();
BRep_Builder B;
TopoDS_Vertex V;
B.MakeVertex(V,PC,1.e-7);
tmpSh2 = V;
AddDist2 = SS->Radius();
IsChange2 = true;
}
else if( S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
gp_Ax3 ax3 = TS->Position();
Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
BRep_Builder B;
TopoDS_Edge E;
B.MakeEdge(E,C,1.e-7);
tmpSh2 = E;
AddDist2 = TS->MinorRadius();
IsChange2 = true;
}
}
}
else
tmpSh2 = aSh2;
}
else
tmpSh2 = aSh2;
if( !IsChange1 && !IsChange2 )
return -2.0;
BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2);
if (dst.IsDone()) {
double MinDist = 1.e9;
gp_Pnt PMin1, PMin2, P1, P2;
for (int i = 1; i <= dst.NbSolution(); i++) {
P1 = dst.PointOnShape1(i);
P2 = dst.PointOnShape2(i);
Standard_Real Dist = P1.Distance(P2);
if (MinDist > Dist) {
MinDist = Dist;
PMin1 = P1;
PMin2 = P2;
}
}
if(MinDist<1.e-7) {
Ptmp1 = PMin1;
Ptmp2 = PMin2;
}
else {
gp_Dir aDir(gp_Vec(PMin1,PMin2));
if( MinDist > (AddDist1+AddDist2) ) {
Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
PMin1.Y() + aDir.Y()*AddDist1,
PMin1.Z() + aDir.Z()*AddDist1 );
Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
PMin2.Y() - aDir.Y()*AddDist2,
PMin2.Z() - aDir.Z()*AddDist2 );
return (MinDist - AddDist1 - AddDist2);
}
else {
if( AddDist1 > 0 ) {
Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
PMin1.Y() + aDir.Y()*AddDist1,
PMin1.Z() + aDir.Z()*AddDist1 );
Ptmp2 = Ptmp1;
}
else {
Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
PMin2.Y() - aDir.Y()*AddDist2,
PMin2.Z() - aDir.Z()*AddDist2 );
Ptmp1 = Ptmp2;
}
}
}
double res = MinDist - AddDist1 - AddDist2;
if(res<0.) res = 0.0;
return res;
}
return -2.0;
}
//=======================================================================
//function : GetMinDistance
//purpose :
//=======================================================================
Standard_Real GEOMUtils::GetMinDistance
(const TopoDS_Shape& theShape1,
const TopoDS_Shape& theShape2,
gp_Pnt& thePnt1, gp_Pnt& thePnt2)
{
Standard_Real aResult = 1.e9;
// Issue 0020231: A min distance bug with torus and vertex.
// Make GetMinDistance() return zero if a sole VERTEX is inside any of SOLIDs
// which of shapes consists of only one vertex?
TopExp_Explorer exp1(theShape1,TopAbs_VERTEX), exp2(theShape2,TopAbs_VERTEX);
TopoDS_Shape V1 = exp1.More() ? exp1.Current() : TopoDS_Shape();
TopoDS_Shape V2 = exp2.More() ? exp2.Current() : TopoDS_Shape();
exp1.Next(); exp2.Next();
if ( exp1.More() ) V1.Nullify();
if ( exp2.More() ) V2.Nullify();
// vertex and container of solids
TopoDS_Shape V = V1.IsNull() ? V2 : V1;
TopoDS_Shape S = V1.IsNull() ? theShape1 : theShape2;
if ( !V.IsNull() ) {
// classify vertex against solids
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( V ) );
for ( exp1.Init( S, TopAbs_SOLID ); exp1.More(); exp1.Next() ) {
BRepClass3d_SolidClassifier classifier( exp1.Current(), p, 1e-6);
if ( classifier.State() == TopAbs_IN ) {
thePnt1 = p;
thePnt2 = p;
return 0.0;
}
}
}
// End Issue 0020231
// skl 30.06.2008
// additional workaround for bugs 19899, 19908 and 19910 from Mantis
double dist = GEOMUtils::GetMinDistanceSingular
(theShape1, theShape2, thePnt1, thePnt2);
if (dist > -1.0) {
return dist;
}
BRepExtrema_DistShapeShape dst (theShape1, theShape2);
if (dst.IsDone()) {
gp_Pnt P1, P2;
for (int i = 1; i <= dst.NbSolution(); i++) {
P1 = dst.PointOnShape1(i);
P2 = dst.PointOnShape2(i);
Standard_Real Dist = P1.Distance(P2);
if (aResult > Dist) {
aResult = Dist;
thePnt1 = P1;
thePnt2 = P2;
}
}
}
return aResult;
}

View File

@ -37,6 +37,8 @@
#include <functional> #include <functional>
class Bnd_Box;
inline Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2) inline Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
{ {
return S1.IsSame(S2); return S1.IsSame(S2);
@ -132,6 +134,45 @@ class GEOMUtils {
Standard_EXPORT static TopoDS_Shape GetEdgeNearPoint (const TopoDS_Shape& theShape, Standard_EXPORT static TopoDS_Shape GetEdgeNearPoint (const TopoDS_Shape& theShape,
const TopoDS_Vertex& thePoint); const TopoDS_Vertex& thePoint);
/*!
* \brief Compute precise bounding box of the shape based on the rough bounding box.
*
* \param theShape the shape.
* \param theBox rough bounding box on input; precise bounding box on output.
* \retval Standard_True in case of success; Standard_False otherwise.
*/
Standard_EXPORT static Standard_Boolean PreciseBoundingBox
(const TopoDS_Shape &theShape, Bnd_Box &theBox);
/*!
* \brief Computes minumal distance between two shapes for singular cases
* (workaround for bugs 19899, 19908 and 19910 from Mantis).
*
* \param aSh1 the first shape
* \param aSh2 the second shape
* \param Ptmp1 the output result point on the first shape
* \param Ptmp2 the output result point on the second shape
* \retval negative value if it is not a singular case; actual distance for singular case.
*/
Standard_EXPORT static Standard_Real GetMinDistanceSingular
(const TopoDS_Shape& aSh1,
const TopoDS_Shape& aSh2,
gp_Pnt& Ptmp1, gp_Pnt& Ptmp2);
/*!
* \brief Computes minumal distance between two shapes.
*
* \param theShape1 the first shape
* \param theShape2 the second shape
* \param thePnt1 the output result point on the first shape
* \param thePnt2 the output result point on the second shape
* \retval negative value in case of failure; otherwise the real distance.
*/
Standard_EXPORT static Standard_Real GetMinDistance
(const TopoDS_Shape& theShape1,
const TopoDS_Shape& theShape2,
gp_Pnt& thePnt1, gp_Pnt& thePnt2);
}; };
#endif #endif

View File

@ -258,6 +258,7 @@ void GEOM_IMeasureOperations_i::GetInertia
*/ */
//============================================================================= //=============================================================================
void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape, void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
CORBA::Boolean precise,
CORBA::Double& Xmin, CORBA::Double& Xmax, CORBA::Double& Xmin, CORBA::Double& Xmax,
CORBA::Double& Ymin, CORBA::Double& Ymax, CORBA::Double& Ymin, CORBA::Double& Ymax,
CORBA::Double& Zmin, CORBA::Double& Zmax) CORBA::Double& Zmin, CORBA::Double& Zmax)
@ -270,7 +271,8 @@ void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
if (aShape.IsNull()) return; if (aShape.IsNull()) return;
// Get shape parameters // Get shape parameters
GetOperations()->GetBoundingBox(aShape, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax); GetOperations()->GetBoundingBox
(aShape, precise, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
} }
//============================================================================= //=============================================================================
@ -279,7 +281,8 @@ void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
*/ */
//============================================================================= //=============================================================================
GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::MakeBoundingBox GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::MakeBoundingBox
(GEOM::GEOM_Object_ptr theShape) (GEOM::GEOM_Object_ptr theShape,
CORBA::Boolean precise)
{ {
GEOM::GEOM_Object_var aGEOMObject; GEOM::GEOM_Object_var aGEOMObject;
@ -291,7 +294,8 @@ GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::MakeBoundingBox
if (aShape.IsNull()) return aGEOMObject._retn(); if (aShape.IsNull()) return aGEOMObject._retn();
// Make Box - bounding box of theShape // Make Box - bounding box of theShape
Handle(GEOM_Object) anObject = GetOperations()->GetBoundingBox(aShape); Handle(GEOM_Object) anObject =
GetOperations()->GetBoundingBox(aShape, precise);
if (!GetOperations()->IsDone() || anObject.IsNull()) if (!GetOperations()->IsDone() || anObject.IsNull())
return aGEOMObject._retn(); return aGEOMObject._retn();

View File

@ -71,11 +71,13 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i :
CORBA::Double& Ix , CORBA::Double& Iy , CORBA::Double& Iz); CORBA::Double& Ix , CORBA::Double& Iy , CORBA::Double& Iz);
void GetBoundingBox (GEOM::GEOM_Object_ptr theShape, void GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
CORBA::Boolean precise,
CORBA::Double& Xmin, CORBA::Double& Xmax, CORBA::Double& Xmin, CORBA::Double& Xmax,
CORBA::Double& Ymin, CORBA::Double& Ymax, CORBA::Double& Ymin, CORBA::Double& Ymax,
CORBA::Double& Zmin, CORBA::Double& Zmax); CORBA::Double& Zmin, CORBA::Double& Zmax);
GEOM::GEOM_Object_ptr MakeBoundingBox (GEOM::GEOM_Object_ptr theShape); GEOM::GEOM_Object_ptr MakeBoundingBox (GEOM::GEOM_Object_ptr theShape,
CORBA::Boolean precise);
void GetTolerance (GEOM::GEOM_Object_ptr theShape, void GetTolerance (GEOM::GEOM_Object_ptr theShape,
CORBA::Double& FaceMin, CORBA::Double& FaceMax, CORBA::Double& FaceMin, CORBA::Double& FaceMax,

View File

@ -9031,18 +9031,20 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
## Get parameters of bounding box of the given shape ## Get parameters of bounding box of the given shape
# @param theShape Shape to obtain bounding box of. # @param theShape Shape to obtain bounding box of.
# @param precise TRUE for precise computation; FALSE for fast one.
# @return [Xmin,Xmax, Ymin,Ymax, Zmin,Zmax] # @return [Xmin,Xmax, Ymin,Ymax, Zmin,Zmax]
# Xmin,Xmax: Limits of shape along OX axis. # Xmin,Xmax: Limits of shape along OX axis.
# Ymin,Ymax: Limits of shape along OY axis. # Ymin,Ymax: Limits of shape along OY axis.
# Zmin,Zmax: Limits of shape along OZ axis. # Zmin,Zmax: Limits of shape along OZ axis.
# #
# @ref tui_measurement_tools_page "Example" # @ref tui_measurement_tools_page "Example"
def BoundingBox (self, theShape): def BoundingBox (self, theShape, precise=False):
""" """
Get parameters of bounding box of the given shape Get parameters of bounding box of the given shape
Parameters: Parameters:
theShape Shape to obtain bounding box of. theShape Shape to obtain bounding box of.
precise TRUE for precise computation; FALSE for fast one.
Returns: Returns:
[Xmin,Xmax, Ymin,Ymax, Zmin,Zmax] [Xmin,Xmax, Ymin,Ymax, Zmin,Zmax]
@ -9051,12 +9053,13 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
Zmin,Zmax: Limits of shape along OZ axis. Zmin,Zmax: Limits of shape along OZ axis.
""" """
# Example: see GEOM_TestMeasures.py # Example: see GEOM_TestMeasures.py
aTuple = self.MeasuOp.GetBoundingBox(theShape) aTuple = self.MeasuOp.GetBoundingBox(theShape, precise)
RaiseIfFailed("GetBoundingBox", self.MeasuOp) RaiseIfFailed("GetBoundingBox", self.MeasuOp)
return aTuple return aTuple
## Get bounding box of the given shape ## Get bounding box of the given shape
# @param theShape Shape to obtain bounding box of. # @param theShape Shape to obtain bounding box of.
# @param precise TRUE for precise computation; FALSE for fast one.
# @param theName Object name; when specified, this parameter is used # @param theName Object name; when specified, this parameter is used
# for result publication in the study. Otherwise, if automatic # for result publication in the study. Otherwise, if automatic
# publication is switched on, default value is used for result name. # publication is switched on, default value is used for result name.
@ -9064,12 +9067,13 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
# @return New GEOM.GEOM_Object, containing the created box. # @return New GEOM.GEOM_Object, containing the created box.
# #
# @ref tui_measurement_tools_page "Example" # @ref tui_measurement_tools_page "Example"
def MakeBoundingBox (self, theShape, theName=None): def MakeBoundingBox (self, theShape, precise=False, theName=None):
""" """
Get bounding box of the given shape Get bounding box of the given shape
Parameters: Parameters:
theShape Shape to obtain bounding box of. theShape Shape to obtain bounding box of.
precise TRUE for precise computation; FALSE for fast one.
theName Object name; when specified, this parameter is used theName Object name; when specified, this parameter is used
for result publication in the study. Otherwise, if automatic for result publication in the study. Otherwise, if automatic
publication is switched on, default value is used for result name. publication is switched on, default value is used for result name.
@ -9078,7 +9082,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
New GEOM.GEOM_Object, containing the created box. New GEOM.GEOM_Object, containing the created box.
""" """
# Example: see GEOM_TestMeasures.py # Example: see GEOM_TestMeasures.py
anObj = self.MeasuOp.MakeBoundingBox(theShape) anObj = self.MeasuOp.MakeBoundingBox(theShape, precise)
RaiseIfFailed("MakeBoundingBox", self.MeasuOp) RaiseIfFailed("MakeBoundingBox", self.MeasuOp)
self._autoPublish(anObj, theName, "bndbox") self._autoPublish(anObj, theName, "bndbox")
return anObj return anObj

View File

@ -220,7 +220,7 @@ bool MeasureGUI_BndBoxDlg::getParameters (double& theXmin, double& theXmax,
return false; return false;
GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow(getOperation()); GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow(getOperation());
anOper->GetBoundingBox(myObj, theXmin, theXmax, theYmin, theYmax, theZmin, theZmax); anOper->GetBoundingBox(myObj, true, theXmin, theXmax, theYmin, theYmax, theZmin, theZmax);
return anOper->IsDone(); return anOper->IsDone();
} }
@ -300,7 +300,7 @@ bool MeasureGUI_BndBoxDlg::isValid (QString&)
bool MeasureGUI_BndBoxDlg::execute (ObjectList& objects) bool MeasureGUI_BndBoxDlg::execute (ObjectList& objects)
{ {
GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow(getOperation()); GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow(getOperation());
GEOM::GEOM_Object_var anObj = anOper->MakeBoundingBox(myObj); GEOM::GEOM_Object_var anObj = anOper->MakeBoundingBox(myObj, true);
if (!anObj->_is_nil()) if (!anObj->_is_nil())
objects.push_back(anObj._retn()); objects.push_back(anObj._retn());

View File

@ -270,7 +270,7 @@ void TransformationGUI_MultiRotationDlg::SelectionIntoArgument()
// recompute myAng and myStep (Mantis issue 0021718) // recompute myAng and myStep (Mantis issue 0021718)
GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId()); GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId());
double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax; double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
anOper->GetBoundingBox(myBase.get(), Xmin, Xmax, Ymin, Ymax, Zmin, Zmax); anOper->GetBoundingBox(myBase.get(), true, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
if (anOper->IsDone()) { if (anOper->IsDone()) {
// angular step // angular step
double diag = sqrt((Xmax-Xmin)*(Xmax-Xmin) + (Ymax-Ymin)*(Ymax-Ymin)); double diag = sqrt((Xmax-Xmin)*(Xmax-Xmin) + (Ymax-Ymin)*(Ymax-Ymin));

View File

@ -335,7 +335,7 @@ void TransformationGUI_MultiTranslationDlg::SelectionIntoArgument()
// recompute myStepU (Mantis issue 0021718) // recompute myStepU (Mantis issue 0021718)
GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId()); GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId());
double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax; double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
anOper->GetBoundingBox(myBase.get(), Xmin, Xmax, Ymin, Ymax, Zmin, Zmax); anOper->GetBoundingBox(myBase.get(), true, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
if (anOper->IsDone()) { if (anOper->IsDone()) {
myStepU = floor(1.5 * (Xmax - Xmin)); myStepU = floor(1.5 * (Xmax - Xmin));
GroupPoints->SpinBox_DX->setValue(myStepU); GroupPoints->SpinBox_DX->setValue(myStepU);
@ -355,7 +355,7 @@ void TransformationGUI_MultiTranslationDlg::SelectionIntoArgument()
// recompute myStepU and myStepV (Mantis issue 0021718) // recompute myStepU and myStepV (Mantis issue 0021718)
GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId()); GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId());
double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax; double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
anOper->GetBoundingBox(myBase.get(), Xmin, Xmax, Ymin, Ymax, Zmin, Zmax); anOper->GetBoundingBox(myBase.get(), true, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
if (anOper->IsDone()) { if (anOper->IsDone()) {
myStepU = floor(1.5 * (Xmax - Xmin)); myStepU = floor(1.5 * (Xmax - Xmin));
myStepV = floor(1.5 * (Ymax - Ymin)); myStepV = floor(1.5 * (Ymax - Ymin));