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
a satisfactory performance.
\n <b>TUI Commands:</b> <em>[Xmin,Xmax, Ymin,Ymax, Zmin,Zmax] = geompy.BoundingBox(Shape)</em>,
<em>BBox = geompy.MakeBoundingBox(Shape)</em>, where \em Shape
is the shape for which the bounding box is computed.
\n <b>TUI Commands:</b> <em>[Xmin,Xmax, Ymin,Ymax, Zmin,Zmax] = geompy.BoundingBox(Shape, precise)</em>,
<em>BBox = geompy.MakeBoundingBox(Shape, precise)</em>, where \em Shape
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".

View File

@ -3640,12 +3640,14 @@ module GEOM
/*!
* \brief Get parameters of bounding box of the given shape
* \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 Ymin,Ymax Output. Limits of shape along OY axis.
* \param Zmin,Zmax Output. Limits of shape along OZ axis.
* \return Returns parameters of bounding box through the last six arguments.
*/
void GetBoundingBox (in GEOM_Object theShape,
in boolean precise,
out double Xmin, out double Xmax,
out double Ymin, out double Ymax,
out double Zmin, out double Zmax);
@ -3653,9 +3655,11 @@ module GEOM
/*!
* \brief Get bounding box of the given shape
* \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.
*/
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

View File

@ -91,27 +91,14 @@
#include <ShapeAnalysis.hxx>
#include <ShapeAnalysis_Surface.hxx>
#include <ShapeFix_Shape.hxx>
#include <GeomAPI_IntSS.hxx>
#include <GeomAPI_ProjectPointOnCurve.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_OffsetSurface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_Surface.hxx>
#include <Geom_SurfaceOfLinearExtrusion.hxx>
#include <Geom_SurfaceOfRevolution.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <GeomLProp_CLProps.hxx>
#include <GeomLProp_SLProps.hxx>
@ -1120,6 +1107,7 @@ void GEOMImpl_IMeasureOperations::GetInertia
//=============================================================================
void GEOMImpl_IMeasureOperations::GetBoundingBox
(Handle(GEOM_Object) theShape,
const Standard_Boolean precise,
Standard_Real& Xmin, Standard_Real& Xmax,
Standard_Real& Ymin, Standard_Real& Ymax,
Standard_Real& Zmin, Standard_Real& Zmax)
@ -1156,6 +1144,14 @@ void GEOMImpl_IMeasureOperations::GetBoundingBox
BRepTools::Clean(aShape);
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);
}
catch (Standard_Failure) {
@ -1173,7 +1169,8 @@ void GEOMImpl_IMeasureOperations::GetBoundingBox
*/
//=============================================================================
Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
(Handle(GEOM_Object) theShape)
(Handle(GEOM_Object) theShape,
const Standard_Boolean precise)
{
SetErrorCode(KO);
@ -1183,8 +1180,9 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
Handle(GEOM_Object) aBnd = GetEngine()->AddObject(GetDocID(), GEOM_BOX);
//Add a new BoundingBox function
const int aType = (precise ? BND_BOX_MEASURE_PRECISE : BND_BOX_MEASURE);
Handle(GEOM_Function) aFunction =
aBnd->AddFunction(GEOMImpl_MeasureDriver::GetID(), BND_BOX_MEASURE);
aBnd->AddFunction(GEOMImpl_MeasureDriver::GetID(), aType);
if (aFunction.IsNull()) return NULL;
//Check if the function is set correctly
@ -1214,7 +1212,15 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
}
//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);
return aBnd;
@ -1584,308 +1590,6 @@ std::vector<bool> GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Objec
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
@ -1918,63 +1622,15 @@ Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance
OCC_CATCH_SIGNALS;
#endif
// Issue 0020231: A min distance bug with torus and vertex.
// Make GetMinDistance() return zero if a sole VERTEX is inside any of SOLIDs
gp_Pnt aPnt1, aPnt2;
// which of shapes consists of only one vertex?
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
MinDist = GEOMUtils::GetMinDistance(aShape1, aShape2, aPnt1, aPnt2);
// skl 30.06.2008
// additional workaround for bugs 19899, 19908 and 19910 from Mantis
gp_Pnt Ptmp1, Ptmp2;
double dist = CheckSingularCase(aShape1, aShape2, Ptmp1, Ptmp2);
if (dist > -1.0) {
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);
if (MinDist >= 0.0) {
aPnt1.Coord(X1, Y1, Z1);
aPnt2.Coord(X2, Y2, Z2);
} else {
return MinDist;
}
}
catch (Standard_Failure) {
@ -2021,7 +1677,7 @@ Standard_Integer GEOMImpl_IMeasureOperations::ClosestPoints (Handle(GEOM_Object)
// skl 30.06.2008
// additional workaround for bugs 19899, 19908 and 19910 from Mantis
gp_Pnt P1, P2;
double dist = CheckSingularCase(aShape1, aShape2, P1, P2);
double dist = GEOMUtils::GetMinDistanceSingular(aShape1, aShape2, P1, P2);
if (dist > -1.0) {
nbSolutions = 1;

View File

@ -114,11 +114,13 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
Standard_Real& Ix , Standard_Real& Iy , Standard_Real& Iz);
Standard_EXPORT void GetBoundingBox (Handle(GEOM_Object) theShape,
const Standard_Boolean precise,
Standard_Real& Xmin, Standard_Real& Xmax,
Standard_Real& Ymin, Standard_Real& Ymax,
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_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();
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();
TopoDS_Shape aShapeBase = aRefBase->GetValue();
@ -124,6 +124,12 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
Bnd_Box 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;
B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);

View File

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

View File

@ -41,6 +41,10 @@
#include <BRepGProp.hxx>
#include <BRepTools.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <Bnd_Box.hxx>
#include <TopAbs.hxx>
@ -58,8 +62,12 @@
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_Array1OfShape.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Surface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <GeomLProp_CLProps.hxx>
#include <GeomLProp_SLProps.hxx>
@ -72,6 +80,9 @@
#include <gp_Pln.hxx>
#include <gp_Lin.hxx>
#include <ShapeAnalysis.hxx>
#include <ShapeFix_Shape.hxx>
#include <vector>
#include <Standard_Failure.hxx>
@ -600,3 +611,343 @@ TopoDS_Shape GEOMUtils::GetEdgeNearPoint (const TopoDS_Shape& theShape,
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>
class Bnd_Box;
inline Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
{
return S1.IsSame(S2);
@ -132,6 +134,45 @@ class GEOMUtils {
Standard_EXPORT static TopoDS_Shape GetEdgeNearPoint (const TopoDS_Shape& theShape,
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

View File

@ -258,6 +258,7 @@ void GEOM_IMeasureOperations_i::GetInertia
*/
//=============================================================================
void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
CORBA::Boolean precise,
CORBA::Double& Xmin, CORBA::Double& Xmax,
CORBA::Double& Ymin, CORBA::Double& Ymax,
CORBA::Double& Zmin, CORBA::Double& Zmax)
@ -270,7 +271,8 @@ void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
if (aShape.IsNull()) return;
// 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 theShape)
(GEOM::GEOM_Object_ptr theShape,
CORBA::Boolean precise)
{
GEOM::GEOM_Object_var aGEOMObject;
@ -291,7 +294,8 @@ GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::MakeBoundingBox
if (aShape.IsNull()) return aGEOMObject._retn();
// 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())
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);
void GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
CORBA::Boolean precise,
CORBA::Double& Xmin, CORBA::Double& Xmax,
CORBA::Double& Ymin, CORBA::Double& Ymax,
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,
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
# @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]
# Xmin,Xmax: Limits of shape along OX axis.
# Ymin,Ymax: Limits of shape along OY axis.
# Zmin,Zmax: Limits of shape along OZ axis.
#
# @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
Parameters:
theShape Shape to obtain bounding box of.
precise TRUE for precise computation; FALSE for fast one.
Returns:
[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.
"""
# Example: see GEOM_TestMeasures.py
aTuple = self.MeasuOp.GetBoundingBox(theShape)
aTuple = self.MeasuOp.GetBoundingBox(theShape, precise)
RaiseIfFailed("GetBoundingBox", self.MeasuOp)
return aTuple
## Get bounding box of the given shape
# @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
# for result publication in the study. Otherwise, if automatic
# 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.
#
# @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
Parameters:
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
for result publication in the study. Otherwise, if automatic
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.
"""
# Example: see GEOM_TestMeasures.py
anObj = self.MeasuOp.MakeBoundingBox(theShape)
anObj = self.MeasuOp.MakeBoundingBox(theShape, precise)
RaiseIfFailed("MakeBoundingBox", self.MeasuOp)
self._autoPublish(anObj, theName, "bndbox")
return anObj

View File

@ -220,7 +220,7 @@ bool MeasureGUI_BndBoxDlg::getParameters (double& theXmin, double& theXmax,
return false;
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();
}
@ -300,7 +300,7 @@ bool MeasureGUI_BndBoxDlg::isValid (QString&)
bool MeasureGUI_BndBoxDlg::execute (ObjectList& objects)
{
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())
objects.push_back(anObj._retn());

View File

@ -270,7 +270,7 @@ void TransformationGUI_MultiRotationDlg::SelectionIntoArgument()
// recompute myAng and myStep (Mantis issue 0021718)
GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId());
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()) {
// angular step
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)
GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId());
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()) {
myStepU = floor(1.5 * (Xmax - Xmin));
GroupPoints->SpinBox_DX->setValue(myStepU);
@ -355,7 +355,7 @@ void TransformationGUI_MultiTranslationDlg::SelectionIntoArgument()
// recompute myStepU and myStepV (Mantis issue 0021718)
GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId());
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()) {
myStepU = floor(1.5 * (Xmax - Xmin));
myStepV = floor(1.5 * (Ymax - Ymin));