// Created: 12 May 2015
// Author: Dmitry Bobylev
-#include <GeomAlgoAPI_Revolution.h>
+#include "GeomAlgoAPI_Revolution.h"
#include <GeomAPI_Face.h>
#include <GeomAPI_ShapeExplorer.h>
#include <TopoDS.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
+/// \brief Constructs infinite face from thePlane, and with axis located on the same side
+/// of the plane as thePoint. Modifies thePlane axis direction.
+/// \param[in,out] thePlane plane to construct face.
+/// \param[in] thePoint point to locate plane axis.
+/// \return constructed face.
+static TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint);
+
+/// \return solid created from face or shell.
+static TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape);
+
+/// \brief Selects solid from theShape with closest center of mass to thePoint
+/// \param[in] theShape compound with solids.
+/// \param[in] thePoint point.
+/// \return solid.
+static TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint);
+
//=================================================================================================
GeomAlgoAPI_Revolution::GeomAlgoAPI_Revolution(std::shared_ptr<GeomAPI_Shape> theBaseShape,
std::shared_ptr<GeomAPI_Ax1> theAxis,
double theToAngle,
double theFromAngle)
-: myDone(false)
{
build(theBaseShape, theAxis, std::shared_ptr<GeomAPI_Shape>(), theToAngle, std::shared_ptr<GeomAPI_Shape>(), theFromAngle);
}
double theToAngle,
std::shared_ptr<GeomAPI_Shape> theFromShape,
double theFromAngle)
-: myDone(false)
{
build(theBaseShape, theAxis, theToShape, theToAngle, theFromShape, theFromAngle);
}
-//=================================================================================================
-TopoDS_Face GeomAlgoAPI_Revolution::makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint)
-{
- if(!thePlane.Contains(thePoint, Precision::Confusion())) {
- gp_XYZ aVec = thePoint.XYZ() - thePlane.Location().XYZ();
- double aSign = aVec * thePlane.Axis().Direction().XYZ();
- if(aSign < 0) thePlane.SetAxis(thePlane.Axis().Reversed());
- }
-
- BRepBuilderAPI_MakeFace aMakeFace(thePlane);
- TopoDS_Face aResultFace = TopoDS::Face(aMakeFace.Shape());
-
- return aResultFace;
-}
-
-//=================================================================================================
-TopoDS_Solid GeomAlgoAPI_Revolution::makeSolidFromShape(const TopoDS_Shape& theShape)
-{
- TopoDS_Shell aShell;
- TopoDS_Solid aSolid;
-
- BRep_Builder aBoundingBuilder;
- if(theShape.ShapeType() == TopAbs_SHELL) {
- aShell = TopoDS::Shell(theShape);
- } else {
- aBoundingBuilder.MakeShell(aShell);
- aBoundingBuilder.Add(aShell, theShape);
- }
- aBoundingBuilder.MakeSolid(aSolid);
- aBoundingBuilder.Add(aSolid, aShell);
-
- return aSolid;
-}
-
-//=================================================================================================
-TopoDS_Shape GeomAlgoAPI_Revolution::findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint)
-{
- TopoDS_Shape aResult = theShape;
-
- if(theShape.ShapeType() == TopAbs_COMPOUND) {
- double aMinDistance = Precision::Infinite();
- double aCurDistance;
- GProp_GProps aGProps;
- gp_Pnt aCentr;
-
- for (TopoDS_Iterator anItr(theShape); anItr.More(); anItr.Next()) {
- TopoDS_Shape aValue = anItr.Value();
- BRepGProp::VolumeProperties(aValue, aGProps);
- aCentr = aGProps.CentreOfMass();
- aCurDistance = aCentr.Distance(thePoint);
-
- if(aCurDistance < aMinDistance) {
- aMinDistance = aCurDistance;
- aResult = aValue;
- }
- }
- }
-
- return aResult;
-}
-
//=================================================================================================
void GeomAlgoAPI_Revolution::build(const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
const std::shared_ptr<GeomAPI_Ax1>& theAxis,
gp_Pnt aBaseCentre = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape)->impl<gp_Pnt>();
TopoDS_Shape aResult;
- ListOfMakeShape aListOfMakeShape;
if(!theFromShape && !theToShape) { // Case 1: When only angles was set.
// Rotating base face with the negative value of "from angle".
gp_Trsf aBaseTrsf;
if(!aBaseTransform) {
return;
}
- aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aBaseTransform)));
+ this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aBaseTransform)));
if(!aBaseTransform->IsDone()) {
return;
}
if(!aRevolBuilder) {
return;
}
- aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aRevolBuilder)));
+ this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aRevolBuilder)));
if(!aRevolBuilder->IsDone()) {
return;
}
std::shared_ptr<GeomAPI_Shape> aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
aFromShape->setImpl(new TopoDS_Shape(aRevolBuilder->FirstShape(aFace)));
aToShape->setImpl(new TopoDS_Shape(aRevolBuilder->LastShape(aFace)));
- myFromFaces.push_back(aFromShape);
- myToFaces.push_back(aToShape);
+ this->addFromFace(aFromShape);
+ this->addToFace(aToShape);
}
} else if(theFromShape && theToShape) { // Case 2: When both bounding planes were set.
// Making revolution to the 360 angle.
if(!aRevolBuilder) {
return;
}
- aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aRevolBuilder)));
+ this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aRevolBuilder)));
if(!aRevolBuilder->IsDone()) {
return;
}
if(!aFromCutBuilder->IsDone()) {
return;
}
- aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aFromCutBuilder)));
+ this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aFromCutBuilder)));
aResult = aFromCutBuilder->Shape();
// Cutting revolution with to plane.
if(!aToCutBuilder->IsDone()) {
return;
}
- aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aToCutBuilder)));
+ this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aToCutBuilder)));
aResult = aToCutBuilder->Shape();
TopExp_Explorer anExp(aResult, TopAbs_SOLID);
if(aFaceSurface == aFromSurface) {
std::shared_ptr<GeomAPI_Shape> aFSHape(new GeomAPI_Shape);
aFSHape->setImpl(new TopoDS_Shape(aFaceOnResult));
- myFromFaces.push_back(aFSHape);
+ this->addFromFace(aFSHape);
}
if(aFaceSurface == aToSurface) {
std::shared_ptr<GeomAPI_Shape> aTSHape(new GeomAPI_Shape);
aTSHape->setImpl(new TopoDS_Shape(aFaceOnResult));
- myToFaces.push_back(aTSHape);
+ this->addToFace(aTSHape);
}
}
} else { //Case 3: When only one bounding plane was set.
if(!aRevolBuilder) {
return;
}
- aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aRevolBuilder)));
+ this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aRevolBuilder)));
if(!aRevolBuilder->IsDone()) {
return;
}
if(!aBoundingCutBuilder->IsDone()) {
return;
}
- aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aBoundingCutBuilder)));
+ this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aBoundingCutBuilder)));
aResult = aBoundingCutBuilder->Shape();
// Setting naming.
for(TopTools_ListIteratorOfListOfShape anIt(aBndShapes); anIt.More(); anIt.Next()) {
std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
aShape->setImpl(new TopoDS_Shape(anIt.Value()));
- isFromFaceSet ? myFromFaces.push_back(aShape) : myToFaces.push_back(aShape);
+ isFromFaceSet ? this->addFromFace(aShape) : this->addToFace(aShape);
}
// Try to cut with base face. If it can not be done then keep result of cut with bounding plane.
TopoDS_Shape aCutResult = aBaseCutBuilder->Shape();
TopExp_Explorer anExp(aCutResult, TopAbs_SOLID);
if(anExp.More()) {
- aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aBaseCutBuilder)));
+ this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aBaseCutBuilder)));
aResult = aCutResult;
}
}
for(TopTools_ListIteratorOfListOfShape anIt(aBsShapes); anIt.More(); anIt.Next()) {
std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
aShape->setImpl(new TopoDS_Shape(anIt.Value()));
- isFromFaceSet ? myToFaces.push_back(aShape) : myFromFaces.push_back(aShape);
+ isFromFaceSet ? this->addToFace(aShape) : this->addFromFace(aShape);
}
TopExp_Explorer anExp(aResult, TopAbs_SOLID);
if(aFaceSurface == aBoundingSurface) {
std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
aShape->setImpl(new TopoDS_Shape(aFaceOnResult));
- isFromFaceSet ? myFromFaces.push_back(aShape) : myToFaces.push_back(aShape);
+ isFromFaceSet ? this->addFromFace(aShape) : this->addToFace(aShape);
}
}
}
if(aResult.IsNull()) {
return;
}
- myShape.reset(new GeomAPI_Shape);
- myShape->setImpl(new TopoDS_Shape(aResult));
-
- // Filling data map to keep correct orientation of sub-shapes.
- myMap.reset(new GeomAPI_DataMapOfShapeShape);
- for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
- std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape);
- aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
- myMap->bind(aCurrentShape, aCurrentShape);
- }
-
- // Setting list of make shape.
- myMkShape.reset(new GeomAlgoAPI_MakeShapeList(aListOfMakeShape));
-
- myDone = true;
+ std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+ aShape->setImpl(new TopoDS_Shape(aResult));
+ this->setShape(aShape);
+ this->setDone(true);
}
//=================================================================================================
-const bool GeomAlgoAPI_Revolution::isDone() const
+TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint)
{
- return myDone;
-}
+ if(!thePlane.Contains(thePoint, Precision::Confusion())) {
+ gp_XYZ aVec = thePoint.XYZ() - thePlane.Location().XYZ();
+ double aSign = aVec * thePlane.Axis().Direction().XYZ();
+ if(aSign < 0) thePlane.SetAxis(thePlane.Axis().Reversed());
+ }
-//=================================================================================================
-const bool GeomAlgoAPI_Revolution::isValid() const
-{
- BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
- return (aChecker.IsValid() == Standard_True);
+ BRepBuilderAPI_MakeFace aMakeFace(thePlane);
+ TopoDS_Face aResultFace = TopoDS::Face(aMakeFace.Shape());
+
+ return aResultFace;
}
//=================================================================================================
-const bool GeomAlgoAPI_Revolution::hasVolume() const
+TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape)
{
- bool hasVolume(false);
- if(isValid()) {
- const TopoDS_Shape& aRShape = myShape->impl<TopoDS_Shape>();
- GProp_GProps aGProp;
- BRepGProp::VolumeProperties(aRShape, aGProp);
- if(aGProp.Mass() > Precision::Confusion())
- hasVolume = true;
+ TopoDS_Shell aShell;
+ TopoDS_Solid aSolid;
+
+ BRep_Builder aBoundingBuilder;
+ if(theShape.ShapeType() == TopAbs_SHELL) {
+ aShell = TopoDS::Shell(theShape);
+ } else {
+ aBoundingBuilder.MakeShell(aShell);
+ aBoundingBuilder.Add(aShell, theShape);
}
- return hasVolume;
-}
+ aBoundingBuilder.MakeSolid(aSolid);
+ aBoundingBuilder.Add(aSolid, aShell);
-//=================================================================================================
-const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Revolution::shape () const
-{
- return myShape;
+ return aSolid;
}
//=================================================================================================
-const ListOfShape& GeomAlgoAPI_Revolution::fromFaces() const
+TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint)
{
- return myFromFaces;
-}
+ TopoDS_Shape aResult = theShape;
-//=================================================================================================
-const ListOfShape& GeomAlgoAPI_Revolution::toFaces() const
-{
- return myToFaces;
-}
+ if(theShape.ShapeType() == TopAbs_COMPOUND) {
+ double aMinDistance = Precision::Infinite();
+ double aCurDistance;
+ GProp_GProps aGProps;
+ gp_Pnt aCentr;
-//=================================================================================================
-std::shared_ptr<GeomAPI_DataMapOfShapeShape> GeomAlgoAPI_Revolution::mapOfShapes() const
-{
- return myMap;
-}
+ for (TopoDS_Iterator anItr(theShape); anItr.More(); anItr.Next()) {
+ TopoDS_Shape aValue = anItr.Value();
+ BRepGProp::VolumeProperties(aValue, aGProps);
+ aCentr = aGProps.CentreOfMass();
+ aCurDistance = aCentr.Distance(thePoint);
-//=================================================================================================
-std::shared_ptr<GeomAlgoAPI_MakeShape> GeomAlgoAPI_Revolution::makeShape() const
-{
- return myMkShape;
+ if(aCurDistance < aMinDistance) {
+ aMinDistance = aCurDistance;
+ aResult = aValue;
+ }
+ }
+ }
+
+ return aResult;
}
#define GeomAlgoAPI_Revolution_H_
#include <GeomAlgoAPI.h>
-#include <GeomAlgoAPI_MakeShape.h>
+#include <GeomAlgoAPI_MakeSweep.h>
#include <GeomAPI_Ax1.h>
-#include <GeomAPI_DataMapOfShapeShape.h>
-class gp_Pln;
-class gp_Pnt;
-class TopoDS_Face;
-class TopoDS_Shape;
-class TopoDS_Solid;
-
-/** \class GeomAlgoAPI_Revolution
- * \ingroup DataAlgo
- * \brief Allows to create the revolution based on a given face, angles and bounding planes.
- * \n Note that only the planar faces are allowed as bounding faces and resulting
- * revolution will be bounded by the infinite planes taken from the faces.
- * \n If the bounding plane was specified with the angle then this plane will be rotated around
- * the axis to the value of the angle.
- * \n Note that algorithm return only one solid object. So in case when after cutting with bounding
- * planes algorithm got more than one solid it will return the closest to the center of mass of
- * the base face.
- */
-class GeomAlgoAPI_Revolution : public GeomAPI_Interface
+/// \class GeomAlgoAPI_Revolution
+/// \ingroup DataAlgo
+/// \brief Allows to create the revolution based on a given face, angles and bounding planes.
+/// \n Note that only the planar faces are allowed as bounding faces and resulting
+/// revolution will be bounded by the infinite planes taken from the faces.
+/// \n If the bounding plane was specified with the angle then this plane will be rotated around
+/// the axis to the value of the angle.
+/// \n Note that algorithm return only one solid object. So in case when after cutting with bounding
+/// planes algorithm got more than one solid it will return the closest to the center of mass of
+/// the base face.
+class GeomAlgoAPI_Revolution : public GeomAlgoAPI_MakeSweep
{
public:
- /** \brief Creates revolution for the given shape.
- * \param[in] theBaseShape face for revolution.
- * \param[in] theAxis axis for revolution.
- * \param[in] theToAngle to angle.
- * \param[in] theFromAngle from angle.
- */
+ /// \brief Creates revolution for the given shape.
+ /// \param[in] theBaseShape face for revolution.
+ /// \param[in] theAxis axis for revolution.
+ /// \param[in] theToAngle to angle.
+ /// \param[in] theFromAngle from angle.
GEOMALGOAPI_EXPORT GeomAlgoAPI_Revolution(std::shared_ptr<GeomAPI_Shape> theBaseShape,
std::shared_ptr<GeomAPI_Ax1> theAxis,
double theToAngle,
double theFromAngle);
- /** \brief Creates revolution for the given shape.
- * \param[in] theBaseShape face for revolution.
- * \param[in] theAxis axis for revolution.
- * \param[in] theToShape to bounding shape. Can be empty. In this case offset will be applied to the basis.
- * \param[in] theToAngle to angle.
- * \param[in] theFromShape from bounding shape. Can be empty. In this case offset will be applied to the basis.
- * \param[in] theFromAngle from angle.
- */
+ /// \brief Creates revolution for the given shape.
+ /// \param[in] theBaseShape face for revolution.
+ /// \param[in] theAxis axis for revolution.
+ /// \param[in] theToShape to bounding shape. Can be empty. In this case offset will be applied to the basis.
+ /// \param[in] theToAngle to angle.
+ /// \param[in] theFromShape from bounding shape. Can be empty. In this case offset will be applied to the basis.
+ /// \param[in] theFromAngle from angle.
GEOMALGOAPI_EXPORT GeomAlgoAPI_Revolution(std::shared_ptr<GeomAPI_Shape> theBaseShape,
std::shared_ptr<GeomAPI_Ax1> theAxis,
std::shared_ptr<GeomAPI_Shape> theToShape,
std::shared_ptr<GeomAPI_Shape> theFromShape,
double theFromAngle);
- /// \return true if algorithm succeed.
- GEOMALGOAPI_EXPORT const bool isDone() const;
-
- /// \return true if resulting shape is valid.
- GEOMALGOAPI_EXPORT const bool isValid() const;
-
- /// \return true if resulting shape has volume.
- GEOMALGOAPI_EXPORT const bool hasVolume() const;
-
- /// \return result of the Revolution algorithm.
- GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape>& shape() const;
-
- /// \returns the list of from faces.
- GEOMALGOAPI_EXPORT const ListOfShape& fromFaces() const;
-
- /// \return the list of to faces.
- GEOMALGOAPI_EXPORT const ListOfShape& toFaces() const;
-
- /// \return map of sub-shapes of the result. To be used for History keeping.
- GEOMALGOAPI_EXPORT std::shared_ptr<GeomAPI_DataMapOfShapeShape> mapOfShapes() const;
-
- /// \return interface for History processing.
- GEOMALGOAPI_EXPORT std::shared_ptr<GeomAlgoAPI_MakeShape> makeShape() const;
-
private:
- /** \brief Constructs infinite face from thePlane, and with axis located on the same side
- * of the plane as thePoint. Modifies thePlane axis direction.
- * \param[in,out] thePlane plane to construct face.
- * \param[in] thePoint point to locate plane axis.
- * \return constructed face.
- */
- TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint);
-
- /// \return solid created from face or shell.
- TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape);
-
- /** \brief Selects solid from theShape with closest center of mass to thePoint
- * \param[in] theShape compound with solids.
- * \param[in] thePoint point.
- * \return solid.
- */
- TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint);
-
/// Builds resulting shape.
void build(const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
const std::shared_ptr<GeomAPI_Ax1>& theAxis,
double theToAngle,
const std::shared_ptr<GeomAPI_Shape>& theFromShape,
double theFromAngle);
-
-private:
- /// Fields.
- bool myDone;
- std::shared_ptr<GeomAPI_Shape> myShape;
- ListOfShape myFromFaces;
- ListOfShape myToFaces;
- std::shared_ptr<GeomAPI_DataMapOfShapeShape> myMap;
- std::shared_ptr<GeomAlgoAPI_MakeShape> myMkShape;
};
#endif
\ No newline at end of file