FeaturesAPI_Defeaturing.h
FeaturesAPI_PointCoordinates.h
FeaturesAPI_GeometryCalculation.h
+ FeaturesAPI_BoundingBox.h
)
SET(PROJECT_SOURCES
FeaturesAPI_Defeaturing.cpp
FeaturesAPI_PointCoordinates.cpp
FeaturesAPI_GeometryCalculation.cpp
+ FeaturesAPI_BoundingBox.cpp
)
SET(PROJECT_LIBRARIES
%shared_ptr(FeaturesAPI_Copy)
%shared_ptr(FeaturesAPI_ImportResult)
%shared_ptr(FeaturesAPI_Defeaturing)
+%shared_ptr(FeaturesAPI_BoundingBox)
%typecheck(SWIG_TYPECHECK_POINTER) std::pair<std::list<ModelHighAPI_Selection>, bool>, const std::pair<std::list<ModelHighAPI_Selection>, bool> & {
%include "FeaturesAPI_ImportResult.h"
%include "FeaturesAPI_PointCoordinates.h"
%include "FeaturesAPI_GeometryCalculation.h"
+%include "FeaturesAPI_BoundingBox.h"
--- /dev/null
+// Copyright (C) 2018-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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 "FeaturesAPI_BoundingBox.h"
+
+#include <FeaturesPlugin_CreateBoundingBox.h>
+#include <ModelAPI_AttributeDoubleArray.h>
+#include <ModelHighAPI_Services.h>
+#include <ModelHighAPI_Tools.h>
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Selection.h>
+#include <ModelHighAPI_Tools.h>
+
+//=================================================================================================
+FeaturesAPI_BoundingBox::FeaturesAPI_BoundingBox(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature)
+ : ModelHighAPI_Interface(theFeature)
+{
+ initialize();
+}
+
+//=================================================================================================
+FeaturesAPI_BoundingBox::FeaturesAPI_BoundingBox(
+ const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const ModelHighAPI_Selection& theObject)
+:ModelHighAPI_Interface(theFeature)
+{
+ if (initialize()) {
+ fillAttribute(theObject, myobjectSelected);
+ execute();
+ }
+}
+
+//=================================================================================================
+FeaturesAPI_BoundingBox::~FeaturesAPI_BoundingBox()
+{
+}
+
+//=================================================================================================
+void FeaturesAPI_BoundingBox::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ FeaturePtr aBase = feature();
+ const std::string& aDocName = theDumper.name(aBase->document());
+
+ AttributeSelectionPtr anAttrObject;
+ anAttrObject = aBase->selection(FeaturesPlugin_CreateBoundingBox::OBJECT_ID());
+
+ theDumper << aBase << " = model.getBoundingBox(" << aDocName << ", " << anAttrObject;
+
+ theDumper << ")" << std::endl;
+}
+
+//=================================================================================================
+BoundingBoxPtr getBoundingBox(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const ModelHighAPI_Selection& theObject)
+{
+
+ FeaturePtr aFeature =
+ thePart->addFeature(FeaturesPlugin_CreateBoundingBox::ID());
+
+ BoundingBoxPtr aBoundingBox;
+
+ aBoundingBox.reset(new FeaturesAPI_BoundingBox(aFeature, theObject));
+
+ return aBoundingBox;
+}
+
--- /dev/null
+// Copyright (C) 2018-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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 FeaturesAPI_BoundingBox_H_
+#define FeaturesAPI_BoundingBox_H_
+
+#include "FeaturesAPI.h"
+
+#include "FeaturesPlugin_CreateBoundingBox.h"
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+#include <memory>
+
+class ModelAPI_Document;
+class ModelHighAPI_Selection;
+
+/// \class FeaturesAPI_NormalToFace
+/// \ingroup CPPHighAPI
+/// \brief Interface for NormalToface feature.
+class FeaturesAPI_BoundingBox: public ModelHighAPI_Interface
+{
+public:
+ /// Constructor without values.
+ FEATURESAPI_EXPORT
+ explicit FeaturesAPI_BoundingBox(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+ FEATURESAPI_EXPORT
+ explicit FeaturesAPI_BoundingBox(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const ModelHighAPI_Selection& theObject);
+
+ /// Destructor.
+ FEATURESAPI_EXPORT
+ virtual ~FeaturesAPI_BoundingBox();
+
+ INTERFACE_1(FeaturesPlugin_CreateBoundingBox::ID(),
+ objectSelected, FeaturesPlugin_CreateBoundingBox::OBJECT_ID(),
+ ModelAPI_AttributeSelection, /** object selected*/)
+
+ /// Dump wrapped feature
+ FEATURESAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
+};
+
+/// Pointer on the NormalToface object.
+typedef std::shared_ptr<FeaturesAPI_BoundingBox> BoundingBoxPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief get the bounding Box
+/// \param thePart the part
+/// \param theobject the object selected
+FEATURESAPI_EXPORT
+BoundingBoxPtr getBoundingBox(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const ModelHighAPI_Selection& theObject);
+
+#endif // FeaturesAPI_BoundingBox_H_
#include "FeaturesAPI_ImportResult.h"
#include "FeaturesAPI_PointCoordinates.h"
#include "FeaturesAPI_GeometryCalculation.h"
+ #include "FeaturesAPI_BoundingBox.h"
#endif // FeaturesAPI_swig_H_
FeaturesPlugin_VersionedChFi.h
FeaturesPlugin_PointCoordinates.h
FeaturesPlugin_GeometryCalculation.h
+ FeaturesPlugin_BoundingBox.h
+ FeaturesPlugin_CommonBoundingBox.h
+ FeaturesPlugin_CreateBoundingBox.h
)
SET(PROJECT_SOURCES
FeaturesPlugin_VersionedChFi.cpp
FeaturesPlugin_PointCoordinates.cpp
FeaturesPlugin_GeometryCalculation.cpp
+ FeaturesPlugin_BoundingBox.cpp
+ FeaturesPlugin_CommonBoundingBox.cpp
+ FeaturesPlugin_CreateBoundingBox.cpp
)
SET(XML_RESOURCES
defeaturing_widget.xml
point_coordinates_widget.xml
geometry_calculation_widget.xml
+ bounding_box_widget.xml
+ create_bounding_box_widget.xml
)
SET(TEXT_RESOURCES
Test20247.py
TestPointCoordinates.py
TestGeometryCalculation.py
+ TestBoundingBox.py
)
--- /dev/null
+// Copyright (C) 2018-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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 "FeaturesPlugin_BoundingBox.h"
+
+#include <Config_PropManager.h>
+
+#include <FeaturesPlugin_CreateBoundingBox.h>
+
+#include <GeomAlgoAPI_BoundingBox.h>
+
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeDoubleArray.h>
+#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+#include <iomanip>
+#include <sstream>
+
+//=================================================================================================
+FeaturesPlugin_BoundingBox::FeaturesPlugin_BoundingBox()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_BoundingBox::initAttributes()
+{
+ // attribute for object selected
+ data()->addAttribute(OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+
+ // attributes for result message and values
+ data()->addAttribute(X_MIN_COORD_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(Y_MIN_COORD_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(Z_MIN_COORD_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(X_MAX_COORD_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(Y_MAX_COORD_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(Z_MAX_COORD_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(CREATEBOX_ID(), ModelAPI_AttributeBoolean::typeId());
+
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), X_MIN_COORD_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), Y_MIN_COORD_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), Z_MIN_COORD_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), X_MAX_COORD_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), Y_MAX_COORD_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), Z_MAX_COORD_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATEBOX_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), RESULT_VALUES_ID());
+
+ data()->addAttribute(RESULT_VALUES_ID(), ModelAPI_AttributeDoubleArray::typeId());
+
+ data()->realArray(RESULT_VALUES_ID())->setSize(6);
+
+}
+
+//=================================================================================================
+void FeaturesPlugin_BoundingBox::execute()
+{
+ updateValues();
+ createBoxByTwoPoints();
+
+ if (boolean(CREATEBOX_ID())->value()) {
+ if (!myCreateFeature.get())
+ createBox();
+ updateBox();
+ } else {
+ if (myCreateFeature.get()) {
+ myCreateFeature->eraseResults();
+ SessionPtr aSession = ModelAPI_Session::get();
+ DocumentPtr aDoc = aSession->activeDocument();
+ aDoc->removeFeature(myCreateFeature);
+ myCreateFeature.reset();
+ }
+ }
+}
+
+//=================================================================================================
+void FeaturesPlugin_BoundingBox::attributeChanged(const std::string& theID)
+{
+ if (theID == OBJECT_ID()) {
+ if (myCreateFeature.get())
+ updateBox();
+ }
+}
+
+//=================================================================================================
+AttributePtr FeaturesPlugin_BoundingBox::attributResultValues()
+{
+ return attribute(RESULT_VALUES_ID());
+}
+
+//=================================================================================================
+void FeaturesPlugin_BoundingBox::updateValues()
+{
+ AttributeSelectionPtr aSelection = selection(OBJECT_ID());
+ if (aSelection->isInitialized()) {
+ AttributeDoubleArrayPtr aValues =
+ std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
+ std::stringstream streamxmin;
+ std::stringstream streamymin;
+ std::stringstream streamzmin;
+ std::stringstream streamxmax;
+ std::stringstream streamymax;
+ std::stringstream streamzmax;
+
+ GeomShapePtr aShape;
+ if (aSelection && aSelection->isInitialized()) {
+ aShape = aSelection->value();
+ if (!aShape && aSelection->context())
+ aShape = aSelection->context()->shape();
+ }
+
+ if (aShape && !aShape->isEqual(myShape)) {
+ double aXmin, aXmax, aYmin,aYmax,aZmin,aZmax;
+ std::string aError;
+ if (!GetBoundingBox(aShape,
+ true,
+ aXmin, aXmax,
+ aYmin,aYmax,
+ aZmin,aZmax,
+ aError))
+ setError("Error in bounding box calculation :" + aError);
+
+ myShape = aShape;
+ streamxmin << std::setprecision(14) << aXmin;
+ aValues->setValue(0, aXmin);
+ streamxmax << std::setprecision(14) << aXmax;
+ aValues->setValue(1, aXmax);
+ streamymin << std::setprecision(14) << aYmin;
+ aValues->setValue(2, aYmin);
+ streamymax << std::setprecision(14) << aYmax;
+ aValues->setValue(3, aYmax);
+ streamzmin << std::setprecision(14) << aZmin;
+ aValues->setValue(4, aZmin);
+ streamzmax << std::setprecision(14) << aZmax;
+ aValues->setValue(5, aZmax);
+ string(X_MIN_COORD_ID() )->setValue( "X = " + streamxmin.str() );
+ string(Y_MIN_COORD_ID() )->setValue( "Y = " + streamymin.str() );
+ string(Z_MIN_COORD_ID() )->setValue( "Z = " + streamzmin.str() );
+ string(X_MAX_COORD_ID() )->setValue( "X = " + streamxmax.str() );
+ string(Y_MAX_COORD_ID() )->setValue( "Y = " + streamymax.str() );
+ string(Z_MAX_COORD_ID() )->setValue( "Z = " + streamzmax.str() );
+ }
+ }
+}
+
+//=================================================================================================
+void FeaturesPlugin_BoundingBox::createBox()
+{
+ SessionPtr aSession = ModelAPI_Session::get();
+
+ DocumentPtr aDoc = aSession->activeDocument();
+
+ if (aDoc.get()) {
+ myCreateFeature = aDoc->addFeature(FeaturesPlugin_CreateBoundingBox::ID());
+ }
+}
+
+//=================================================================================================
+void FeaturesPlugin_BoundingBox::updateBox()
+{
+ myCreateFeature->boolean(FeaturesPlugin_CreateBoundingBox::COMPUTE_ID())->setValue(false);
+ myCreateFeature->selection(FeaturesPlugin_CreateBoundingBox::OBJECT_ID())
+ ->setValue(selection(OBJECT_ID())->context(),
+ selection(OBJECT_ID())->value());
+
+ AttributeDoubleArrayPtr aValuesFeatures =
+ std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>
+ (myCreateFeature->attribute(RESULT_VALUES_ID()));
+ AttributeDoubleArrayPtr aValues =
+ std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
+ for (int anI=0; anI < 6; anI++)
+ aValuesFeatures->setValue(anI,aValues->value(anI));
+
+ myCreateFeature->execute();
+ myCreateFeature->boolean(FeaturesPlugin_CreateBoundingBox::COMPUTE_ID())->setValue(true);
+}
--- /dev/null
+// Copyright (C) 2018-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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 FeaturesPlugin_BoundingBox_H_
+#define FeaturesPlugin_BoundingBox_H_
+
+#include <FeaturesPlugin_CommonBoundingBox.h>
+
+/// \class FeaturesPlugin_BoundingBox
+/// \ingroup Plugins
+/// \brief Feature to view the Bounding Box.
+
+class FeaturesPlugin_BoundingBox : public FeaturesPlugin_CommonBoundingBox
+{
+public:
+ /// Bounding box macro kind.
+ inline static const std::string& ID()
+ {
+ static const std::string MY_ID("BoundingBoxMacro");
+ return MY_ID;
+ }
+
+ /// Attribute name for object selected.
+ inline static const std::string& OBJECT_ID()
+ {
+ static const std::string MY_OBJECT_ID("main_object");
+ return MY_OBJECT_ID;
+ }
+
+ /// Attribute name for x coodinate.
+ inline static const std::string& X_MIN_COORD_ID()
+ {
+ static const std::string MY_X_MIN_COORD_ID("xmincoordinate");
+ return MY_X_MIN_COORD_ID;
+ }
+
+ /// Attribute name for y coodinate.
+ inline static const std::string& Y_MIN_COORD_ID()
+ {
+ static const std::string MY_Y_MIN_COORD_ID("ymincoordinate");
+ return MY_Y_MIN_COORD_ID;
+ }
+
+ /// Attribute name for z coodinate.
+ inline static const std::string& Z_MIN_COORD_ID()
+ {
+ static const std::string MY_Z_MIN_COORD_ID("zmincoordinate");
+ return MY_Z_MIN_COORD_ID;
+ }
+
+ /// Attribute name for x max coodinate.
+ inline static const std::string& X_MAX_COORD_ID()
+ {
+ static const std::string MY_X_MAX_COORD_ID("xmaxcoordinate");
+ return MY_X_MAX_COORD_ID;
+ }
+
+ /// Attribute name for y max coodinate.
+ inline static const std::string& Y_MAX_COORD_ID()
+ {
+ static const std::string MY_Y_MAX_COORD_ID("ymaxcoordinate");
+ return MY_Y_MAX_COORD_ID;
+ }
+
+ /// Attribute name for z max coodinate.
+ inline static const std::string& Z_MAX_COORD_ID()
+ {
+ static const std::string MY_Z_MAX_COORD_ID("zmaxcoordinate");
+ return MY_Z_MAX_COORD_ID;
+ }
+
+ /// Attribute name for checkbox create box.
+ inline static const std::string& CREATEBOX_ID()
+ {
+ static const std::string MY_CREATEBOX_ID("createbox");
+ return MY_CREATEBOX_ID;
+ }
+
+ /// Attribute name for values of result.
+ inline static const std::string& RESULT_VALUES_ID()
+ {
+ static const std::string MY_RESULT_VALUES_ID("result_values");
+ return MY_RESULT_VALUES_ID;
+ }
+
+ /// \return the kind of a feature.
+ virtual const std::string& getKind()
+ {
+ return ID();
+ }
+
+ /// Performs the algorithm and stores results it in the data structure.
+ FEATURESPLUGIN_EXPORT virtual void execute();
+
+ /// Request for initialization of data model of the feature: adding all attributes
+ FEATURESPLUGIN_EXPORT virtual void initAttributes();
+
+ /// Called on change of any argument-attribute of this object
+ /// \param theID identifier of changed attribute
+ FEATURESPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
+ /// Reimplemented from ModelAPI_Feature::isMacro(). Returns true.
+ FEATURESPLUGIN_EXPORT virtual bool isMacro() const { return true; }
+
+ /// Use plugin manager for features creation
+ FeaturesPlugin_BoundingBox();
+
+private:
+ /// Return Attribut values of result.
+ virtual AttributePtr attributResultValues();
+
+ /// Update values displayed.
+ void updateValues();
+ /// Create Box
+ void createBox();
+ /// Update Box
+ void updateBox();
+
+ /// Feature to create box
+ FeaturePtr myCreateFeature;
+
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2018-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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 "FeaturesPlugin_CommonBoundingBox.h"
+
+#include <ModelAPI_AttributeDoubleArray.h>
+
+#include <ModelAPI_Data.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+#include <GeomAPI_Vertex.h>
+
+#include <GeomAlgoAPI_BoundingBox.h>
+#include <GeomAlgoAPI_PointBuilder.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <Config_PropManager.h>
+
+#include <iomanip>
+#include <sstream>
+
+
+
+//=================================================================================================
+void FeaturesPlugin_CommonBoundingBox::createBoxByTwoPoints()
+{
+ AttributeDoubleArrayPtr aValues =
+ std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attributResultValues());
+
+ SessionPtr aSession = ModelAPI_Session::get();
+
+ DocumentPtr aDoc = aSession->activeDocument();
+
+ GeomVertexPtr vertexFirst =
+ GeomAlgoAPI_PointBuilder::vertex(aValues->value(0),
+ aValues->value(2),
+ aValues->value(4));
+
+ GeomVertexPtr vertexSecond =
+ GeomAlgoAPI_PointBuilder::vertex(aValues->value(1),
+ aValues->value(3),
+ aValues->value(5));
+
+
+ std::shared_ptr<GeomAlgoAPI_Box> aBoxAlgo;
+
+
+ aBoxAlgo = std::shared_ptr<GeomAlgoAPI_Box>(
+ new GeomAlgoAPI_Box(vertexFirst->point(),vertexSecond->point()));
+
+
+ // These checks should be made to the GUI for the feature but
+ // the corresponding validator does not exist yet.
+ if (!aBoxAlgo->check()) {
+ setError(aBoxAlgo->getError());
+ return;
+ }
+
+ // Build the box
+ aBoxAlgo->build();
+
+ // Check if the creation of the box
+ if (!aBoxAlgo->isDone()) {
+ // The error is not displayed in a popup window. It must be in the message console.
+ setError(aBoxAlgo->getError());
+ return;
+ }
+ if (!aBoxAlgo->checkValid("Box builder with two points")) {
+ // The error is not displayed in a popup window. It must be in the message console.
+ setError(aBoxAlgo->getError());
+ return;
+ }
+
+ int aResultIndex = 0;
+ ResultBodyPtr aResultBox = document()->createBody(data(), aResultIndex);
+ loadNamingDS(aBoxAlgo, aResultBox);
+ setResult(aResultBox, aResultIndex);
+}
+
+//=================================================================================================
+void FeaturesPlugin_CommonBoundingBox::loadNamingDS(std::shared_ptr<GeomAlgoAPI_Box> theBoxAlgo,
+ std::shared_ptr<ModelAPI_ResultBody> theResultBox)
+{
+ // Load the result
+ theResultBox->store(theBoxAlgo->shape());
+
+ // Prepare the naming
+ theBoxAlgo->prepareNamingFaces();
+
+ // Insert to faces
+ std::map< std::string, std::shared_ptr<GeomAPI_Shape> > listOfFaces =
+ theBoxAlgo->getCreatedFaces();
+ for (std::map< std::string, std::shared_ptr<GeomAPI_Shape> >::iterator it = listOfFaces.begin();
+ it != listOfFaces.end();
+ ++it) {
+ theResultBox->generated((*it).second, (*it).first);
+ }
+}
--- /dev/null
+// Copyright (C) 2018-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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 FeaturesPlugin_CommonBoundingBox_H_
+#define FeaturesPlugin_CommonBoundingBox_H_
+
+#include "FeaturesPlugin.h"
+#include <ModelAPI_Feature.h>
+
+#include <GeomAlgoAPI_Box.h>
+
+#include <GeomAPI_IPresentable.h>
+#include <GeomAPI_IScreenParams.h>
+
+#include <ModelAPI_Attribute.h>
+
+/// \class FeaturesPlugin_CommonBoundingBox
+/// \ingroup Plugins
+/// \brief Feature to view the Bounding Box.
+
+class FeaturesPlugin_CommonBoundingBox : public ModelAPI_Feature
+{
+public:
+ /// Performs the algorithm and stores results it in the data structure.
+ FEATURESPLUGIN_EXPORT virtual void execute(){};
+
+ /// Return Attribut values of result.
+ virtual AttributePtr attributResultValues() = 0;
+
+protected:
+ FeaturesPlugin_CommonBoundingBox() {}
+
+ /// Create box with two points
+ void createBoxByTwoPoints();
+
+ /// Create namming
+ void loadNamingDS(std::shared_ptr<GeomAlgoAPI_Box> theBoxAlgo,
+ std::shared_ptr<ModelAPI_ResultBody> theResultBox);
+
+ GeomShapePtr myShape;
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2018-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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 "FeaturesPlugin_CreateBoundingBox.h"
+
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeDoubleArray.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeBoolean.h>
+
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+#include <GeomAlgoAPI_BoundingBox.h>
+
+#include <Config_PropManager.h>
+#include <ModelAPI_ResultBody.h>
+
+#include <iomanip>
+#include <sstream>
+
+//=================================================================================================
+FeaturesPlugin_CreateBoundingBox::FeaturesPlugin_CreateBoundingBox()
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_CreateBoundingBox::initAttributes()
+{
+ // attribute for object selected
+ data()->addAttribute(OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+
+ // attributes for result message and values
+ data()->addAttribute(X_MIN_COORD_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(Y_MIN_COORD_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(Z_MIN_COORD_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(X_MAX_COORD_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(Y_MAX_COORD_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(Z_MAX_COORD_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(COMPUTE_ID(), ModelAPI_AttributeBoolean::typeId());
+
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), X_MIN_COORD_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), Y_MIN_COORD_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), Z_MIN_COORD_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), X_MAX_COORD_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), Y_MAX_COORD_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), Z_MAX_COORD_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), COMPUTE_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), OBJECT_ID());
+ data()->addAttribute(RESULT_VALUES_ID(), ModelAPI_AttributeDoubleArray::typeId());
+
+ data()->realArray(RESULT_VALUES_ID())->setSize(6);
+ data()->boolean(COMPUTE_ID())->setValue(true);
+}
+
+//=================================================================================================
+void FeaturesPlugin_CreateBoundingBox::execute()
+{
+ updateValues();
+ createBoxByTwoPoints();
+}
+
+//=================================================================================================
+void FeaturesPlugin_CreateBoundingBox::attributeChanged(const std::string& theID)
+{
+}
+
+//=================================================================================================
+void FeaturesPlugin_CreateBoundingBox::updateValues()
+{
+ AttributeSelectionPtr aSelection = selection(OBJECT_ID());
+ AttributeDoubleArrayPtr aValues =
+ std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
+
+ if (aSelection->isInitialized()) {
+ std::stringstream streamxmin;
+ std::stringstream streamymin;
+ std::stringstream streamzmin;
+ std::stringstream streamxmax;
+ std::stringstream streamymax;
+ std::stringstream streamzmax;
+
+ GeomShapePtr aShape;
+ if (aSelection && aSelection->isInitialized()) {
+ aShape = aSelection->value();
+ if (!aShape && aSelection->context())
+ aShape = aSelection->context()->shape();
+ }
+
+ AttributeBooleanPtr anIsCompute = boolean(COMPUTE_ID());
+ if (!anIsCompute->value()) {
+ myShape = aShape;
+ anIsCompute->setValue(true);
+ }
+
+ if (aShape && !aShape->isEqual(myShape)) {
+ double aXmin, aXmax, aYmin,aYmax,aZmin,aZmax;
+ std::string aError;
+ if (!GetBoundingBox(aShape,
+ true,
+ aXmin, aXmax,
+ aYmin,aYmax,
+ aZmin,aZmax,
+ aError))
+ setError("Error in bounding box calculation :" + aError);
+ myShape = aShape;
+ streamxmin << std::setprecision(14) << aXmin;
+ aValues->setValue(0, aXmin);
+ streamxmax << std::setprecision(14) << aXmax;
+ aValues->setValue(1, aXmax);
+ streamymin << std::setprecision(14) << aYmin;
+ aValues->setValue(2, aYmin);
+ streamymax << std::setprecision(14) << aYmax;
+ aValues->setValue(3, aYmax);
+ streamzmin << std::setprecision(14) << aZmin;
+ aValues->setValue(4, aZmin);
+ streamzmax << std::setprecision(14) << aZmax;
+ aValues->setValue(5, aZmax);
+ } else {
+ streamxmin << std::setprecision(14) << aValues->value(0);
+ streamxmax << std::setprecision(14) << aValues->value(1);
+ streamymin << std::setprecision(14) << aValues->value(2);
+ streamymax << std::setprecision(14) << aValues->value(3);
+ streamzmin << std::setprecision(14) << aValues->value(4);
+ streamzmax << std::setprecision(14) << aValues->value(5);
+ }
+
+ string(X_MIN_COORD_ID() )->setValue( "X = " + streamxmin.str() );
+ string(Y_MIN_COORD_ID() )->setValue( "Y = " + streamymin.str() );
+ string(Z_MIN_COORD_ID() )->setValue( "Z = " + streamzmin.str() );
+ string(X_MAX_COORD_ID() )->setValue( "X = " + streamxmax.str() );
+ string(Y_MAX_COORD_ID() )->setValue( "Y = " + streamymax.str() );
+ string(Z_MAX_COORD_ID() )->setValue( "Z = " + streamzmax.str() );
+ }
+}
+
+//=================================================================================================
+AttributePtr FeaturesPlugin_CreateBoundingBox::attributResultValues()
+{
+ return attribute(RESULT_VALUES_ID());
+}
--- /dev/null
+// Copyright (C) 2018-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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 FeaturesPlugin_CreateBoundingBox_H_
+#define FeaturesPlugin_CreateBoundingBox_H_
+
+#include <FeaturesPlugin_CommonBoundingBox.h>
+
+/// \class FeaturesPlugin_BoundingBox
+/// \ingroup Plugins
+/// \brief Feature to view the Bounding Box.
+
+class FeaturesPlugin_CreateBoundingBox : public FeaturesPlugin_CommonBoundingBox
+{
+public:
+ /// Bounding box kind.
+ inline static const std::string& ID()
+ {
+ static const std::string MY_ID("BoundingBox");
+ return MY_ID;
+ }
+
+ /// Attribute name for object selected.
+ inline static const std::string& OBJECT_ID()
+ {
+ static const std::string MY_OBJECT_ID("main_object");
+ return MY_OBJECT_ID;
+ }
+
+ /// Attribute name for x coodinate.
+ inline static const std::string& X_MIN_COORD_ID()
+ {
+ static const std::string MY_X_MIN_COORD_ID("xmincoordinate");
+ return MY_X_MIN_COORD_ID;
+ }
+
+ /// Attribute name for y coodinate.
+ inline static const std::string& Y_MIN_COORD_ID()
+ {
+ static const std::string MY_Y_MIN_COORD_ID("ymincoordinate");
+ return MY_Y_MIN_COORD_ID;
+ }
+
+ /// Attribute name for z coodinate.
+ inline static const std::string& Z_MIN_COORD_ID()
+ {
+ static const std::string MY_Z_MIN_COORD_ID("zmincoordinate");
+ return MY_Z_MIN_COORD_ID;
+ }
+
+ /// Attribute name for x max coodinate.
+ inline static const std::string& X_MAX_COORD_ID()
+ {
+ static const std::string MY_X_MAX_COORD_ID("xmaxcoordinate");
+ return MY_X_MAX_COORD_ID;
+ }
+
+ /// Attribute name for y max coodinate.
+ inline static const std::string& Y_MAX_COORD_ID()
+ {
+ static const std::string MY_Y_MAX_COORD_ID("ymaxcoordinate");
+ return MY_Y_MAX_COORD_ID;
+ }
+
+ /// Attribute name for z max coodinate.
+ inline static const std::string& Z_MAX_COORD_ID()
+ {
+ static const std::string MY_Z_MAX_COORD_ID("zmaxcoordinate");
+ return MY_Z_MAX_COORD_ID;
+ }
+
+ /// Attribute name for values of result.
+ inline static const std::string& RESULT_VALUES_ID()
+ {
+ static const std::string MY_RESULT_VALUES_ID("result_values");
+ return MY_RESULT_VALUES_ID;
+ }
+
+ /// Attribute name for indicate to compute the bounding box.
+ inline static const std::string& COMPUTE_ID()
+ {
+ static const std::string MY_COMPUTE_ID("compute");
+ return MY_COMPUTE_ID;
+ }
+
+ /// \return the kind of a feature.
+ virtual const std::string& getKind()
+ {
+ return ID();
+ }
+
+ /// Performs the algorithm and stores results it in the data structure.
+ FEATURESPLUGIN_EXPORT virtual void execute();
+
+ /// Request for initialization of data model of the feature: adding all attributes
+ FEATURESPLUGIN_EXPORT virtual void initAttributes();
+
+ /// Called on change of any argument-attribute of this object
+ /// \param theID identifier of changed attribute
+ FEATURESPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
+ /// Return Attribut values of result.
+ FEATURESPLUGIN_EXPORT virtual AttributePtr attributResultValues();
+
+ /// Use plugin manager for features creation
+ FeaturesPlugin_CreateBoundingBox();
+
+private:
+ /// Update values displayed.
+ void updateValues();
+
+};
+
+#endif
#include <FeaturesPlugin_BooleanCommon.h>
#include <FeaturesPlugin_BooleanSmash.h>
#include <FeaturesPlugin_BooleanFill.h>
+#include <FeaturesPlugin_BoundingBox.h>
#include <FeaturesPlugin_Chamfer.h>
+#include <FeaturesPlugin_CreateBoundingBox.h>
#include <FeaturesPlugin_Defeaturing.h>
#include <FeaturesPlugin_Extrusion.h>
#include <FeaturesPlugin_ExtrusionCut.h>
return FeaturePtr(new FeaturesPlugin_PointCoordinates);
} else if (theFeatureID == FeaturesPlugin_GeometryCalculation::ID()) {
return FeaturePtr(new FeaturesPlugin_GeometryCalculation);
+ } else if (theFeatureID == FeaturesPlugin_BoundingBox::ID()) {
+ return FeaturePtr(new FeaturesPlugin_BoundingBox);
+ } else if (theFeatureID == FeaturesPlugin_CreateBoundingBox::ID()) {
+ return FeaturePtr(new FeaturesPlugin_CreateBoundingBox);
}
<source>Geometry calculation</source>
<translation>Calcul de la géométrie</translation>
</message>
+ <message>
+ <source>Bounding box</source>
+ <translation>Boîte englobante</translation>
+ </message>
<message>
<source>Placement</source>
<translation>Placement</translation>
</message>
</context>
+ <!-- Bounding Box -->
+ <context>
+ <name>BoundingBox</name>
+ <message>
+ <source>BoundingBox</source>
+ <translation>Boîte englobante</translation>
+ </message>
+ <message>
+ <source>Create box</source>
+ <translation>Créer la boîte</translation>
+ </message>
+ </context>
+ <context>
+ <name>BoundingBoxMacro</name>
+ <message>
+ <source>BoundingBox</source>
+ <translation>Boîte englobante</translation>
+ </message>
+ <message>
+ <source>Create box</source>
+ <translation>Créer la boîte</translation>
+ </message>
+ </context>
+
<!-- Chamfer -->
<context>
<name>Chamfer</name>
<translation>Deuxième direction</translation>
</message>
</context>
- <!-- PointCoordinates -->
+
+ <!--Bounding box-->
<context>
- <name>PointCoordinates</name>
+ <name>BoundingBoxMacro</name>
<message>
- <source>Point coordinates</source>
- <translation>Coordonnées d'un point</translation>
+ <source>Bounding box</source>
+ <translation>Boîte englobante</translation>
+ </message>
+ </context>
+ <context>
+ <name>BoundingBoxMacro:main_object</name>
+ <message>
+ <source>Object</source>
+ <translation>Objet</translation>
</message>
</context>
+ <context>
+ <name>BoundingBoxMacro:createbox</name>
+ <message>
+ <source>Create box</source>
+ <translation>Créer la boîte</translation>
+ </message>
+ </context>
+ <context>
+ <name>BoundingBox</name>
+ <message>
+ <source>Bounding box</source>
+ <translation>Boîte englobante</translation>
+ </message>
+ </context>
+ <context>
+ <name>BoundingBox:main_object</name>
+ <message>
+ <source>Object</source>
+ <translation>Objet</translation>
+ </message>
+ </context>
+
<!--Geometry calculation-->
<context>
<name>GeometryCalculation</name>
<translation>Volume = </translation>
</message>
</context>
+
<!-- Measurement -->
<context>
<name>Measurement</name>
</message>
</context>
+ <!-- PointCoordinates -->
+ <context>
+ <name>PointCoordinates</name>
+ <message>
+ <source>Point coordinates</source>
+ <translation>Coordonnées d'un point</translation>
+ </message>
+ </context>
+
<!-- Rotation -->
<context>
<name>Rotation</name>
--- /dev/null
+# Copyright (C) 2014-2020 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+"""
+ Unit test of ...
+"""
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+
+import os
+import math
+
+from ModelAPI import *
+from salome.shaper import model
+
+
+__updated__ = "2020-11-12"
+
+
+#=========================================================================
+# test Bounding Box
+#=========================================================================
+def test_Bounding_Box():
+
+ model.begin()
+ file_path = os.path.join(os.getenv("DATA_DIR"),"Shapes","Step","screw.step")
+ partSet = model.moduleDocument()
+ Part_1 = model.addPart(partSet)
+ Part_1_doc = Part_1.document()
+ Import_1 = model.addImport(Part_1_doc,file_path)
+ model.do()
+ ### Create BoundingBox
+ BoundingBox_1 = model.getBoundingBox(Part_1_doc, model.selection("SOLID", "screw_1"))
+ model.end()
+
+ myDelta = 1e-6
+ Props = model.getGeometryCalculation(Part_1_doc,model.selection("SOLID", "BoundingBox_1_1"))
+
+ print(" Basic Properties:")
+ print(" Wires length: ", Props[0])
+ print(" Surface area: ", Props[1])
+ print(" Volume : ", Props[2])
+
+ aReflength = 0.32855301948678
+ aReslength = Props[0]
+ assert (math.fabs(aReslength - aReflength) < myDelta), "The surface is wrong: expected = {0}, real = {1}".format(aReflength, aReslength)
+
+ aRefSurface = 0.0041640657342782
+ aResSurface = Props[1]
+ assert (math.fabs(aResSurface - aRefSurface) < myDelta), "The surface is wrong: expected = {0}, real = {1}".format(aRefSurface, aResSurface)
+
+ aRefVolume = 1.6785355394103e-05
+ aResVolume = Props[2]
+ assert (math.fabs(aResVolume - aRefVolume) < myDelta), "The volume is wrong: expected = {0}, real = {1}".format(aRefVolume, aResVolume)
+
+
+if __name__ == '__main__':
+
+ test_Bounding_Box()
+
+ #=========================================================================
+ # End of test
+ #=========================================================================
--- /dev/null
+<source>
+ <shape_selector id="main_object"
+ label="Object"
+ tooltip="Select a object"
+ shape_types="vertex edge face solid compsolid compound object"
+ default=""
+ geometrical_selection="true">
+ <validator id="GeomValidators_ConstructionComposite"/>
+ <validator id="GeomValidators_ShapeType" parameters="vertex,line,edge,wire,face,shell,solid,compsolid,compound"/>
+ </shape_selector>
+ <groupbox title="Min">
+ <label id="xmincoordinate" isSelectable = "true"/>
+ <label id="ymincoordinate" isSelectable = "true"/>
+ <label id="zmincoordinate" isSelectable = "true"/>
+ </groupbox>
+ <groupbox title="Max">
+ <label id="xmaxcoordinate" isSelectable = "true"/>
+ <label id="ymaxcoordinate" isSelectable = "true"/>
+ <label id="zmaxcoordinate" isSelectable = "true"/>
+ </groupbox>
+ <boolvalue id="createbox" label="Create box" default="false"/>
+</source>
--- /dev/null
+<source>
+ <shape_selector id="main_object"
+ label="Object"
+ tooltip="Select a object"
+ shape_types="vertex edge face solid compsolid compound object"
+ default=""
+ geometrical_selection="true">
+ <validator id="GeomValidators_ConstructionComposite"/>
+ <validator id="GeomValidators_ShapeType" parameters="vertex,line,edge,wire,face,shell,solid,compsolid,compound"/>
+ </shape_selector>
+ <groupbox title="Min">
+ <label id="xmincoordinate" isSelectable = "true"/>
+ <label id="ymincoordinate" isSelectable = "true"/>
+ <label id="zmincoordinate" isSelectable = "true"/>
+ </groupbox>
+ <groupbox title="Max">
+ <label id="xmaxcoordinate" isSelectable = "true"/>
+ <label id="ymaxcoordinate" isSelectable = "true"/>
+ <label id="zmaxcoordinate" isSelectable = "true"/>
+ </groupbox>
+</source>
booleanOperations.rst
angularCopyFeature.rst
+ boundingBoxFeature.rst
chamferFeature.rst
copyFeature.rst
defeaturingFeature.rst
--- /dev/null
+
+ .. _tui_create_Bounding_Box:
+
+Create bounding box
+===================
+
+.. literalinclude:: examples/create_bounding_box.py
+ :linenos:
+ :language: python
+
+:download:`Download this script <examples/create_bounding_box.py>`
--- /dev/null
+.. |boundingBox.icon| image:: images/bounding.png
+
+Bounding box
+============
+
+The **Bounding box** feature displays the bounding box of sub-elements of a geometrical object (shape).
+
+The property panel displays the coordinates of inferior (**Min**) and superior (**Max**) points.
+the resulting bounding box can be created via a dedicated check-box **Create Box**. If this last is checked corresponding result and feature would be created.
+
+If the check-box **Create Box** isn't checked, **Apply** button does not generate any result and has the same effect as **Cancel** for this feature.
+
+To display the bounding box in the active part:
+
+#. select in the Main Menu *Inspection - > Bounding box* item or
+#. click |boundingBox.icon| **Bounding box** button in the toolbar
+
+Coordinates of the two points (inferior and superior) of the bounding box can be displayed for a selected object in the property panel :
+
+.. figure:: images/boundingBoxPropertyPanel.png
+ :align: center
+
+ Bounding Box
+
+
+Input fields:
+
+- **Object** contains object selected in 3D OCC viewer or object browser.
+- **Create box** check-box allow the creation of the bounding box (result and feature).
+
+Note, the coordinates of two points displayed can be selected.
+
+**TUI Command**:
+
+.. py:function:: model.getBoundingBox(Part_doc, shape)
+
+ :param part: The current part object.
+ :param object: A shape in format *model.selection("Type", shape)*.
+ :return: Created bounding box.
+
+Result
+""""""
+
+Result of **Bounding box** where **Create box** is checked.
+
+.. figure:: images/BoundingBoxResult.png
+ :align: center
+
+ Object selected
+
+**See Also** a sample TUI Script of :ref:`tui_create_Bounding_Box` operation.
--- /dev/null
+from salome.shaper import model
+import os
+
+model.begin()
+file_path = os.path.join(os.getenv("DATA_DIR"),"Shapes","Step","screw.step")
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Import_1 = model.addImport(Part_1_doc,file_path)
+model.do()
+### Create BoundingBox
+BoundingBox_1 = model.getBoundingBox(Part_1_doc, model.selection("SOLID", "screw_1"))
+model.end()
icon="icons/Features/geometryCalculation.png" helpfile="geometryCalculationFeature.html" abort_confirmation="false">
<source path="geometry_calculation_widget.xml"/>
</feature>
+ <feature id="BoundingBoxMacro" title="Bounding box" tooltip="Calculate the bounding box" auto_preview="true"
+ icon="icons/Features/bounding.png" helpfile="boundingBoxFeature.html">
+ <source path="bounding_box_widget.xml"/>
+ </feature>
+ <feature id="BoundingBox" title="Bounding box" tooltip="Calculate the bounding box" auto_preview="true"
+ icon="icons/Features/bounding.png" helpfile="boundingBoxFeature.html" internal="1">
+ <source path="create_bounding_box_widget.xml"/>
+ </feature>
<feature id="Measurement" title="Measurement" tooltip="Calculate properties of objects"
icon="icons/Features/measurement.png" helpfile="measurementFeature.html" abort_confirmation="false">
<source path="measurement_widget.xml"/>
GeomAlgoAPI_Chamfer.h
GeomAlgoAPI_Defeaturing.h
GeomAlgoAPI_GeometryCalculation.h
+ GeomAlgoAPI_BoundingBox.h
)
SET(PROJECT_SOURCES
GeomAlgoAPI_Chamfer.cpp
GeomAlgoAPI_Defeaturing.cpp
GeomAlgoAPI_GeometryCalculation.cpp
+ GeomAlgoAPI_BoundingBox.cpp
)
SET(PROJECT_LIBRARIES
--- /dev/null
+// Copyright (C) 2014-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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 "GeomAlgoAPI_BoundingBox.h"
+
+#include <BRepBuilderAPI_Copy.hxx>
+#include <Bnd_Box.hxx>
+#include <BRepTools.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepBndLib.hxx>
+#include <BRep_Builder.hxx>
+#include <Geom_Circle.hxx>
+#include <ShapeAnalysis.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS.hxx>
+#include <gp_Pln.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <BRepExtrema_DistShapeShape.hxx>
+#include <ShapeFix_Shape.hxx>
+#include <BRepBuilderAPI_Sewing.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <TopExp_Explorer.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <Geom_ToroidalSurface.hxx>
+
+/**
+* This function constructs and returns modified shape from the original one
+* for singular cases. It is used for the method GetMinDistanceSingular.
+*
+* \param theShape the original shape
+* \param theModifiedShape output parameter. The modified shape.
+* \param theAddDist output parameter. The added distance for modified shape.
+* \retval true if the shape is modified; false otherwise.
+*
+* \internal
+*/
+Standard_Boolean ModifyShape(const TopoDS_Shape &theShape,
+ TopoDS_Shape &theModifiedShape,
+ Standard_Real &theAddDist)
+{
+ TopExp_Explorer anExp;
+ int nbf = 0;
+
+ theAddDist = 0.;
+ theModifiedShape.Nullify();
+
+ for ( anExp.Init( theShape, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+ nbf++;
+ theModifiedShape = anExp.Current();
+ }
+ if(nbf==1) {
+ TopoDS_Shape sh = theShape;
+ while(sh.ShapeType()==TopAbs_COMPOUND) {
+ TopoDS_Iterator it(sh);
+ sh = it.Value();
+ }
+ Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(theModifiedShape));
+ if(S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
+ S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ||
+ S->IsUPeriodic()) {
+ const Standard_Boolean isShell =
+ (sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE);
+
+ if (!isShell && 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);
+ theModifiedShape = V;
+ theAddDist = SS->Radius();
+ return Standard_True;
+ }
+ if (!isShell && 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);
+ theModifiedShape = E;
+ theAddDist = TS->MinorRadius();
+ return Standard_True;
+ }
+
+ // non solid case or any periodic surface (Mantis 22454).
+ 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(theModifiedShape),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);
+ TopoDS_Shape aMShape;
+
+ TopoDS_Face F1 = BRepBuilderAPI_MakeFace(TrS1, Precision::Confusion());
+ TopoDS_Face F2 = BRepBuilderAPI_MakeFace(TrS2, Precision::Confusion());
+
+ if (isShell) {
+ BRep_Builder B;
+ B.MakeCompound(TopoDS::Compound(aMShape));
+ B.Add(aMShape, F1);
+ B.Add(aMShape, F2);
+ } else {
+ // The original shape is a solid.
+ BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0);
+ aSewing.Add(F1);
+ aSewing.Add(F2);
+ aSewing.Perform();
+ aMShape = aSewing.SewedShape();
+ BRep_Builder B;
+ TopoDS_Solid aSolid;
+ B.MakeSolid(aSolid);
+ B.Add(aSolid, aMShape);
+ aMShape = aSolid;
+ }
+
+ Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
+ sfs->Init(aMShape);
+ sfs->SetPrecision(1.e-6);
+ sfs->SetMaxTolerance(1.0);
+ sfs->Perform();
+ theModifiedShape = sfs->Shape();
+ return Standard_True;
+ }
+ }
+
+ theModifiedShape = theShape;
+ return Standard_False;
+ }
+
+//=======================================================================
+// function : GetMinDistanceSingular
+//=======================================================================
+double GetMinDistanceSingular(const TopoDS_Shape& aSh1,
+ const TopoDS_Shape& aSh2,
+ gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
+{
+ TopoDS_Shape tmpSh1;
+ TopoDS_Shape tmpSh2;
+ Standard_Real AddDist1 = 0.;
+ Standard_Real AddDist2 = 0.;
+ Standard_Boolean IsChange1 = ModifyShape(aSh1, tmpSh1, AddDist1);
+ Standard_Boolean IsChange2 = ModifyShape(aSh2, tmpSh2, AddDist2);
+
+ 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
+//=======================================================================
+Standard_Real 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;
+ }
+ }
+ }
+
+ aResult = GetMinDistanceSingular(theShape1, theShape2, thePnt1, thePnt2);
+
+
+ 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 < 0 || aResult > Dist) {
+ aResult = Dist;
+ thePnt1 = P1;
+ thePnt2 = P2;
+ }
+ }
+ }
+
+ return aResult;
+}
+
+//=======================================================================
+// function : PreciseBoundingBox
+//=======================================================================
+Standard_Boolean PreciseBoundingBox
+ (const TopoDS_Shape &theShape, Bnd_Box &theBox)
+{
+ if (theBox.IsVoid()) BRepBndLib::Add( theShape, theBox );
+ if (theBox.IsVoid()) return Standard_False;
+
+ 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 = 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;
+}
+
+//=================================================================================================
+bool GetBoundingBox(const std::shared_ptr<GeomAPI_Shape>& theShape,
+ const bool thePrecise,
+ Standard_Real& theXmin,Standard_Real& theXmax,
+ Standard_Real& theYmin,Standard_Real& theYmax,
+ Standard_Real& theZmin,Standard_Real& theZmax,
+ std::string& theError)
+{
+ #ifdef _DEBUG
+ std::cout << "GetBoundingBox " << std::endl;
+ #endif
+
+ if (!theShape.get()) {
+ theError = "GetBoundingBox : An invalid argument";
+ return false;
+ }
+
+ TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
+
+ //Compute the parameters
+ Bnd_Box B;
+ try {
+ OCC_CATCH_SIGNALS;
+ BRepBuilderAPI_Copy aCopyTool (aShape);
+ if (!aCopyTool.IsDone()) {
+ theError = "GetBoundingBox Error: Bad shape detected";
+ return false;
+ }
+
+ aShape = aCopyTool.Shape();
+
+ // remove triangulation to obtain more exact boundaries
+ BRepTools::Clean(aShape);
+
+ BRepBndLib::Add(aShape, B);
+
+ if (thePrecise) {
+ if (!PreciseBoundingBox(aShape, B)) {
+ theError = "GetBoundingBox Error: Bounding box cannot be precised";
+ return false;
+ }
+ }
+
+ B.Get(theXmin, theYmin, theZmin, theXmax, theYmax, theZmax);
+ }
+ catch (Standard_Failure& aFail) {
+ theError = aFail.GetMessageString();
+ return false;
+ }
+ return true;
+}
+
--- /dev/null
+// Copyright (C) 2014-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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 GeomAlgoAPI_BoundingBox_H_
+#define GeomAlgoAPI_BoundingBox_H_
+
+#include <GeomAlgoAPI.h>
+#include <GeomAPI_Shape.h>
+#include <Standard_TypeDef.hxx>
+
+/// get the boundin box of theshape.
+ /// \param theShape the shape
+ /// \param thePrecise precise TRUE for precise computation; FALSE for fast one.
+ /// \param theXmin X min of the box
+ /// \param theXmax X max of the box
+ /// \param theYmin Y min of the box
+ /// \param theYmax Y max of the box
+ /// \param theZmin Z min of the box
+ /// \param theZmax Z max of the box
+ /// \param theError error
+GEOMALGOAPI_EXPORT
+bool GetBoundingBox(const std::shared_ptr<GeomAPI_Shape>& theShape,
+ const bool thePrecise,
+ Standard_Real& theXmin,Standard_Real& theXmax,
+ Standard_Real& theYmin,Standard_Real& theYmax,
+ Standard_Real& theZmin,Standard_Real& theZmax,
+ std::string& theError);
+
+#endif
from FeaturesAPI import addFillet, addChamfer
from FeaturesAPI import addFusionFaces
from FeaturesAPI import measureLength, measureDistance, measureRadius, measureAngle
-from FeaturesAPI import getPointCoordinates, getGeometryCalculation
+from FeaturesAPI import getPointCoordinates, getGeometryCalculation, getBoundingBox
from FeaturesAPI import addRemoveResults
from FeaturesAPI import addCopy, addImportResult
from FeaturesAPI import addDefeaturing