Mantis issue 0021716: EDF 1679 : Create the bounding box in the GUI

This commit is contained in:
jfa 2012-12-21 08:29:02 +00:00
parent e8d16d1174
commit e39ee4040b
14 changed files with 332 additions and 42 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -2,8 +2,10 @@
\page bounding_box_page Bounding Box
Returns the dimensions of the bounding box for the selected
geometrical object.
Shows the dimensions of the bounding box for the selected
geometrical object. Creates corresponding shape (box) on "Apply".
\image html measures5.png
\note To take into account any possible shape distortion
that affects the resulting bounding box, the algorithm enlarges
@ -12,14 +14,10 @@ faces (by iterating through all faces of a shape).
This functionallity is implemented in such a way to have
a satisfactory performance.
<b>Result:</b> Displays the bounding box dimensions of a
geometrical object in form of a Python Tuple (Xmin, Xmax, Ymin,
Ymax, Zmin, Zmax).
\n <b>TUI Command:</b> <em>geompy.BoundingBox(Shape),</em> where \em Shape
\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 a bounding box is computed.
See also a \ref tui_bounding_box_page "TUI example".
\image html measures5.png
*/

View File

@ -7,11 +7,17 @@ import geompy
# create a box
box = geompy.MakeBoxDXDYDZ(100,30,100)
bb = geompy.BoundingBox(box)
print "\nBounding Box of box 100x30x100:"
print " Xmin = ", bb[0], ", Xmax = ", bb[1]
print " Ymin = ", bb[2], ", Ymax = ", bb[3]
print " Zmin = ", bb[4], ", Zmax = ", bb[5]
aBB = geompy.MakeBoundingBox(box)
geompy.addToStudy(box, "box 100x30x100")
geompy.addToStudy(aBB, "Bounding box of box 100x30x100")
\endcode
*/

View File

@ -3558,6 +3558,13 @@ module GEOM
out double Ymin, out double Ymax,
out double Zmin, out double Zmax);
/*!
* \brief Get bounding box of the given shape
* \param theShape Shape to obtain bounding box of.
* \return New GEOM_Object, containing the created bounding box.
*/
GEOM_Object MakeBoundingBox (in GEOM_Object theShape);
/*!
* \brief Get min and max tolerances of sub-shapes of theShape
* \param theShape Shape, to get tolerances of.

View File

@ -1166,6 +1166,59 @@ void GEOMImpl_IMeasureOperations::GetBoundingBox
SetErrorCode(OK);
}
//=============================================================================
/*!
* GetBoundingBox
*/
//=============================================================================
Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
(Handle(GEOM_Object) theShape)
{
SetErrorCode(KO);
if (theShape.IsNull()) return NULL;
//Add a new BoundingBox object
Handle(GEOM_Object) aBnd = GetEngine()->AddObject(GetDocID(), GEOM_BOX);
//Add a new BoundingBox function
Handle(GEOM_Function) aFunction =
aBnd->AddFunction(GEOMImpl_MeasureDriver::GetID(), BND_BOX_MEASURE);
if (aFunction.IsNull()) return NULL;
//Check if the function is set correctly
if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
GEOMImpl_IMeasure aCI (aFunction);
Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
if (aRefShape.IsNull()) return NULL;
aCI.SetBase(aRefShape);
//Compute the BoundingBox value
try {
#if OCC_VERSION_LARGE > 0x06010000
OCC_CATCH_SIGNALS;
#endif
if (!GetSolver()->ComputeFunction(aFunction)) {
SetErrorCode("Measure driver failed to compute a bounding box");
return NULL;
}
}
catch (Standard_Failure) {
Handle(Standard_Failure) aFail = Standard_Failure::Caught();
SetErrorCode(aFail->GetMessageString());
return NULL;
}
//Make a Python command
GEOM::TPythonDump(aFunction) << aBnd << " = geompy.MakeBoundingBox(" << theShape << ")";
SetErrorCode(OK);
return aBnd;
}
//=============================================================================
/*!
* GetTolerance

View File

@ -117,6 +117,8 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
Standard_Real& Ymin, Standard_Real& Ymax,
Standard_Real& Zmin, Standard_Real& Zmax);
Standard_EXPORT Handle(GEOM_Object) GetBoundingBox (Handle(GEOM_Object) theShape);
Standard_EXPORT void GetTolerance (Handle(GEOM_Object) theShape,
Standard_Real& FaceMin, Standard_Real& FaceMax,
Standard_Real& EdgeMin, Standard_Real& EdgeMax,

View File

@ -30,9 +30,12 @@
#include <GEOMUtils.hxx>
#include <BRep_Tool.hxx>
#include <BRepTools.hxx>
#include <BRepGProp.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <TopAbs.hxx>
#include <TopoDS.hxx>
@ -55,6 +58,7 @@
#include <gp_Pnt.hxx>
#include <Precision.hxx>
#include <Standard_NullObject.hxx>
#include <StdFail_NotDone.hxx>
//=======================================================================
//function : GetID
@ -93,14 +97,47 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
{
Handle(GEOM_Function) aRefBase = aCI.GetBase();
TopoDS_Shape aShapeBase = aRefBase->GetValue();
if (aShapeBase.IsNull()) {
if (aShapeBase.IsNull())
Standard_NullObject::Raise("Shape for centre of mass calculation is null");
}
gp_Ax3 aPos = GEOMUtils::GetPosition(aShapeBase);
gp_Pnt aCenterMass = aPos.Location();
aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
}
else if (aType == BND_BOX_MEASURE)
{
Handle(GEOM_Function) aRefBase = aCI.GetBase();
TopoDS_Shape aShapeBase = aRefBase->GetValue();
if (aShapeBase.IsNull())
Standard_NullObject::Raise("Shape for bounding box calculation is null");
BRepBuilderAPI_Copy aCopyTool (aShapeBase);
if (!aCopyTool.IsDone())
Standard_NullObject::Raise("Shape for bounding box calculation is bad");
aShapeBase = aCopyTool.Shape();
// remove triangulation to obtain more exact boundaries
BRepTools::Clean(aShapeBase);
Bnd_Box B;
BRepBndLib::Add(aShapeBase, B);
Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
if (Xmax - Xmin < Precision::Confusion()) Xmax += Precision::Confusion();
if (Ymax - Ymin < Precision::Confusion()) Ymax += Precision::Confusion();
if (Zmax - Zmin < Precision::Confusion()) Zmax += Precision::Confusion();
gp_Pnt P1 (Xmin, Ymin, Zmin);
gp_Pnt P2 (Xmax, Ymax, Zmax);
BRepPrimAPI_MakeBox MB (P1, P2);
MB.Build();
if (!MB.IsDone()) StdFail_NotDone::Raise("Bounding box cannot be computed from the given shape");
aShape = MB.Shape();
}
else if (aType == VERTEX_BY_INDEX)
{
Handle(GEOM_Function) aRefBase = aCI.GetBase();

View File

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

View File

@ -18,7 +18,6 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
#include <Standard_Stream.hxx>
@ -273,6 +272,31 @@ void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
GetOperations()->GetBoundingBox(aShape, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
}
//=============================================================================
/*!
* MakeBoundingBox
*/
//=============================================================================
GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::MakeBoundingBox
(GEOM::GEOM_Object_ptr theShape)
{
GEOM::GEOM_Object_var aGEOMObject;
//Set a not done flag
GetOperations()->SetNotDone();
//Get the reference shape
Handle(GEOM_Object) aShape = GetObjectImpl(theShape);
if (aShape.IsNull()) return aGEOMObject._retn();
// Make Box - bounding box of theShape
Handle(GEOM_Object) anObject = GetOperations()->GetBoundingBox(aShape);
if (!GetOperations()->IsDone() || anObject.IsNull())
return aGEOMObject._retn();
return GetObject(anObject);
}
//=============================================================================
/*!
* GetTolerance

View File

@ -18,7 +18,6 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
#ifndef _GEOM_IMeasureOperations_i_HeaderFile
#define _GEOM_IMeasureOperations_i_HeaderFile
@ -75,6 +74,8 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i :
CORBA::Double& Ymin, CORBA::Double& Ymax,
CORBA::Double& Zmin, CORBA::Double& Zmax);
GEOM::GEOM_Object_ptr MakeBoundingBox (GEOM::GEOM_Object_ptr theShape);
void GetTolerance (GEOM::GEOM_Object_ptr theShape,
CORBA::Double& FaceMin, CORBA::Double& FaceMax,
CORBA::Double& EdgeMin, CORBA::Double& EdgeMax,

View File

@ -19,7 +19,6 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
def TestMeasureOperations (geompy, math):
@ -98,6 +97,8 @@ def TestMeasureOperations (geompy, math):
print " Xmin = ", BB[0], ", Xmax = ", BB[1]
print " Ymin = ", BB[2], ", Ymax = ", BB[3]
print " Zmin = ", BB[4], ", Zmax = ", BB[5]
BB = geompy.MakeBoundingBox(box)
geompy.addToStudy(BB, "BoundingBox")
####### Inertia #######

View File

@ -6662,6 +6662,26 @@ class geompyDC(GEOM._objref_GEOM_Gen):
RaiseIfFailed("GetBoundingBox", self.MeasuOp)
return aTuple
## Get bounding box of the given shape
# @param theShape Shape to obtain bounding box of.
# @return New GEOM.GEOM_Object, containing the created box.
#
# @ref tui_measurement_tools_page "Example"
def MakeBoundingBox (self, theShape):
"""
Get bounding box of the given shape
Parameters:
theShape Shape to obtain bounding box of.
Returns:
New GEOM.GEOM_Object, containing the created box.
"""
# Example: see GEOM_TestMeasures.py
anObj = self.MeasuOp.MakeBoundingBox(theShape)
RaiseIfFailed("MakeBoundingBox", self.MeasuOp)
return anObj
## Get inertia matrix and moments of inertia of theShape.
# @param theShape Shape to calculate inertia of.
# @return [I11,I12,I13, I21,I22,I23, I31,I32,I33, Ix,Iy,Iz]

View File

@ -35,6 +35,10 @@
#include <SUIT_Session.h>
#include <SUIT_ResourceMgr.h>
#include <SUIT_OverrideCursor.h>
#include <SalomeApp_Application.h>
#include <SalomeApp_Tools.h>
#include <LightApp_SelectionMgr.h>
//=================================================================================
// class : MeasureGUI_BndBoxDlg()
@ -44,12 +48,10 @@
// true to construct a modal dialog.
//=================================================================================
MeasureGUI_BndBoxDlg::MeasureGUI_BndBoxDlg (GeometryGUI* GUI, QWidget* parent)
: MeasureGUI_Skeleton(GUI, parent)
: GEOMBase_Skeleton(GUI, parent)
{
QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap(
"GEOM", tr( "ICON_DLG_BOUNDING_BOX" ) ) );
QPixmap image1( SUIT_Session::session()->resourceMgr()->loadPixmap(
"GEOM", tr( "ICON_SELECT" ) ) );
QPixmap image0 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_BOUNDING_BOX")));
QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
setWindowTitle(tr("GEOM_BNDBOX_TITLE"));
@ -57,6 +59,10 @@ MeasureGUI_BndBoxDlg::MeasureGUI_BndBoxDlg (GeometryGUI* GUI, QWidget* parent)
mainFrame()->GroupConstructors->setTitle(tr("GEOM_BNDBOX"));
mainFrame()->RadioButton1->setIcon(image0);
mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose );
mainFrame()->RadioButton2->close();
mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
mainFrame()->RadioButton3->close();
myGrp = new MeasureGUI_1Sel6LineEdit (centralWidget());
myGrp->GroupBox1->setTitle( tr( "GEOM_BNDBOX_OBJDIM" ) );
@ -87,7 +93,7 @@ MeasureGUI_BndBoxDlg::MeasureGUI_BndBoxDlg (GeometryGUI* GUI, QWidget* parent)
/***************************************************************/
myHelpFileName = "using_measurement_tools_page.html#bounding_box_anchor";
myHelpFileName = "bounding_box_page.html";
/* Initialisation */
Init();
@ -107,9 +113,41 @@ MeasureGUI_BndBoxDlg::~MeasureGUI_BndBoxDlg()
//=================================================================================
void MeasureGUI_BndBoxDlg::Init()
{
mySelBtn = myGrp->PushButton1;
mySelEdit = myGrp->LineEdit1;
MeasureGUI_Skeleton::Init();
myEditCurrentArgument = myGrp->LineEdit1;
connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
connect(myGrp->PushButton1, SIGNAL(clicked()), this, SLOT(SelectionIntoArgument()));
connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
this, SLOT(SelectionIntoArgument()));
initName(tr("GEOM_BNDBOX"));
globalSelection();
SelectionIntoArgument();
}
//=================================================================================
// function : ClickOnOk()
// purpose :
//=================================================================================
void MeasureGUI_BndBoxDlg::ClickOnOk()
{
if (ClickOnApply())
ClickOnCancel();
}
//=================================================================================
// function : ClickOnApply()
// purpose :
//=================================================================================
bool MeasureGUI_BndBoxDlg::ClickOnApply()
{
if (!onAccept())
return false;
initName();
return true;
}
//=================================================================================
@ -121,7 +159,7 @@ void MeasureGUI_BndBoxDlg::processObject()
double aXMin, aXMax, aYMin, aYMax, aZMin, aZMax;
if (!getParameters(aXMin, aXMax, aYMin, aYMax, aZMin, aZMax)) {
mySelEdit->setText("");
myEditCurrentArgument->setText("");
myGrp->LineEdit11->setText("");
myGrp->LineEdit12->setText("");
myGrp->LineEdit21->setText("");
@ -177,3 +215,97 @@ SALOME_Prs* MeasureGUI_BndBoxDlg::buildPrs()
return !aShape.IsNull() ? getDisplayer()->BuildPrs(aShape) : 0;
}
//=================================================================================
// function : SelectionIntoArgument()
// purpose : Called when selection as changed or other case
//=================================================================================
void MeasureGUI_BndBoxDlg::SelectionIntoArgument()
{
myEditCurrentArgument->setText("");
myObj = GEOM::GEOM_Object::_nil();
LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
SALOME_ListIO aSelList;
aSelMgr->selectedObjects(aSelList);
if (aSelList.Extent() != 1) {
processObject();
erasePreview();
return;
}
GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject(aSelList.First());
if (aSelectedObject->_is_nil()) {
processObject();
erasePreview();
return;
}
myObj = aSelectedObject;
myEditCurrentArgument->setText(GEOMBase::GetName(myObj));
processObject();
redisplayPreview();
}
//=================================================================================
// function : createOperation
// purpose :
//=================================================================================
GEOM::GEOM_IOperations_ptr MeasureGUI_BndBoxDlg::createOperation()
{
return getGeomEngine()->GetIMeasureOperations(getStudyId());
}
//=================================================================================
// function : isValid
// purpose :
//=================================================================================
bool MeasureGUI_BndBoxDlg::isValid (QString&)
{
return !myObj->_is_nil();
}
//=================================================================================
// function : execute
// purpose :
//=================================================================================
bool MeasureGUI_BndBoxDlg::execute (ObjectList& objects)
{
GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow(getOperation());
GEOM::GEOM_Object_var anObj = anOper->MakeBoundingBox(myObj);
if (!anObj->_is_nil())
objects.push_back(anObj._retn());
return true;
}
//=================================================================================
// function : redisplayPreview()
// purpose :
//=================================================================================
void MeasureGUI_BndBoxDlg::redisplayPreview()
{
QString aMess;
if (!isValid(aMess)) {
erasePreview(true);
return;
}
erasePreview(false);
try {
SUIT_OverrideCursor();
getDisplayer()->SetColor(Quantity_NOC_VIOLET);
getDisplayer()->SetToActivate(false);
if (SALOME_Prs* aPrs = buildPrs())
displayPreview(aPrs);
}
catch (const SALOME::SALOME_Exception& e) {
SalomeApp_Tools::QtCatchCorbaException(e);
}
}

View File

@ -18,16 +18,15 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// GEOM GEOMGUI : GUI for Geometry component
// File : MeasureGUI_BndBoxDlg.h
// Author : Nicolas REJNERI, Open CASCADE S.A.S.
//
#ifndef MEASUREGUI_BNDBOXDLG_H
#define MEASUREGUI_BNDBOXDLG_H
#include "MeasureGUI_Skeleton.h"
#include "GEOMBase_Skeleton.h"
class MeasureGUI_1Sel6LineEdit;
@ -35,7 +34,7 @@ class MeasureGUI_1Sel6LineEdit;
// class : DialogBox_PROPERTIES
// purpose :
//=================================================================================
class MeasureGUI_BndBoxDlg : public MeasureGUI_Skeleton
class MeasureGUI_BndBoxDlg : public GEOMBase_Skeleton
{
Q_OBJECT
@ -44,18 +43,27 @@ public:
~MeasureGUI_BndBoxDlg();
protected:
// redefined from GEOMBase_Helper and MeasureGUI_Skeleton
// redefined from GEOMBase_Helper
virtual GEOM::GEOM_IOperations_ptr createOperation();
virtual bool isValid (QString&);
virtual bool execute (ObjectList&);
void redisplayPreview();
virtual void processObject();
virtual SALOME_Prs* buildPrs();
private:
void Init();
bool getParameters( double&, double&,
double&, double&,
double&, double& );
bool getParameters (double&, double&, double&, double&, double&, double&);
private:
GEOM::GEOM_Object_var myObj;
MeasureGUI_1Sel6LineEdit* myGrp;
private slots:
void ClickOnOk();
bool ClickOnApply();
void SelectionIntoArgument();
};
#endif // MEASUREGUI_BNDBOXDLG_H