}
GeomAlgoAPI_MakeShapeList aMakeShapeList;
+ std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints = GeomAlgoAPI_ShapeTools::getBoundingBox(anObjects, 1.0);
// Getting tools.
AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Partition::TOOL_LIST_ID());
// it could be a construction plane
ResultPtr aContext = aToolAttr->context();
if(aContext.get()) {
- aTool = GeomAlgoAPI_ShapeTools::faceToInfinitePlane(aContext->shape());
+ aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aContext->shape(), aBoundingPoints);
std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(new GeomAlgoAPI_MakeShapeCustom);
aMkShCustom->addModified(aContext->shape(), aTool);
aMakeShapeList.append(aMkShCustom);
GEOMAlgo_Splitter* anOperation = new GEOMAlgo_Splitter;
myMkShape.reset(new GeomAlgoAPI_MakeShape(anOperation, GeomAlgoAPI_MakeShape::BOPAlgoBuilder));
- // Bounding box of all objects.
- Bnd_Box aBndBox;
-
// Getting objects.
for (ListOfShape::const_iterator anObjectsIt = theObjects.begin(); anObjectsIt != theObjects.end(); anObjectsIt++) {
const TopoDS_Shape& aShape = (*anObjectsIt)->impl<TopoDS_Shape>();
- BRepBndLib::Add(aShape, aBndBox);
anOperation->AddArgument(aShape);
}
- // We enlarge bounding box just to be sure that plane will be large enough to cut all objects.
- aBndBox.Enlarge(1.0);
- Standard_Real aXArr[2] = {aBndBox.CornerMin().X(), aBndBox.CornerMax().X()};
- Standard_Real aYArr[2] = {aBndBox.CornerMin().Y(), aBndBox.CornerMax().Y()};
- Standard_Real aZArr[2] = {aBndBox.CornerMin().Z(), aBndBox.CornerMax().Z()};
- gp_Pnt aPoints[8];
- int aNum = 0;
- for(int i = 0; i < 2; i++) {
- for(int j = 0; j < 2; j++) {
- for(int k = 0; k < 2; k++) {
- aPoints[aNum] = gp_Pnt(aXArr[i], aYArr[j], aZArr[k]);
- aNum++;
- }
- }
- }
-
// Getting tools.
for (ListOfShape::const_iterator aToolsIt = theTools.begin(); aToolsIt != theTools.end(); aToolsIt++) {
- TopoDS_Shape aShape = (*aToolsIt)->impl<TopoDS_Shape>();
- if(aShape.ShapeType() == TopAbs_FACE) {
- TopoDS_Face aFace = TopoDS::Face(aShape);
- Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
- if (!aSurf.IsNull()) {
- GeomLib_IsPlanarSurface isPlanar(aSurf);
- if(isPlanar.IsPlanar()) {
- Standard_Real UMin, UMax, VMin, VMax;
- BRepTools::UVBounds(aFace, UMin, UMax, VMin, VMax);
- if(UMin == -Precision::Infinite() && UMax == Precision::Infinite() &&
- VMin == -Precision::Infinite() && VMax == Precision::Infinite()) {
- const gp_Pln& aFacePln = isPlanar.Plan();
- Handle(Geom_Plane) aFacePlane = new Geom_Plane(aFacePln);
- IntAna_Quadric aQuadric(aFacePln);
- UMin = UMax = VMin = VMax = 0;
- for(int i = 0; i < 8; i++) {
- gp_Lin aLin(aPoints[i], aFacePln.Axis().Direction());
- IntAna_IntConicQuad anIntAna(aLin, aQuadric);
- const gp_Pnt& aPntOnFace = anIntAna.Point(1);
- Standard_Real aPntU(0), aPntV(0);
- GeomLib_Tool::Parameters(aFacePlane, aPntOnFace, Precision::Confusion(), aPntU, aPntV);
- if(aPntU < UMin) UMin = aPntU;
- if(aPntU > UMax) UMax = aPntU;
- if(aPntV < VMin) VMin = aPntV;
- if(aPntV > VMax) VMax = aPntV;
- }
- aShape = BRepLib_MakeFace(aFacePln, UMin, UMax, VMin, VMax).Face();
- }
- }
- }
- }
+ const TopoDS_Shape& aShape = (*aToolsIt)->impl<TopoDS_Shape>();
anOperation->AddTool(aShape);
}
#include <gp_Pln.hxx>
+#include <Bnd_Box.hxx>
#include <BOPTools.hxx>
+#include <BRepBndLib.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepGProp.hxx>
#include <BRepTools.hxx>
#include <BRep_Tool.hxx>
#include <Geom_Plane.hxx>
+#include <GeomLib_IsPlanarSurface.hxx>
+#include <GeomLib_Tool.hxx>
#include <GProp_GProps.hxx>
+#include <IntAna_IntConicQuad.hxx>
+#include <IntAna_Quadric.hxx>
#include <NCollection_Vector.hxx>
#include <TCollection_AsciiString.hxx>
#include <TopoDS_Builder.hxx>
//=================================================================================================
-double GeomAlgoAPI_ShapeTools::volume(std::shared_ptr<GeomAPI_Shape> theShape)
+double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr<GeomAPI_Shape> theShape)
{
GProp_GProps aGProps;
if(!theShape) {
}
//=================================================================================================
-std::shared_ptr<GeomAPI_Pnt> GeomAlgoAPI_ShapeTools::centreOfMass(std::shared_ptr<GeomAPI_Shape> theShape)
+std::shared_ptr<GeomAPI_Pnt> GeomAlgoAPI_ShapeTools::centreOfMass(const std::shared_ptr<GeomAPI_Shape> theShape)
{
GProp_GProps aGProps;
if(!theShape) {
}
//=================================================================================================
-std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::faceToInfinitePlane(const std::shared_ptr<GeomAPI_Shape>& theFace)
+std::list<std::shared_ptr<GeomAPI_Pnt> > GeomAlgoAPI_ShapeTools::getBoundingBox(const ListOfShape& theShapes, const double theEnlarge)
+{
+ // Bounding box of all objects.
+ Bnd_Box aBndBox;
+
+ // Getting box.
+ for (ListOfShape::const_iterator anObjectsIt = theShapes.begin(); anObjectsIt != theShapes.end(); anObjectsIt++) {
+ const TopoDS_Shape& aShape = (*anObjectsIt)->impl<TopoDS_Shape>();
+ BRepBndLib::Add(aShape, aBndBox);
+ }
+
+ if(theEnlarge != 0.0) {
+ // We enlarge bounding box just to be sure that plane will be large enough to cut all objects.
+ aBndBox.Enlarge(theEnlarge);
+ }
+
+ Standard_Real aXArr[2] = {aBndBox.CornerMin().X(), aBndBox.CornerMax().X()};
+ Standard_Real aYArr[2] = {aBndBox.CornerMin().Y(), aBndBox.CornerMax().Y()};
+ Standard_Real aZArr[2] = {aBndBox.CornerMin().Z(), aBndBox.CornerMax().Z()};
+ std::list<std::shared_ptr<GeomAPI_Pnt> > aResultPoints;
+ int aNum = 0;
+ for(int i = 0; i < 2; i++) {
+ for(int j = 0; j < 2; j++) {
+ for(int k = 0; k < 2; k++) {
+ std::shared_ptr<GeomAPI_Pnt> aPnt(new GeomAPI_Pnt(aXArr[i], aYArr[j], aZArr[k]));
+ aResultPoints.push_back(aPnt);
+ }
+ }
+ }
+
+ return aResultPoints;
+}
+
+//=================================================================================================
+std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::faceToInfinitePlane(const std::shared_ptr<GeomAPI_Shape> theFace)
{
if (!theFace.get())
return std::shared_ptr<GeomAPI_Shape>();
aResult->setImpl(new TopoDS_Shape(anInfiniteFace));
return aResult;
}
+
+//=================================================================================================
+std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::fitPlaneToBox(const std::shared_ptr<GeomAPI_Shape> thePlane,
+ const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints)
+{
+ std::shared_ptr<GeomAPI_Shape> aResultShape;
+
+ if(!thePlane.get()) {
+ return aResultShape;
+ }
+
+ const TopoDS_Shape& aShape = thePlane->impl<TopoDS_Shape>();
+ if(aShape.ShapeType() != TopAbs_FACE) {
+ return aResultShape;
+ }
+
+ TopoDS_Face aFace = TopoDS::Face(aShape);
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+ if(aSurf.IsNull()) {
+ return aResultShape;
+ }
+
+ GeomLib_IsPlanarSurface isPlanar(aSurf);
+ if(!isPlanar.IsPlanar()) {
+ return aResultShape;
+ }
+
+ if(thePoints.size() != 8) {
+ return aResultShape;
+ }
+
+ const gp_Pln& aFacePln = isPlanar.Plan();
+ Handle(Geom_Plane) aFacePlane = new Geom_Plane(aFacePln);
+ IntAna_Quadric aQuadric(aFacePln);
+ Standard_Real UMin, UMax, VMin, VMax;
+ UMin = UMax = VMin = VMax = 0;
+ for (std::list<std::shared_ptr<GeomAPI_Pnt> >::const_iterator aPointsIt = thePoints.begin(); aPointsIt != thePoints.end(); aPointsIt++) {
+ const gp_Pnt& aPnt = (*aPointsIt)->impl<gp_Pnt>();
+ gp_Lin aLin(aPnt, aFacePln.Axis().Direction());
+ IntAna_IntConicQuad anIntAna(aLin, aQuadric);
+ const gp_Pnt& aPntOnFace = anIntAna.Point(1);
+ Standard_Real aPntU(0), aPntV(0);
+ GeomLib_Tool::Parameters(aFacePlane, aPntOnFace, Precision::Confusion(), aPntU, aPntV);
+ if(aPntU < UMin) UMin = aPntU;
+ if(aPntU > UMax) UMax = aPntU;
+ if(aPntV < VMin) VMin = aPntV;
+ if(aPntV > VMax) VMax = aPntV;
+ }
+ aResultShape.reset(new GeomAPI_Shape);
+ aResultShape->setImpl(new TopoDS_Shape(BRepLib_MakeFace(aFacePln, UMin, UMax, VMin, VMax).Face()));
+
+ return aResultShape;
+}
{
public:
/// \return the total volume of the solids of the current shape or 0.0 if it can be computed.
- static double volume(std::shared_ptr<GeomAPI_Shape> theShape);
+ static double volume(const std::shared_ptr<GeomAPI_Shape> theShape);
/// \return the centre of mass of the current face. The coordinates returned for the center of mass
/// are expressed in the absolute Cartesian coordinate system. (This function works only for surfaces).
- static std::shared_ptr<GeomAPI_Pnt> centreOfMass(std::shared_ptr<GeomAPI_Shape> theShape);
+ static std::shared_ptr<GeomAPI_Pnt> centreOfMass(const std::shared_ptr<GeomAPI_Shape> theShape);
/** \brief Combines faces with common edges to shells, or solids to compsolids.
* \param[in] theCompound compound of shapes.
ListOfShape& theCombinedShapes,
ListOfShape& theFreeShapes);
+ /** \brief Calculates bounding box for theShapes
+ * \return list of eight points.
+ * \param[in] theShapes list of shapes.
+ * \param[in] theEnlarge enlarges bounding box size.
+ */
+ static std::list<std::shared_ptr<GeomAPI_Pnt> > getBoundingBox(const ListOfShape& theShapes, const double theEnlarge = 0.0);
+
/**
- * Returns infinite plane received from theFace plane
+ * Returns infinite plane received from theFace plane.
*/
- static std::shared_ptr<GeomAPI_Shape> faceToInfinitePlane(const std::shared_ptr<GeomAPI_Shape>& theFace);
+ static std::shared_ptr<GeomAPI_Shape> faceToInfinitePlane(const std::shared_ptr<GeomAPI_Shape> theFace);
+
+ /** \brief Enlarges or reduces plane to fit bounding box.
+ * \return plane that fits to bounding box.
+ * \param[in] thePlane base plane.
+ * \param[in] thePoints bounding box points (shoud be eight).
+ */
+ static std::shared_ptr<GeomAPI_Shape> fitPlaneToBox(const std::shared_ptr<GeomAPI_Shape> thePlane,
+ const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints);
+
};
#endif