From: azv Date: Tue, 14 Aug 2018 05:47:20 +0000 (+0300) Subject: Issue 2556: Functionality of inspection “WhatIs” X-Git-Tag: SHAPER_V9_1_0RC1~75 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=5ff96b13035a4e95572580dbc6aa6f2c526d0a45;p=modules%2Fshaper.git Issue 2556: Functionality of inspection “WhatIs” Assign inspection roles to the corresponding shapes --- diff --git a/src/GeomAPI/CMakeLists.txt b/src/GeomAPI/CMakeLists.txt index d42c54c57..5d71673a7 100644 --- a/src/GeomAPI/CMakeLists.txt +++ b/src/GeomAPI/CMakeLists.txt @@ -60,7 +60,14 @@ SET(PROJECT_HEADERS GeomAPI_Ellipse.h GeomAPI_Ellipse2d.h GeomAPI_Tools.h - GeomAPI_IScreenParams.h + GeomAPI_IScreenParams.h + GeomAPI_Shell.h + GeomAPI_Solid.h + GeomAPI_Sphere.h + GeomAPI_Cylinder.h + GeomAPI_Cone.h + GeomAPI_Torus.h + GeomAPI_Box.h ) SET(PROJECT_SOURCES @@ -99,6 +106,13 @@ SET(PROJECT_SOURCES GeomAPI_Ellipse.cpp GeomAPI_Ellipse2d.cpp GeomAPI_Tools.cpp + GeomAPI_Shell.cpp + GeomAPI_Solid.cpp + GeomAPI_Sphere.cpp + GeomAPI_Cylinder.cpp + GeomAPI_Cone.cpp + GeomAPI_Torus.cpp + GeomAPI_Box.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/GeomAPI/GeomAPI.i b/src/GeomAPI/GeomAPI.i index c6002ccc9..82e292108 100644 --- a/src/GeomAPI/GeomAPI.i +++ b/src/GeomAPI/GeomAPI.i @@ -63,6 +63,9 @@ %shared_ptr(GeomAPI_XYZ) %shared_ptr(GeomAPI_Trsf) %shared_ptr(GeomAPI_Wire) +%shared_ptr(GeomAPI_Shell) +%shared_ptr(GeomAPI_Solid) +%shared_ptr(GeomAPI_Box) // all supported interfaces @@ -96,3 +99,6 @@ %include "GeomAPI_XYZ.h" %include "GeomAPI_Trsf.h" %include "GeomAPI_Wire.h" +%include "GeomAPI_Shell.h" +%include "GeomAPI_Solid.h" +%include "GeomAPI_Box.h" diff --git a/src/GeomAPI/GeomAPI_Box.cpp b/src/GeomAPI/GeomAPI_Box.cpp new file mode 100644 index 000000000..68fe4db81 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Box.cpp @@ -0,0 +1,96 @@ +// Copyright (C) 2018-20xx 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 +#include + +#include + +struct Box +{ + std::shared_ptr myCoordSystem; + double myWidth; + double myDepth; + double myHeight; + + Box(const std::shared_ptr& theCoordSystem, + const double theWidth, + const double theDepth, + const double theHeight) + : myCoordSystem(theCoordSystem), + myWidth(theWidth), + myDepth(theDepth), + myHeight(theHeight) + {} +}; + +#define MY_BOX implPtr() + +//================================================================================================= +GeomAPI_Box::GeomAPI_Box() + : GeomAPI_Interface(new Box(std::shared_ptr(new GeomAPI_Ax3), 0., 0., 0.)) +{ +} + +//================================================================================================= +GeomAPI_Box::GeomAPI_Box(const std::shared_ptr& theCorner, + const double theWidth, + const double theDepth, + const double theHeight) + : GeomAPI_Interface(new Box(theCorner, theWidth, theDepth, theHeight)) +{ +} + +//================================================================================================= +std::shared_ptr GeomAPI_Box::axes() const +{ + return MY_BOX->myCoordSystem; +} + +//================================================================================================= +std::shared_ptr GeomAPI_Box::corner() const +{ + return axes()->origin(); +} + +//================================================================================================= +double GeomAPI_Box::width() const +{ + return MY_BOX->myWidth; +} + +//================================================================================================= +double GeomAPI_Box::depth() const +{ + return MY_BOX->myDepth; +} + +//================================================================================================= +double GeomAPI_Box::height() const +{ + return MY_BOX->myHeight; +} + +//================================================================================================= +bool GeomAPI_Box::isAxesAligned() const +{ + return Abs(MY_BOX->myCoordSystem->dirX()->x() - 1.0) < Precision::Angular() && + Abs(MY_BOX->myCoordSystem->normal()->z() - 1.0) < Precision::Angular(); +} diff --git a/src/GeomAPI/GeomAPI_Box.h b/src/GeomAPI/GeomAPI_Box.h new file mode 100644 index 000000000..c3c9673cc --- /dev/null +++ b/src/GeomAPI/GeomAPI_Box.h @@ -0,0 +1,68 @@ +// Copyright (C) 2018-20xx 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 GeomAPI_Box_H_ +#define GeomAPI_Box_H_ + +#include +#include + +class GeomAPI_Ax3; +class GeomAPI_Pnt; + +/**\class GeomAPI_Box + * \ingroup DataModel + * \brief Box in 3D + */ +class GeomAPI_Box : public GeomAPI_Interface +{ +public: + /// Default constructor + GEOMAPI_EXPORT GeomAPI_Box(); + + /// Creation of torus defined by center point, direction, major and minor radii + GEOMAPI_EXPORT GeomAPI_Box(const std::shared_ptr& theCorner, + const double theWidth, + const double theDepth, + const double theHeight); + + /// Return axes of the box + GEOMAPI_EXPORT std::shared_ptr axes() const; + + /// Return base corner of the box + GEOMAPI_EXPORT std::shared_ptr corner() const; + + /// Return width of the box + GEOMAPI_EXPORT double width() const; + + /// Return depth of the box + GEOMAPI_EXPORT double depth() const; + + /// Return height of the box + GEOMAPI_EXPORT double height() const; + + /// Return \c true is the box is aligned in main axes + GEOMAPI_EXPORT bool isAxesAligned() const; +}; + +//! Pointer on the object +typedef std::shared_ptr GeomBoxPtr; + +#endif diff --git a/src/GeomAPI/GeomAPI_Cone.cpp b/src/GeomAPI/GeomAPI_Cone.cpp new file mode 100644 index 000000000..e18d4d333 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Cone.cpp @@ -0,0 +1,130 @@ +// Copyright (C) 2018-20xx 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 +#include +#include + +#include +#include + +#define MY_CONE implPtr() + +static gp_Cone* newCone(const gp_Pnt& theApex, const gp_Dir& theAxis, + const double theSemiAngle, const double theRadius = 0.0) +{ + return new gp_Cone(gp_Ax3(theApex, theAxis), theSemiAngle, theRadius); +} + +//================================================================================================= +GeomAPI_Cone::GeomAPI_Cone(const std::shared_ptr& theApex, + const std::shared_ptr& theAxis, + const double theSemiAngle) + : GeomAPI_Interface(newCone(theApex->impl(), theAxis->impl(), theSemiAngle)), + myRadius1(Precision::Infinite()), + myRadius2(Precision::Infinite()) +{ +} + +//================================================================================================= +GeomAPI_Cone::GeomAPI_Cone(const std::shared_ptr& theLocation, + const std::shared_ptr& theAxis, + const double theSemiAngle, + const double theRadius) + : GeomAPI_Interface( + newCone(theLocation->impl(), theAxis->impl(), theSemiAngle, theRadius)), + myRadius1(theRadius), + myRadius2(Precision::Infinite()) +{ +} + +//================================================================================================= +GeomAPI_Cone::GeomAPI_Cone(const std::shared_ptr& theLocation, + const std::shared_ptr& theAxis, + const double theSemiAngle, + const double theRadius1, + const double theRadius2) + : GeomAPI_Interface( + newCone(theLocation->impl(), theAxis->impl(), theSemiAngle, theRadius1)), + myRadius1(theRadius1), + myRadius2(theRadius2) +{ +} + +//================================================================================================= +std::shared_ptr GeomAPI_Cone::apex() const +{ + const gp_Pnt& anApex = MY_CONE->Apex(); + return std::shared_ptr(new GeomAPI_Pnt(anApex.X(), anApex.Y(), anApex.Z())); +} + +//================================================================================================= +std::shared_ptr GeomAPI_Cone::location() const +{ + const gp_Pnt& aLoc = MY_CONE->Location(); + return std::shared_ptr(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); +} + +//================================================================================================= +std::shared_ptr GeomAPI_Cone::axis() const +{ + const gp_Dir& anAxis = MY_CONE->Position().Direction(); + return std::shared_ptr(new GeomAPI_Dir(anAxis.X(), anAxis.Y(), anAxis.Z())); +} + +//================================================================================================= +double GeomAPI_Cone::semiAngle() const +{ + return MY_CONE->SemiAngle(); +} + +//================================================================================================= +double GeomAPI_Cone::radius1() const +{ + return myRadius1; +} + +//================================================================================================= +double GeomAPI_Cone::radius2() const +{ + return myRadius2; +} + +//================================================================================================= +double GeomAPI_Cone::height() const +{ + if (Precision::IsInfinite(myRadius1) || Precision::IsInfinite(myRadius2)) + return Precision::Infinite(); + + return Abs((myRadius2 - myRadius1) / Tan(semiAngle())); +} + +//================================================================================================= +bool GeomAPI_Cone::isSemiInfinite() const +{ + return (!Precision::IsInfinite(myRadius1) && Precision::IsInfinite(myRadius2)) || + (Precision::IsInfinite(myRadius1) && !Precision::IsInfinite(myRadius2)); +} + +//================================================================================================= +bool GeomAPI_Cone::isInfinite() const +{ + return Precision::IsInfinite(myRadius1) && Precision::IsInfinite(myRadius2); +} diff --git a/src/GeomAPI/GeomAPI_Cone.h b/src/GeomAPI/GeomAPI_Cone.h new file mode 100644 index 000000000..59e24956c --- /dev/null +++ b/src/GeomAPI/GeomAPI_Cone.h @@ -0,0 +1,89 @@ +// Copyright (C) 2018-20xx 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 GeomAPI_Cone_H_ +#define GeomAPI_Cone_H_ + +#include +#include + +class GeomAPI_Dir; +class GeomAPI_Pnt; + +/**\class GeomAPI_Cone + * \ingroup DataModel + * \brief Conical surface in 3D + */ +class GeomAPI_Cone : public GeomAPI_Interface +{ +public: + /// Creation of infinite cone defined by apex, axis and semi-angle + GEOMAPI_EXPORT GeomAPI_Cone(const std::shared_ptr& theApex, + const std::shared_ptr& theAxis, + const double theSemiAngle); + + /// Creation of semi-infinite cone by location and radius of reference circle, axis, semi-angle + GEOMAPI_EXPORT GeomAPI_Cone(const std::shared_ptr& theLocation, + const std::shared_ptr& theAxis, + const double theSemiAngle, + const double theRadius); + + /// Creating of cone by location of reference circle, axis, semi-angle and radii of boundary circles + GEOMAPI_EXPORT GeomAPI_Cone(const std::shared_ptr& theLocation, + const std::shared_ptr& theAxis, + const double theSemiAngle, + const double theRadius1, + const double theRadius2); + + /// Return apex of the cone + GEOMAPI_EXPORT std::shared_ptr apex() const; + + /// Return location of the cone (center of the circle nearest to the apex) + GEOMAPI_EXPORT std::shared_ptr location() const; + + /// Return axis of the cone + GEOMAPI_EXPORT std::shared_ptr axis() const; + + /// Return semi-angle of the cone + GEOMAPI_EXPORT double semiAngle() const; + + /// Return first radius of the cone or Precision::Infinite() if the cone is infinite + GEOMAPI_EXPORT double radius1() const; + + /// Return second radius of the cone or Precision::Infinite() if the cone is infinite + GEOMAPI_EXPORT double radius2() const; + + /// Return height of the cone + GEOMAPI_EXPORT double height() const; + + /// Return \c true is the cone is semi-infinite + GEOMAPI_EXPORT bool isSemiInfinite() const; + + /// Return \c true is the cone is infinite + GEOMAPI_EXPORT bool isInfinite() const; + +private: + double myRadius1, myRadius2; +}; + +//! Pointer on the object +typedef std::shared_ptr GeomConePtr; + +#endif diff --git a/src/GeomAPI/GeomAPI_Cylinder.cpp b/src/GeomAPI/GeomAPI_Cylinder.cpp new file mode 100644 index 000000000..0e043bbc7 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Cylinder.cpp @@ -0,0 +1,84 @@ +// Copyright (C) 2018-20xx 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 +#include +#include + +#include +#include + +#define MY_CYL implPtr() + +static gp_Cylinder* newCyl(const gp_Pnt& theLocation, const gp_Dir& theAxis, const double theRadius) +{ + return new gp_Cylinder(gp_Ax3(theLocation, theAxis), theRadius); +} + +//================================================================================================= +GeomAPI_Cylinder::GeomAPI_Cylinder(const std::shared_ptr& theLocation, + const std::shared_ptr& theAxis, + const double theRadius) + : GeomAPI_Interface(newCyl(theLocation->impl(), theAxis->impl(), theRadius)), + myHeight(Precision::Infinite()) +{ +} + +//================================================================================================= +GeomAPI_Cylinder::GeomAPI_Cylinder(const std::shared_ptr& theLocation, + const std::shared_ptr& theAxis, + const double theRadius, + const double theHeight) + : GeomAPI_Interface(newCyl(theLocation->impl(), theAxis->impl(), theRadius)), + myHeight(theHeight) +{ +} + +//================================================================================================= +std::shared_ptr GeomAPI_Cylinder::location() const +{ + const gp_Pnt& aCenter = MY_CYL->Location(); + return std::shared_ptr(new GeomAPI_Pnt(aCenter.X(), aCenter.Y(), aCenter.Z())); +} + +//================================================================================================= +std::shared_ptr GeomAPI_Cylinder::axis() const +{ + const gp_Dir& anAxis = MY_CYL->Position().Direction(); + return std::shared_ptr(new GeomAPI_Dir(anAxis.X(), anAxis.Y(), anAxis.Z())); +} + +//================================================================================================= +double GeomAPI_Cylinder::radius() const +{ + return MY_CYL->Radius(); +} + +//================================================================================================= +double GeomAPI_Cylinder::height() const +{ + return myHeight; +} + +//================================================================================================= +bool GeomAPI_Cylinder::isInfinite() const +{ + return Precision::IsInfinite(myHeight); +} diff --git a/src/GeomAPI/GeomAPI_Cylinder.h b/src/GeomAPI/GeomAPI_Cylinder.h new file mode 100644 index 000000000..025a8e0de --- /dev/null +++ b/src/GeomAPI/GeomAPI_Cylinder.h @@ -0,0 +1,70 @@ +// Copyright (C) 2018-20xx 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 GeomAPI_Cylinder_H_ +#define GeomAPI_Cylinder_H_ + +#include +#include + +class GeomAPI_Dir; +class GeomAPI_Pnt; + +/**\class GeomAPI_Cylinder + * \ingroup DataModel + * \brief Cylindrical surface in 3D + */ +class GeomAPI_Cylinder : public GeomAPI_Interface +{ +public: + /// Creation of infinite cylinder defined by location, axis and radius + GEOMAPI_EXPORT GeomAPI_Cylinder(const std::shared_ptr& theLocation, + const std::shared_ptr& theAxis, + const double theRadius); + + /// Creation of cylinder defined by location, axis, radius and height + GEOMAPI_EXPORT GeomAPI_Cylinder(const std::shared_ptr& theLocation, + const std::shared_ptr& theAxis, + const double theRadius, + const double theHeight); + + /// Return location of the cylinder + GEOMAPI_EXPORT std::shared_ptr location() const; + + /// Return axis of the cylinder + GEOMAPI_EXPORT std::shared_ptr axis() const; + + /// Return radius of the cylinder + GEOMAPI_EXPORT double radius() const; + + /// Return height of the cylinder or Precision::Infinite() if the cylinder is infinite + GEOMAPI_EXPORT double height() const; + + /// Return \c true is the cylinder is infinite + GEOMAPI_EXPORT bool isInfinite() const; + +private: + double myHeight; +}; + +//! Pointer on the object +typedef std::shared_ptr GeomCylinderPtr; + +#endif diff --git a/src/GeomAPI/GeomAPI_Ellipse.cpp b/src/GeomAPI/GeomAPI_Ellipse.cpp index 9c0926a13..23247f843 100644 --- a/src/GeomAPI/GeomAPI_Ellipse.cpp +++ b/src/GeomAPI/GeomAPI_Ellipse.cpp @@ -54,6 +54,13 @@ GeomPointPtr GeomAPI_Ellipse::secondFocus() const return std::shared_ptr(new GeomAPI_Pnt(aSecond.X(), aSecond.Y(), aSecond.Z())); } +std::shared_ptr GeomAPI_Ellipse::normal() const +{ + const gp_Ax1& anAxis = MY_ELIPS->Axis(); + const gp_Dir& aDir = anAxis.Direction(); + return std::shared_ptr(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z())); +} + double GeomAPI_Ellipse::minorRadius() const { return MY_ELIPS->MinorRadius(); diff --git a/src/GeomAPI/GeomAPI_Ellipse.h b/src/GeomAPI/GeomAPI_Ellipse.h index 02536b240..fa79bd022 100644 --- a/src/GeomAPI/GeomAPI_Ellipse.h +++ b/src/GeomAPI/GeomAPI_Ellipse.h @@ -28,8 +28,9 @@ #include #include -class GeomAPI_Pnt; class GeomAPI_Ax2; +class GeomAPI_Dir; +class GeomAPI_Pnt; /**\class GeomAPI_Ellipse @@ -62,6 +63,9 @@ public: /// Returns second focus of the ellipse GEOMAPI_EXPORT std::shared_ptr secondFocus() const; + /// Return orthogonal direction to the ellipse's plane + GEOMAPI_EXPORT std::shared_ptr normal() const; + /// Returns minor radius of the ellipse GEOMAPI_EXPORT double minorRadius() const; diff --git a/src/GeomAPI/GeomAPI_Face.cpp b/src/GeomAPI/GeomAPI_Face.cpp index 1541f26bc..89e39adfe 100644 --- a/src/GeomAPI/GeomAPI_Face.cpp +++ b/src/GeomAPI/GeomAPI_Face.cpp @@ -23,18 +23,33 @@ #include "GeomAPI_Dir.h" #include "GeomAPI_Pln.h" #include "GeomAPI_Pnt.h" +#include "GeomAPI_Sphere.h" +#include "GeomAPI_Cylinder.h" +#include "GeomAPI_Cone.h" +#include "GeomAPI_Torus.h" #include #include #include +#include #include +#include +#include #include #include +#include #include #include +#include #include #include +#include +#include +#include +#include + + GeomAPI_Face::GeomAPI_Face() : GeomAPI_Shape() { @@ -130,3 +145,89 @@ std::shared_ptr GeomAPI_Face::getPlane() const aResult = std::shared_ptr(new GeomAPI_Pln(aA, aB, aC, aD)); return aResult; } + +std::shared_ptr GeomAPI_Face::getSphere() const +{ + GeomSpherePtr aSphere; + + const TopoDS_Face& aFace = TopoDS::Face(impl()); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + if (aSurf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) { + gp_Sphere aSph = Handle(Geom_SphericalSurface)::DownCast(aSurf)->Sphere(); + const gp_Pnt& aCenter = aSph.Location(); + double aRadius = aSph.Radius(); + + GeomPointPtr aCenterPnt(new GeomAPI_Pnt(aCenter.X(), aCenter.Y(), aCenter.Z())); + aSphere = GeomSpherePtr(new GeomAPI_Sphere(aCenterPnt, aRadius)); + } + return aSphere; +} + +std::shared_ptr GeomAPI_Face::getCylinder() const +{ + GeomCylinderPtr aCylinder; + + const TopoDS_Face& aFace = TopoDS::Face(impl()); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + if (aSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) { + gp_Cylinder aCyl = Handle(Geom_CylindricalSurface)::DownCast(aSurf)->Cylinder(); + gp_Pnt aLoc = aCyl.Location(); + const gp_Dir& aDir = aCyl.Position().Direction(); + double aRadius = aCyl.Radius(); + + double aUMin, aUMax, aVMin, aVMax; + BRepTools::UVBounds(aFace, aUMin, aUMax, aVMin, aVMax); + double aHeight = aVMax - aVMin; + + aLoc.ChangeCoord() += aDir.XYZ() * aVMin; + GeomPointPtr aLocation(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); + GeomDirPtr aDirection(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z())); + aCylinder = GeomCylinderPtr(new GeomAPI_Cylinder(aLocation, aDirection, aRadius, aHeight)); + } + return aCylinder; +} + +std::shared_ptr GeomAPI_Face::getCone() const +{ + GeomConePtr aCone; + + const TopoDS_Face& aFace = TopoDS::Face(impl()); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + if (aSurf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) { + gp_Cone aCon = Handle(Geom_ConicalSurface)::DownCast(aSurf)->Cone(); + const gp_Pnt& aLoc = aCon.Location(); + const gp_Dir& aDir = aCon.Position().Direction(); + double aRadius1 = aCon.RefRadius(); + + double aUMin, aUMax, aVMin, aVMax; + BRepTools::UVBounds(aFace, aUMin, aUMax, aVMin, aVMax); + + double aSemiAngle = Abs(aCon.SemiAngle()); + double aRadius2 = aRadius1 - (aVMax - aVMin) * Sin(aSemiAngle); + + GeomPointPtr aLocation(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); + GeomDirPtr aDirection(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z())); + aCone = GeomConePtr(new GeomAPI_Cone(aLocation, aDirection, aSemiAngle, aRadius1, aRadius2)); + } + return aCone; +} + +std::shared_ptr GeomAPI_Face::getTorus() const +{ + GeomTorusPtr aTorus; + + const TopoDS_Face& aFace = TopoDS::Face(impl()); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + if (aSurf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) { + gp_Torus aTor = Handle(Geom_ToroidalSurface)::DownCast(aSurf)->Torus(); + const gp_Pnt& aLoc = aTor.Location(); + const gp_Dir& aDir = aTor.Position().Direction(); + double aMajorRadius = aTor.MajorRadius(); + double aMinorRadius = aTor.MinorRadius(); + + GeomPointPtr aCenter(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); + GeomDirPtr aDirection(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z())); + aTorus = GeomTorusPtr(new GeomAPI_Torus(aCenter, aDirection, aMajorRadius, aMinorRadius)); + } + return aTorus; +} diff --git a/src/GeomAPI/GeomAPI_Face.h b/src/GeomAPI/GeomAPI_Face.h index 477b91b90..3e654e916 100644 --- a/src/GeomAPI/GeomAPI_Face.h +++ b/src/GeomAPI/GeomAPI_Face.h @@ -24,6 +24,10 @@ #include class GeomAPI_Pln; +class GeomAPI_Sphere; +class GeomAPI_Cylinder; +class GeomAPI_Cone; +class GeomAPI_Torus; /**\class GeomAPI_Face * \ingroup DataModel @@ -51,6 +55,18 @@ public: /// Returns the base plane of the face (if it is planar) with location in the center of the face GEOMAPI_EXPORT std::shared_ptr getPlane() const; + + /// Returns sphere if the face is based on the spherical surface + GEOMAPI_EXPORT std::shared_ptr getSphere() const; + + /// Returns cylinder if the face is based on the cylindrical surface + GEOMAPI_EXPORT std::shared_ptr getCylinder() const; + + /// Returns cone if the face is based on the conical surface + GEOMAPI_EXPORT std::shared_ptr getCone() const; + + /// Returns torus if the face is based on the toroidal surface + GEOMAPI_EXPORT std::shared_ptr getTorus() const; }; //! Pointer on attribute object diff --git a/src/GeomAPI/GeomAPI_Shape.cpp b/src/GeomAPI/GeomAPI_Shape.cpp index 49cc0cb6b..fc736ac74 100644 --- a/src/GeomAPI/GeomAPI_Shape.cpp +++ b/src/GeomAPI/GeomAPI_Shape.cpp @@ -20,6 +20,13 @@ #include "GeomAPI_Shape.h" +#include +#include +#include +#include +#include +#include + #include #include #include @@ -115,6 +122,12 @@ bool GeomAPI_Shape::isFace() const return !aShape.IsNull() && aShape.ShapeType() == TopAbs_FACE; } +bool GeomAPI_Shape::isShell() const +{ + const TopoDS_Shape& aShape = const_cast(this)->impl(); + return !aShape.IsNull() && aShape.ShapeType() == TopAbs_SHELL; +} + bool GeomAPI_Shape::isCompound() const { const TopoDS_Shape& aShape = const_cast(this)->impl(); @@ -298,6 +311,89 @@ bool GeomAPI_Shape::isPlanar() const return false; } +std::shared_ptr GeomAPI_Shape::vertex() const +{ + GeomVertexPtr aVertex; + if (isVertex()) { + const TopoDS_Shape& aShape = const_cast(this)->impl(); + aVertex = GeomVertexPtr(new GeomAPI_Vertex); + aVertex->setImpl(new TopoDS_Shape(aShape)); + } + return aVertex; +} + +std::shared_ptr GeomAPI_Shape::edge() const +{ + GeomEdgePtr anEdge; + if (isEdge()) { + const TopoDS_Shape& aShape = const_cast(this)->impl(); + anEdge = GeomEdgePtr(new GeomAPI_Edge); + anEdge->setImpl(new TopoDS_Shape(aShape)); + } + return anEdge; +} + +std::shared_ptr GeomAPI_Shape::wire() const +{ + GeomWirePtr aWire; + if (isWire()) { + const TopoDS_Shape& aShape = const_cast(this)->impl(); + aWire = GeomWirePtr(new GeomAPI_Wire); + aWire->setImpl(new TopoDS_Shape(aShape)); + } + return aWire; +} + +std::shared_ptr GeomAPI_Shape::face() const +{ + GeomFacePtr aFace; + if (isFace()) { + const TopoDS_Shape& aShape = const_cast(this)->impl(); + aFace = GeomFacePtr(new GeomAPI_Face); + aFace->setImpl(new TopoDS_Shape(aShape)); + } + return aFace; +} + +std::shared_ptr GeomAPI_Shape::shell() const +{ + GeomShellPtr aShell; + if (isShell()) { + const TopoDS_Shape& aShape = const_cast(this)->impl(); + aShell = GeomShellPtr(new GeomAPI_Shell); + aShell->setImpl(new TopoDS_Shape(aShape)); + } + return aShell; +} + +std::shared_ptr GeomAPI_Shape::solid() const +{ + GeomSolidPtr aSolid; + if (isSolid()) { + const TopoDS_Shape& aShape = const_cast(this)->impl(); + aSolid = GeomSolidPtr(new GeomAPI_Solid); + aSolid->setImpl(new TopoDS_Shape(aShape)); + } + return aSolid; +} + +std::list > +GeomAPI_Shape::subShapes(ShapeType theSubShapeType) const +{ + ListOfShape aSubs; + const TopoDS_Shape& aShape = impl(); + if (aShape.IsNull()) + return aSubs; + + for (TopExp_Explorer anExp(aShape, (TopAbs_ShapeEnum)theSubShapeType); + anExp.More(); anExp.Next()) { + GeomShapePtr aSub(new GeomAPI_Shape); + aSub->setImpl(new TopoDS_Shape(anExp.Current())); + aSubs.push_back(aSub); + } + return aSubs; +} + GeomAPI_Shape::ShapeType GeomAPI_Shape::shapeType() const { const TopoDS_Shape& aShape = impl(); diff --git a/src/GeomAPI/GeomAPI_Shape.h b/src/GeomAPI/GeomAPI_Shape.h index 51cd414c8..66e6a2aad 100644 --- a/src/GeomAPI/GeomAPI_Shape.h +++ b/src/GeomAPI/GeomAPI_Shape.h @@ -27,6 +27,13 @@ #include #include +class GeomAPI_Vertex; +class GeomAPI_Edge; +class GeomAPI_Wire; +class GeomAPI_Face; +class GeomAPI_Shell; +class GeomAPI_Solid; + /**\class GeomAPI_Shape * \ingroup DataModel * \brief Interface to the topological shape object @@ -86,6 +93,10 @@ public: GEOMAPI_EXPORT virtual bool isFace() const; + /// Returns whether the shape is a shell + GEOMAPI_EXPORT + virtual bool isShell() const; + /// Returns whether the shape is a compound GEOMAPI_EXPORT virtual bool isCompound() const; @@ -110,6 +121,34 @@ public: GEOMAPI_EXPORT virtual bool isPlanar() const; + /// Returns vertex or empty shape + GEOMAPI_EXPORT + std::shared_ptr vertex() const; + + /// Returns edge or empty shape + GEOMAPI_EXPORT + std::shared_ptr edge() const; + + /// Returns wire or empty shape + GEOMAPI_EXPORT + std::shared_ptr wire() const; + + /// Returns face or empty shape + GEOMAPI_EXPORT + std::shared_ptr face() const; + + /// Returns shell or empty shape + GEOMAPI_EXPORT + std::shared_ptr shell() const; + + /// Returns solid or empty shape + GEOMAPI_EXPORT + std::shared_ptr solid() const; + + /// Returns list of sub-shapes of the given type + GEOMAPI_EXPORT + std::list > subShapes(ShapeType theSubShapeType) const; + /// Returns the shape type GEOMAPI_EXPORT virtual ShapeType shapeType() const; diff --git a/src/GeomAPI/GeomAPI_Shell.cpp b/src/GeomAPI/GeomAPI_Shell.cpp new file mode 100644 index 000000000..5b7713a96 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Shell.cpp @@ -0,0 +1,367 @@ +// Copyright (C) 2018-20xx 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 "GeomAPI_Shell.h" + +#include "GeomAPI_Ax3.h" +#include "GeomAPI_Box.h" +#include "GeomAPI_Cone.h" +#include "GeomAPI_Cylinder.h" +#include "GeomAPI_Face.h" +#include "GeomAPI_Pnt.h" +#include "GeomAPI_Sphere.h" +#include "GeomAPI_Torus.h" +#include "GeomAPI_Wire.h" +#include "GeomAPI_XYZ.h" + +#include +#include +#include +#include + +#include + +//================================================================================================= +GeomAPI_Shell::GeomAPI_Shell() +{ + TopoDS_Shell* aShell = new TopoDS_Shell(); + + BRep_Builder aBuilder; + aBuilder.MakeShell(*aShell); + + this->setImpl(aShell); +} + +//================================================================================================= +GeomAPI_Shell::GeomAPI_Shell(const std::shared_ptr& theShape) +{ + if (!theShape->isNull() && theShape->isShell()) { + setImpl(new TopoDS_Shape(theShape->impl())); + } +} + +//================================================================================================= +std::shared_ptr GeomAPI_Shell::getSphere() const +{ + bool isSphere = true; + bool isFirstFace = true; + GeomSpherePtr aSphere; + + for (TopExp_Explorer anExp(impl(), TopAbs_FACE); anExp.More(); anExp.Next()) { + GeomFacePtr aFace(new GeomAPI_Face); + aFace->setImpl(new TopoDS_Shape(anExp.Current())); + + GeomSpherePtr aCurSphere = aFace->getSphere(); + if (!aCurSphere) { + isSphere = false; + break; + } + + if (isFirstFace) { + aSphere = aCurSphere; + isFirstFace = false; + } + else if (aSphere->center()->distance(aCurSphere->center()) >= Precision::Confusion() || + Abs(aSphere->radius() - aCurSphere->radius()) >= Precision::Confusion()) { + isSphere = false; + break; + } + } + + return isSphere ? aSphere : GeomSpherePtr(); +} + +//================================================================================================= +std::shared_ptr GeomAPI_Shell::getCylinder() const +{ + bool isCylinder = true; + bool isFirstFace = true; + + GeomPointPtr aLocation; + GeomDirPtr anAxis; + double aRadius; + double aHeight; + + for (TopExp_Explorer anExp(impl(), TopAbs_FACE); anExp.More(); anExp.Next()) { + GeomFacePtr aFace(new GeomAPI_Face); + aFace->setImpl(new TopoDS_Shape(anExp.Current())); + + GeomCylinderPtr aCurCyl = aFace->getCylinder(); + if (!aCurCyl) { + isCylinder = false; + break; + } + + if (isFirstFace) { + aLocation = aCurCyl->location(); + anAxis = aCurCyl->axis(); + aRadius = aCurCyl->radius(); + aHeight = aCurCyl->height(); + isFirstFace = false; + } + else { + // compare radii + if (Abs(aRadius - aCurCyl->radius()) >= Precision::Confusion() || + // check directions are collinear + !anAxis->isParallel(aCurCyl->axis()) || + // check current center is on the main axis + anAxis->xyz()->cross(aLocation->xyz()->decreased(aCurCyl->location()->xyz()) + )->squareModulus() >= Precision::SquareConfusion()) { + isCylinder = false; + break; + } + + double aMinHeight = 0.0; + double aMaxHeight = aHeight; + + std::shared_ptr aCurCylLoc = aCurCyl->location()->xyz(); + std::shared_ptr aCurCylLocHeight = + aCurCylLoc->added(aCurCyl->axis()->xyz()->multiplied(aCurCyl->height())); + + std::shared_ptr anAxisXYZ = anAxis->xyz(); + + double aDist = anAxisXYZ->dot(aCurCylLoc->decreased(aLocation->xyz())); + if (aDist < aMinHeight) + aMinHeight = aDist; + else if (aDist > aMaxHeight) + aMaxHeight = aDist; + + aDist = anAxisXYZ->dot(aCurCylLocHeight->decreased(aLocation->xyz())); + if (aDist < aMinHeight) + aMinHeight = aDist; + else if (aDist > aMaxHeight) + aMaxHeight = aDist; + + if (aMinHeight < 0.0) { + // move location of full cylinder + aLocation->setX(aLocation->x() + aMinHeight * anAxis->x()); + aLocation->setY(aLocation->y() + aMinHeight * anAxis->y()); + aLocation->setZ(aLocation->z() + aMinHeight * anAxis->z()); + } + + aHeight = aMaxHeight - aMinHeight; + } + } + + GeomCylinderPtr aCylinder; + if (isCylinder) + aCylinder = GeomCylinderPtr(new GeomAPI_Cylinder(aLocation, anAxis, aRadius, aHeight)); + return aCylinder; +} + +//================================================================================================= +std::shared_ptr GeomAPI_Shell::getCone() const +{ + bool isCone = true; + bool isFirstFace = true; + + GeomPointPtr anApex; + GeomDirPtr anAxis; + double aSemiAngle, aCosSemiAngle; + double aHeight1, aHeight2; + + for (TopExp_Explorer anExp(impl(), TopAbs_FACE); anExp.More(); anExp.Next()) { + GeomFacePtr aFace(new GeomAPI_Face); + aFace->setImpl(new TopoDS_Shape(anExp.Current())); + + GeomConePtr aCurCone = aFace->getCone(); + if (!aCurCone) { + isCone = false; + break; + } + + if (isFirstFace) { + anApex = aCurCone->apex(); + anAxis = aCurCone->axis(); + aSemiAngle = aCurCone->semiAngle(); + aCosSemiAngle = Cos(aSemiAngle); + aHeight1 = aCurCone->radius1() * aCosSemiAngle; + aHeight2 = aCurCone->radius2() * aCosSemiAngle; + isFirstFace = false; + } + else { + // check equal locations + if (anApex->distance(aCurCone->apex()) >= Precision::Confusion() || + // check equal angles + Abs(aSemiAngle - aCurCone->semiAngle()) >= Precision::Confusion() || + // check directions are collinear + !anAxis->isParallel(aCurCone->axis())) { + isCone = false; + break; + } + + double aSign = anAxis->dot(aCurCone->axis()); + double aCurSemiAngle = aCurCone->semiAngle(); + double aCosCurSemiAngle = Cos(aSemiAngle); + + double aH = aCurCone->radius1() * aCosCurSemiAngle * aSign; + if (aH < aHeight1) + aHeight1 = aH; + else if (aH > aHeight2) + aHeight2 = aH; + + aH = aCurCone->radius2() * aCosCurSemiAngle * aSign; + if (aH < aHeight1) + aHeight1 = aH; + else if (aH > aHeight2) + aHeight2 = aH; + } + } + + GeomConePtr aCone; + if (isCone) { + GeomPointPtr aLocation(new GeomAPI_Pnt( + anApex->xyz()->added(anAxis->xyz()->multiplied(aHeight1)))); + double aRadius1 = aHeight1 * Tan(aSemiAngle); + double aRadius2 = aHeight2 * Tan(aSemiAngle); + + aCone = GeomConePtr(new GeomAPI_Cone(aLocation, anAxis, aSemiAngle, aRadius1, aRadius2)); + } + return aCone; +} + +//================================================================================================= +std::shared_ptr GeomAPI_Shell::getTorus() const +{ + bool isTorus = true; + bool isFirstFace = true; + GeomTorusPtr aTorus; + + for (TopExp_Explorer anExp(impl(), TopAbs_FACE); anExp.More(); anExp.Next()) { + GeomFacePtr aFace(new GeomAPI_Face); + aFace->setImpl(new TopoDS_Shape(anExp.Current())); + + GeomTorusPtr aCurTorus = aFace->getTorus(); + if (!aCurTorus) { + isTorus = false; + break; + } + + if (isFirstFace) { + aTorus = aCurTorus; + isFirstFace = false; + } + else { + // compare radii + if (Abs(aTorus->majorRadius() - aCurTorus->majorRadius()) >= Precision::Confusion() || + Abs(aTorus->minorRadius() - aCurTorus->minorRadius()) >= Precision::Confusion() || + // check equal centers + aTorus->center()->distance(aCurTorus->center()) >= Precision::SquareConfusion() || + // check directions are collinear + !aTorus->direction()->isParallel(aCurTorus->direction())) { + isTorus = false; + break; + } + } + } + + return isTorus ? aTorus : GeomTorusPtr(); +} + +//================================================================================================= +std::shared_ptr GeomAPI_Shell::getParallelepiped() const +{ + struct Plane + { + std::shared_ptr myAxes; + double myWidth; + double myDepth; + double myHeight; + } aPlanes[6]; + std::map aParallelPlanes; + + int aNbPlanes = 0; + for (TopExp_Explorer anExp(impl(), TopAbs_WIRE); + anExp.More() && aNbPlanes < 6; anExp.Next()) { + GeomWirePtr aWire(new GeomAPI_Wire); + aWire->setImpl(new TopoDS_Shape(anExp.Current())); + + std::list aCorners; + if (aWire->isRectangle(aCorners)) { + // convert rectangle to plane with dimensions + GeomPointPtr anOrigin = aCorners.front(); + aCorners.pop_front(); + + GeomPointPtr aFront = aCorners.front(); + GeomPointPtr aBack = aCorners.back(); + + aPlanes[aNbPlanes].myWidth = aBack->distance(anOrigin); + aPlanes[aNbPlanes].myDepth = aFront->distance(anOrigin); + aPlanes[aNbPlanes].myHeight = Precision::Infinite(); + + GeomDirPtr aDX(new GeomAPI_Dir(aBack->x() - anOrigin->x(), + aBack->y() - anOrigin->y(), + aBack->z() - anOrigin->z())); + GeomDirPtr aDY(new GeomAPI_Dir(aFront->x() - anOrigin->x(), + aFront->y() - anOrigin->y(), + aFront->z() - anOrigin->z())); + GeomDirPtr aDZ(new GeomAPI_Dir(aDX->cross(aDY))); + aPlanes[aNbPlanes].myAxes = + std::shared_ptr(new GeomAPI_Ax3(anOrigin, aDX, aDZ)); + + // find parallel plane + for (int i = 0; i < aNbPlanes; ++i) { + double aDot = aPlanes[i].myAxes->normal()->dot(aDZ); + if (Abs(aDot + 1.0) < Precision::Angular()) { + if (aParallelPlanes.find(i) == aParallelPlanes.end()) + aParallelPlanes[i] = aNbPlanes; + else + break; // parallel planes already exist + } + } + + ++aNbPlanes; + + } else + break; + } + + if (aNbPlanes != 6 || aParallelPlanes.size() != 3) // not a parallelepiped + return GeomBoxPtr(); + + // calculate heights for planes computed by rectangles + for (std::map::iterator it = aParallelPlanes.begin(); + it != aParallelPlanes.end(); ++it) { + GeomDirPtr aNormal = aPlanes[it->first].myAxes->normal(); + GeomPointPtr anOrigin = aPlanes[it->first].myAxes->origin(); + GeomPointPtr aNeighbor = aPlanes[it->second].myAxes->origin(); + + aPlanes[it->first].myHeight = + aPlanes[it->second].myHeight = + aNormal->xyz()->dot( aNeighbor->xyz()->decreased(anOrigin->xyz()) ); + } + + // check if the box is oriented in the main axes + int anIndex = 0; + for (int i = 0; i < 6; ++i) { + if (Abs(aPlanes[i].myAxes->dirX()->x() - 1.) < Precision::Angular() && + Abs(aPlanes[i].myAxes->normal()->z() - 1.) < Precision::Angular()) { + anIndex = i; + break; + } + } + + // construct a box + GeomBoxPtr aBox(new GeomAPI_Box(aPlanes[anIndex].myAxes, + aPlanes[anIndex].myWidth, + aPlanes[anIndex].myDepth, + aPlanes[anIndex].myHeight)); + return aBox; +} diff --git a/src/GeomAPI/GeomAPI_Shell.h b/src/GeomAPI/GeomAPI_Shell.h new file mode 100644 index 000000000..91b6a313b --- /dev/null +++ b/src/GeomAPI/GeomAPI_Shell.h @@ -0,0 +1,66 @@ +// Copyright (C) 2018-20xx 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 GeomAPI_Shell_H_ +#define GeomAPI_Shell_H_ + +#include + +class GeomAPI_Sphere; +class GeomAPI_Cylinder; +class GeomAPI_Cone; +class GeomAPI_Torus; +class GeomAPI_Box; + +/// \class GeomAPI_Shell +/// \ingroup DataModel +/// \brief Interface to the shell object +class GeomAPI_Shell: public GeomAPI_Shape +{ +public: + /// Makes an undefined shell. + GEOMAPI_EXPORT GeomAPI_Shell(); + + /// Creation of shell by the shell-shape + GEOMAPI_EXPORT GeomAPI_Shell(const std::shared_ptr& theShape); + + /// Returns sphere if the shell consists only of faces + /// which are based on the same spherical surface + GEOMAPI_EXPORT std::shared_ptr getSphere() const; + + /// Returns cylinder if the shell consists only of faces + /// which are based on the same cylindrical surface + GEOMAPI_EXPORT std::shared_ptr getCylinder() const; + + /// Returns cone if the shell consists only of faces + /// which are based on the same conical surface + GEOMAPI_EXPORT std::shared_ptr getCone() const; + + /// Returns torus if the shell consists only of faces + /// which are based on the same toroidal surface + GEOMAPI_EXPORT std::shared_ptr getTorus() const; + + /// Returns box if the shell consists of 6 rectangular faces composing a box + GEOMAPI_EXPORT std::shared_ptr getParallelepiped() const; +}; + +typedef std::shared_ptr GeomShellPtr; + +#endif diff --git a/src/GeomAPI/GeomAPI_Solid.cpp b/src/GeomAPI/GeomAPI_Solid.cpp new file mode 100644 index 000000000..0f377f2c2 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Solid.cpp @@ -0,0 +1,300 @@ +// Copyright (C) 2018-20xx 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 "GeomAPI_Solid.h" + +#include "GeomAPI_Box.h" +#include "GeomAPI_Cone.h" +#include "GeomAPI_Cylinder.h" +#include "GeomAPI_Dir.h" +#include "GeomAPI_Face.h" +#include "GeomAPI_Pln.h" +#include "GeomAPI_Pnt.h" +#include "GeomAPI_Shell.h" +#include "GeomAPI_Sphere.h" +#include "GeomAPI_Torus.h" +#include "GeomAPI_XYZ.h" + +#include +#include +#include +#include + +//================================================================================================== +GeomAPI_Solid::GeomAPI_Solid() : GeomAPI_Shape() +{ +} + +//================================================================================================== +GeomAPI_Solid::GeomAPI_Solid(const std::shared_ptr& theShape) +{ + if (!theShape->isNull() && theShape->isSolid()) { + setImpl(new TopoDS_Shape(theShape->impl())); + } +} + +//================================================================================================== +std::shared_ptr GeomAPI_Solid::getSphere() const +{ + GeomSpherePtr aSphere; + ListOfShape aShells = subShapes(SHELL); + if (aShells.size() == 1) + aSphere = aShells.front()->shell()->getSphere(); + return aSphere; +} + +//================================================================================================== +std::shared_ptr GeomAPI_Solid::getCylinder() const +{ + bool isCylinder = false; + + GeomPointPtr aLocation; + GeomDirPtr anAxis; + double aRadius; + double aHeight; + + GeomPlanePtr aCaps[2]; + + for (TopExp_Explorer anExp(impl(), TopAbs_FACE); anExp.More(); anExp.Next()) { + GeomFacePtr aFace(new GeomAPI_Face); + aFace->setImpl(new TopoDS_Shape(anExp.Current())); + + GeomCylinderPtr aCurCyl = aFace->getCylinder(); + if (aCurCyl) { + if (isCylinder) { // at least one cylindrical face is found + // compare radii + if (Abs(aRadius - aCurCyl->radius()) >= Precision::Confusion() || + // check directions are collinear + !anAxis->isParallel(aCurCyl->axis()) || + // check current center is on the main axis + anAxis->xyz()->cross(aLocation->xyz()->decreased(aCurCyl->location()->xyz()) + )->squareModulus() >= Precision::SquareConfusion()) { + isCylinder = false; + break; + } + } + else { // first cylinder is found + aLocation = aCurCyl->location(); + if (anAxis) { + // the plane is found => compare directions + if (!anAxis->isParallel(aCurCyl->axis())) + break; + } + else + anAxis = aCurCyl->axis(); + aRadius = aCurCyl->radius(); + aHeight = aCurCyl->height(); + isCylinder = true; + } + } + else { + // check the face is planar + bool isPlaneApplicable = false; + GeomPlanePtr aCurPln = aFace->getPlane(); + if (aCurPln) { + // verify the plane is already exists + int aLastPlanIndex = 0; + while (aLastPlanIndex < 2) { + if (!aCaps[aLastPlanIndex]) { + // add new plane + aCaps[aLastPlanIndex] = aCurPln; + break; + } + if (aCaps[aLastPlanIndex]->isCoincident(aCurPln)) + break; + ++aLastPlanIndex; + } + + isPlaneApplicable = aLastPlanIndex < 2; + } + + if (isPlaneApplicable) { + if (!anAxis) // no cylinder is found, store the normal as further cylinder's axis + anAxis = aCurPln->direction(); + } + else { + isCylinder = false; + break; + } + } + } + + isCylinder = isCylinder && aCaps[0] && aCaps[1] && + aCaps[0]->direction()->isParallel(anAxis) && + aCaps[1]->direction()->isParallel(anAxis); + + GeomCylinderPtr aCylinder; + if (isCylinder) { + // intersect planes with cylinder's axis + std::shared_ptr anAxisXYZ = anAxis->xyz(); + std::shared_ptr aLocationXYZ = aLocation->xyz(); + double aParam0 = anAxisXYZ->dot( aCaps[0]->location()->xyz()->decreased(aLocationXYZ) ); + double aParam1 = anAxisXYZ->dot( aCaps[1]->location()->xyz()->decreased(aLocationXYZ) ); + if (aParam0 > aParam1 + Precision::Confusion()) { + double tmp = aParam0; + aParam0 = aParam1; + aParam1 = tmp; + } + + // update location of cylinder to be coincident with one of planes + aLocation->setX(aLocation->x() + aParam0 * anAxis->x()); + aLocation->setY(aLocation->y() + aParam0 * anAxis->y()); + aLocation->setZ(aLocation->z() + aParam0 * anAxis->z()); + + aHeight = aParam1 - aParam0; + + aCylinder = GeomCylinderPtr(new GeomAPI_Cylinder(aLocation, anAxis, aRadius, aHeight)); + } + return aCylinder; +} + +//================================================================================================== +std::shared_ptr GeomAPI_Solid::getCone() const +{ + bool isCone = false; + + GeomPointPtr anApex; + GeomDirPtr anAxis; + double aSemiAngle; + double aHeight; + + GeomPlanePtr aCaps[2]; + + for (TopExp_Explorer anExp(impl(), TopAbs_FACE); anExp.More(); anExp.Next()) { + GeomFacePtr aFace(new GeomAPI_Face); + aFace->setImpl(new TopoDS_Shape(anExp.Current())); + + GeomConePtr aCurCone = aFace->getCone(); + if (aCurCone) { + if (isCone) { // at least one conical face is found + // check equal apexes + if (anApex->distance(aCurCone->apex()) >= Precision::Confusion() || + // check semi-angle + Abs(aSemiAngle - aCurCone->semiAngle() >= Precision::Confusion()) || + // check axes are collinear + !anAxis->isParallel(aCurCone->axis())) { + isCone = false; + break; + } + } + else { // first cone is found + anApex = aCurCone->apex(); + if (anAxis) { + // the plane is found => compare directions + if (!anAxis->isParallel(aCurCone->axis())) + break; + } + else + anAxis = aCurCone->axis(); + aSemiAngle = aCurCone->semiAngle(); + aHeight = aCurCone->height(); + isCone = true; + } + } + else { + // check the face is planar + bool isPlaneApplicable = false; + GeomPlanePtr aCurPln = aFace->getPlane(); + if (aCurPln) { + // verify the plane is already exists + int aLastPlanIndex = 0; + while (aLastPlanIndex < 2) { + if (!aCaps[aLastPlanIndex]) { + // add new plane + aCaps[aLastPlanIndex] = aCurPln; + break; + } + if (aCaps[aLastPlanIndex]->isCoincident(aCurPln)) + break; + ++aLastPlanIndex; + } + + isPlaneApplicable = aLastPlanIndex < 2; + } + + if (isPlaneApplicable) { + if (!anAxis) // no cone is found, store the normal as further cone's axis + anAxis = aCurPln->direction(); + } + else { + isCone = false; + break; + } + } + } + + isCone = isCone && aCaps[0] && aCaps[0]->direction()->isParallel(anAxis); + if (isCone && aCaps[1]) // cone map have only one cap, if it is bounded by the apex + isCone = aCaps[1]->direction()->isParallel(anAxis); + + GeomConePtr aCone; + if (isCone) { + // intersect planes with cone's axis + std::shared_ptr anAxisXYZ = anAxis->xyz(); + std::shared_ptr anApexXYZ = anApex->xyz(); + double aParam0 = anAxisXYZ->dot(aCaps[0]->location()->xyz()->decreased(anApexXYZ)); + double aParam1 = + aCaps[1] ? anAxisXYZ->dot(aCaps[1]->location()->xyz()->decreased(anApexXYZ)) : 0.0; + if (aParam0 <= 0.0 && aParam1 <= 0.0) { + // reverse axis to make smaller cap be the first + anAxis->reverse(); + aParam0 = -aParam0; + aParam1 = -aParam1; + } + if (aParam0 > aParam1 + Precision::Confusion()) { + double tmp = aParam0; + aParam0 = aParam1; + aParam1 = tmp; + } + + // calculate location of cone to be coincident with one of planes + GeomPointPtr aLocation(new GeomAPI_Pnt( + anApex->x() + aParam0 * anAxis->x(), + anApex->y() + aParam0 * anAxis->y(), + anApex->z() + aParam0 * anAxis->z())); + + // calculate radii of caps + aParam0 /= Cos(aSemiAngle); + aParam1 /= Cos(aSemiAngle); + + aCone = GeomConePtr(new GeomAPI_Cone(aLocation, anAxis, aSemiAngle, aParam0, aParam1)); + } + return aCone; +} + +//================================================================================================== +std::shared_ptr GeomAPI_Solid::getTorus() const +{ + GeomTorusPtr aTorus; + ListOfShape aShells = subShapes(SHELL); + if (aShells.size() == 1) + aTorus = aShells.front()->shell()->getTorus(); + return aTorus; +} + +//================================================================================================== +std::shared_ptr GeomAPI_Solid::getParallelepiped() const +{ + GeomBoxPtr aBox; + ListOfShape aShells = subShapes(SHELL); + if (aShells.size() == 1) + aBox = aShells.front()->shell()->getParallelepiped(); + return aBox; +} diff --git a/src/GeomAPI/GeomAPI_Solid.h b/src/GeomAPI/GeomAPI_Solid.h new file mode 100644 index 000000000..a81828c8e --- /dev/null +++ b/src/GeomAPI/GeomAPI_Solid.h @@ -0,0 +1,66 @@ +// Copyright (C) 2018-20xx 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 GeomAPI_Solid_H_ +#define GeomAPI_Solid_H_ + +#include + +class GeomAPI_Sphere; +class GeomAPI_Cylinder; +class GeomAPI_Cone; +class GeomAPI_Torus; +class GeomAPI_Box; + +/// \class GeomAPI_Solid +/// \ingroup DataModel +/// \brief Interface to the solid object +class GeomAPI_Solid: public GeomAPI_Shape +{ +public: + /// Makes an undefined solid. + GEOMAPI_EXPORT GeomAPI_Solid(); + + /// Creation of solid by the solid-shape + GEOMAPI_EXPORT GeomAPI_Solid(const std::shared_ptr& theShape); + + /// Returns sphere if the solid is only bounded by faces + /// which are based on the same spherical surface + GEOMAPI_EXPORT std::shared_ptr getSphere() const; + + /// Returns cylinder if the solid is bounded by faces based on the same cylindrical surface + /// and a pair of parallel planar faces + GEOMAPI_EXPORT std::shared_ptr getCylinder() const; + + /// Returns cone if the solid is bounded by faces based on the same conical surface + /// and a pair of parallel planar faces + GEOMAPI_EXPORT std::shared_ptr getCone() const; + + /// Returns torus if the shell solid is only bounded by faces + /// which are based on the same toroidal surface + GEOMAPI_EXPORT std::shared_ptr getTorus() const; + + /// Returns box if the solid is bounded by 6 rectangular faces composing a box + GEOMAPI_EXPORT std::shared_ptr getParallelepiped() const; +}; + +typedef std::shared_ptr GeomSolidPtr; + +#endif diff --git a/src/GeomAPI/GeomAPI_Sphere.cpp b/src/GeomAPI/GeomAPI_Sphere.cpp new file mode 100644 index 000000000..72e9eb534 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Sphere.cpp @@ -0,0 +1,50 @@ +// Copyright (C) 2018-20xx 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 +#include + +#include + +#define MY_SPHERE implPtr() + +static gp_Sphere* newSphere(const gp_Pnt& theCenter, const double theRadius) +{ + return new gp_Sphere(gp_Ax3(theCenter, gp::DZ()), theRadius); +} + +//================================================================================================= +GeomAPI_Sphere::GeomAPI_Sphere(const std::shared_ptr& theCenter, double theRadius) + : GeomAPI_Interface(newSphere(theCenter->impl(), theRadius)) +{ +} + +//================================================================================================= +const std::shared_ptr GeomAPI_Sphere::center() const +{ + const gp_Pnt& aCenter = MY_SPHERE->Location(); + return std::shared_ptr(new GeomAPI_Pnt(aCenter.X(), aCenter.Y(), aCenter.Z())); +} + +//================================================================================================= +double GeomAPI_Sphere::radius() const +{ + return MY_SPHERE->Radius(); +} diff --git a/src/GeomAPI/GeomAPI_Sphere.h b/src/GeomAPI/GeomAPI_Sphere.h new file mode 100644 index 000000000..4217733ac --- /dev/null +++ b/src/GeomAPI/GeomAPI_Sphere.h @@ -0,0 +1,50 @@ +// Copyright (C) 2018-20xx 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 GeomAPI_Sphere_H_ +#define GeomAPI_Sphere_H_ + +#include +#include + +class GeomAPI_Pnt; + +/**\class GeomAPI_Sphere + * \ingroup DataModel + * \brief Spherical surface in 3D + */ +class GeomAPI_Sphere : public GeomAPI_Interface +{ +public: + + /// Construct sphere by center and radius + GEOMAPI_EXPORT GeomAPI_Sphere(const std::shared_ptr& theCenter, double theRadius); + + /// Return center of the sphere + GEOMAPI_EXPORT const std::shared_ptr center() const; + + /// Return radius of the sphere + GEOMAPI_EXPORT double radius() const; +}; + +//! Pointer on the object +typedef std::shared_ptr GeomSpherePtr; + +#endif diff --git a/src/GeomAPI/GeomAPI_Torus.cpp b/src/GeomAPI/GeomAPI_Torus.cpp new file mode 100644 index 000000000..b6da884e9 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Torus.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2018-20xx 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 + +#include +#include + +#include + +#define MY_TORUS implPtr() + +static gp_Torus* newTorus(const gp_Pnt& theCenter, const gp_Dir& theDir, + const double theMajorRadius, const double theMinorRadius) +{ + return new gp_Torus(gp_Ax3(theCenter, theDir), theMajorRadius, theMinorRadius); +} + +//================================================================================================= +GeomAPI_Torus::GeomAPI_Torus(const std::shared_ptr& theCenter, + const std::shared_ptr& theDir, + const double theMajorRadius, + const double theMinorRadius) + : GeomAPI_Interface( + newTorus(theCenter->impl(), theDir->impl(), theMajorRadius, theMinorRadius)) +{ +} + +//================================================================================================= +std::shared_ptr GeomAPI_Torus::center() const +{ + const gp_Pnt& aCenter = MY_TORUS->Location(); + return std::shared_ptr(new GeomAPI_Pnt(aCenter.X(), aCenter.Y(), aCenter.Z())); +} + +//================================================================================================= +std::shared_ptr GeomAPI_Torus::direction() const +{ + const gp_Dir& aDir = MY_TORUS->Axis().Direction(); + return std::shared_ptr(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z())); +} + +//================================================================================================= +double GeomAPI_Torus::majorRadius() const +{ + return MY_TORUS->MajorRadius(); +} + +//================================================================================================= +double GeomAPI_Torus::minorRadius() const +{ + return MY_TORUS->MinorRadius(); +} diff --git a/src/GeomAPI/GeomAPI_Torus.h b/src/GeomAPI/GeomAPI_Torus.h new file mode 100644 index 000000000..c8db45bf8 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Torus.h @@ -0,0 +1,59 @@ +// Copyright (C) 2018-20xx 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 GeomAPI_Torus_H_ +#define GeomAPI_Torus_H_ + +#include +#include + +class GeomAPI_Dir; +class GeomAPI_Pnt; + +/**\class GeomAPI_Torus + * \ingroup DataModel + * \brief Toroidal surface in 3D + */ +class GeomAPI_Torus : public GeomAPI_Interface +{ +public: + /// Creation of torus defined by center point, direction, major and minor radii + GEOMAPI_EXPORT GeomAPI_Torus(const std::shared_ptr& theCenter, + const std::shared_ptr& theDir, + const double theMajorRadius, + const double theMinorRadius); + + /// Return center of the torus + GEOMAPI_EXPORT std::shared_ptr center() const; + + /// Return direction of the torus + GEOMAPI_EXPORT std::shared_ptr direction() const; + + /// Return major radius of the torus + GEOMAPI_EXPORT double majorRadius() const; + + /// Return minor radius of the torus + GEOMAPI_EXPORT double minorRadius() const; +}; + +//! Pointer on the object +typedef std::shared_ptr GeomTorusPtr; + +#endif diff --git a/src/GeomAPI/GeomAPI_Wire.cpp b/src/GeomAPI/GeomAPI_Wire.cpp index e750f3ac5..32df6d6bb 100644 --- a/src/GeomAPI/GeomAPI_Wire.cpp +++ b/src/GeomAPI/GeomAPI_Wire.cpp @@ -19,8 +19,14 @@ // #include "GeomAPI_Wire.h" +#include "GeomAPI_Pnt.h" #include +#include +#include +#include +#include +#include #include //================================================================================================== @@ -41,3 +47,69 @@ GeomAPI_Wire::GeomAPI_Wire(const std::shared_ptr& theShape) setImpl(new TopoDS_Shape(theShape->impl())); } } + +//================================================================================================== +bool GeomAPI_Wire::isClosed() const +{ + return BRep_Tool::IsClosed(impl()); +} + +//================================================================================================== +bool GeomAPI_Wire::isPolygon(std::list& thePoints) const +{ + const TopoDS_Wire& aWire = TopoDS::Wire(impl()); + + bool isPolygon = true; + const Handle(Standard_Type)& aLineType = STANDARD_TYPE(Geom_Line); + for (BRepTools_WireExplorer anExp(aWire); anExp.More() && isPolygon; anExp.Next()) { + const TopoDS_Edge& anEdge = anExp.Current(); + double aT1, aT2; + Handle(Geom_Curve) aC3D = BRep_Tool::Curve(anEdge, aT1, aT2); + if (!aC3D.IsNull() && aC3D->IsKind(aLineType)) { + gp_Pnt aCorner = BRep_Tool::Pnt(anExp.CurrentVertex()); + thePoints.push_back(GeomPointPtr(new GeomAPI_Pnt(aCorner.X(), aCorner.Y(), aCorner.Z()))); + } + else + isPolygon = false; + } + + if (!isPolygon) + thePoints.clear(); + return isPolygon; +} + +//================================================================================================== +bool GeomAPI_Wire::isRectangle(std::list& thePoints) const +{ + const TopoDS_Wire& aWire = TopoDS::Wire(impl()); + const Handle(Standard_Type)& aLineType = STANDARD_TYPE(Geom_Line); + + gp_XYZ aPrevDir(0, 0, 0); + + for (BRepTools_WireExplorer anExp(aWire); anExp.More(); anExp.Next()) { + const TopoDS_Edge& anEdge = anExp.Current(); + double aT1, aT2; + Handle(Geom_Curve) aC3D = BRep_Tool::Curve(anEdge, aT1, aT2); + if (!aC3D.IsNull() && aC3D->IsKind(aLineType)) { + gp_Pnt aCorner = BRep_Tool::Pnt(anExp.CurrentVertex()); + thePoints.push_back(GeomPointPtr(new GeomAPI_Pnt(aCorner.X(), aCorner.Y(), aCorner.Z()))); + } + else + return false; + + if (thePoints.size() > 4) + return false; + + // collect length of the edge + gp_Pnt aStart = aC3D->Value(aT1); + gp_Pnt aEnd = aC3D->Value(aT2); + + // check the edge is orthogonal to the previous + gp_XYZ aCurDir = (aEnd.XYZ() - aStart.XYZ()).Normalized(); + if (aPrevDir.Dot(aCurDir) < Precision::Confusion()) + aPrevDir = aCurDir; + else + return false; + } + return true; +} diff --git a/src/GeomAPI/GeomAPI_Wire.h b/src/GeomAPI/GeomAPI_Wire.h index 888e9b19c..c79283d8e 100644 --- a/src/GeomAPI/GeomAPI_Wire.h +++ b/src/GeomAPI/GeomAPI_Wire.h @@ -23,6 +23,8 @@ #include "GeomAPI_Shape.h" +class GeomAPI_Pnt; + /// \class GeomAPI_Wire /// \ingroup DataModel /// \brief Interface to the wire object @@ -34,6 +36,17 @@ public: /// Creation of wire by the wire-shape GEOMAPI_EXPORT GeomAPI_Wire(const std::shared_ptr& theShape); + + /// Returns "closed" status of the wire + GEOMAPI_EXPORT bool isClosed() const; + + /// Returns \c true if the wire is a polygon + /// \param[out] thePoints vertices of the polygon + GEOMAPI_EXPORT bool isPolygon(std::list >& thePoints) const; + + /// Returns \c true if the wire is a rectangle + /// \param[out] thePoints corners of the rectangle + GEOMAPI_EXPORT bool isRectangle(std::list >& thePoints) const; }; typedef std::shared_ptr GeomWirePtr; diff --git a/src/GeomAPI/GeomAPI_swig.h b/src/GeomAPI/GeomAPI_swig.h index fa515a4fd..a7712b0ed 100644 --- a/src/GeomAPI/GeomAPI_swig.h +++ b/src/GeomAPI/GeomAPI_swig.h @@ -26,9 +26,12 @@ #include "GeomAPI_Ax1.h" #include "GeomAPI_Ax2.h" #include "GeomAPI_Ax3.h" + #include "GeomAPI_Box.h" #include "GeomAPI_Circ.h" #include "GeomAPI_Circ2d.h" + #include "GeomAPI_Cone.h" #include "GeomAPI_Curve.h" + #include "GeomAPI_Cylinder.h" #include "GeomAPI_DataMapOfShapeMapOfShapes.h" #include "GeomAPI_DataMapOfShapeShape.h" #include "GeomAPI_Dir.h" @@ -47,6 +50,10 @@ #include "GeomAPI_Shape.h" #include "GeomAPI_ShapeExplorer.h" #include "GeomAPI_ShapeIterator.h" + #include "GeomAPI_Shell.h" + #include "GeomAPI_Solid.h" + #include "GeomAPI_Sphere.h" + #include "GeomAPI_Torus.h" #include "GeomAPI_Vertex.h" #include "GeomAPI_XY.h" #include "GeomAPI_XYZ.h" diff --git a/src/XGUI/XGUI_InspectionPanel.cpp b/src/XGUI/XGUI_InspectionPanel.cpp index 682f74c5f..16ef5c164 100644 --- a/src/XGUI/XGUI_InspectionPanel.cpp +++ b/src/XGUI/XGUI_InspectionPanel.cpp @@ -28,6 +28,23 @@ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -36,33 +53,59 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include // CAREFUL ! position of this file is critic +// ================ Auxiliary functions ================ +#define TITLE(val) ("" + (val) + "") + +static void appendPointToParameters(const QString& thePointTitle, + const GeomPointPtr& theCoord, + QString& theParams) +{ + theParams += TITLE(thePointTitle) + + "
X: " + QString::number(theCoord->x()) + + "
Y: " + QString::number(theCoord->y()) + + "
Z: " + QString::number(theCoord->z()) + + "
"; +} + +static void appendDirToParameters(const QString& theDirTitle, + const GeomDirPtr& theDirection, + QString& theParams) +{ + theParams += TITLE(theDirTitle) + + "
DX: " + QString::number(theDirection->x()) + + "
DY: " + QString::number(theDirection->y()) + + "
DZ: " + QString::number(theDirection->z()) + + "
"; +} + +static void appendGroupNameToParameters(const QString& theGroupTitle, QString& theParams) +{ + theParams += TITLE(theGroupTitle) + "
"; +} + +static void appendNamedValueToParameters(const QString& theName, + const double theValue, + QString& theParams) +{ + theParams += theName + ": " + QString::number(theValue) + "
"; +} + +static void appendNamedValueToParameters(const QString& theName, + const bool theValue, + QString& theParams) +{ + theParams += theName + ": " + (theValue ? "True" : "False") + "
"; +} + + +// ================ XGUI_InspectionPanel ================ + XGUI_InspectionPanel::XGUI_InspectionPanel(QWidget* theParent, XGUI_SelectionMgr* theMgr) : QDockWidget(theParent), mySelectionMgr(theMgr) @@ -240,491 +283,391 @@ void XGUI_InspectionPanel::setShapeContent(const TopoDS_Shape& theShape) //******************************************************************** void XGUI_InspectionPanel::setShapeParams(const TopoDS_Shape& theShape) { - switch (theShape.ShapeType()) { - case TopAbs_VERTEX: - fillVertex(theShape); + GeomShapePtr aShape(new GeomAPI_Shape); + aShape->setImpl(new TopoDS_Shape(theShape)); + + switch (aShape->shapeType()) { + case GeomAPI_Shape::VERTEX: + fillVertex(aShape->vertex()); break; - case TopAbs_EDGE: - fillEdge(theShape); + case GeomAPI_Shape::EDGE: + fillEdge(aShape->edge()); break; - case TopAbs_FACE: - fillFace(theShape); + case GeomAPI_Shape::FACE: + fillFace(aShape->face()); break; - case TopAbs_SOLID: - fillSolid(theShape); + case GeomAPI_Shape::SOLID: + fillSolid(aShape->solid()); break; - case TopAbs_WIRE: - case TopAbs_SHELL: - case TopAbs_COMPSOLID: - case TopAbs_COMPOUND: - fillContainer(theShape); + case GeomAPI_Shape::WIRE: + fillWire(aShape->wire()); + break; + case GeomAPI_Shape::SHELL: + fillShell(aShape->shell()); + break; + case GeomAPI_Shape::COMPSOLID: + case GeomAPI_Shape::COMPOUND: + fillContainer(aShape); break; } } //******************************************************************** -void XGUI_InspectionPanel::fillVertex(const TopoDS_Shape& theShape) +void XGUI_InspectionPanel::fillVertex(const GeomVertexPtr& theVertex) { - TopoDS_Vertex aV = TopoDS::Vertex(theShape); - gp_Pnt aP = BRep_Tool::Pnt(aV); - setVertexType(aP.XYZ()); -} + GeomPointPtr aPoint = theVertex->point(); -//******************************************************************** -void XGUI_InspectionPanel::fillEdge(const TopoDS_Shape& theShape) -{ - TopoDS_Edge aE = TopoDS::Edge(theShape); - - bool bDegenerated = BRep_Tool::Degenerated(aE); - - double aT1, aT2; - Handle(Geom_Curve) aC3D = BRep_Tool::Curve(aE, aT1, aT2); - GeomAdaptor_Curve aGAC(aC3D); - GeomAbs_CurveType aCT = aGAC.GetType(); - - if (aCT == GeomAbs_Line) { // Line - gp_Pnt aP1, aP2; - aGAC.D0(aT1, aP1); - aGAC.D0(aT2, aP2); - setLineType(aP1.XYZ(), aP2.XYZ()); - - } else if (aCT == GeomAbs_Circle) { - gp_Circ aCirc = aGAC.Circle(); - gp_Pnt aP = aCirc.Location(); - gp_Ax2 aAx2 = aCirc.Position(); - double aR1 = aCirc.Radius(); - gp_Dir aDir = aAx2.Axis().Direction(); - - bool isArc = (Abs(aT2 - aT1 - aC3D->Period()) >= Precision::PConfusion()); - if (isArc) { - gp_Pnt aP1, aP2; - aGAC.D0(aT1, aP1); - aGAC.D0(aT2, aP2); - setArcType(aP.XYZ(), aDir.XYZ(), aR1, aP1.XYZ(), aP2.XYZ()); - } else - setCircleType(aP.XYZ(), aDir.XYZ(), aR1); - - } else if (aCT == GeomAbs_Ellipse) { - gp_Elips aElips = aGAC.Ellipse(); - gp_Pnt aP = aElips.Location(); - gp_Ax2 aAx2 = aElips.Position(); - double aR1 = aElips.MajorRadius(); - double aR2 = aElips.MinorRadius(); - gp_Dir aDir = aAx2.Axis().Direction(); - gp_Pnt aP1, aP2; - aGAC.D0(aT1, aP1); - aGAC.D0(aT2, aP2); - bool isArc = aP1.Distance(aP2) > Precision::Confusion(); - if (isArc) - setEllipseArcType(aP.XYZ(), aDir.XYZ(), aR1, aR2, aP1.XYZ(), aP2.XYZ()); - else - setEllipseType(aP.XYZ(), aDir.XYZ(), aR1, aR2); - } + myTypeLbl->setText(tr("Vertex")); + + QString aParams; + appendPointToParameters(tr("Coordinates"), aPoint, aParams); + myTypeParams->setText(aParams); } //******************************************************************** -void XGUI_InspectionPanel::fillFace(const TopoDS_Shape& theShape) +void XGUI_InspectionPanel::fillEdge(const GeomEdgePtr& theEdge) { - TopoDS_Face aF = TopoDS::Face(theShape); - // - Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aF); - GeomAdaptor_Surface aGAS(aSurf); - GeomAbs_SurfaceType aST = aGAS.GetType(); - - // 1. Plane - if (aST == GeomAbs_Plane) { - gp_Pln aPln = aGAS.Plane(); - gp_Pnt aP0 = aPln.Location(); - gp_Ax3 aAx3 = aPln.Position(); - - setPlaneType(aP0.XYZ(), aAx3.Direction().XYZ()); - } - // 2. Sphere - else if (aST == GeomAbs_Sphere) { - gp_Sphere aSphere = aGAS.Sphere(); - gp_Pnt aP0 = aSphere.Location(); - double aR1 = aSphere.Radius(); + QString aParams; + if (theEdge->isDegenerated()) + appendNamedValueToParameters(tr("Degenerated"), true, aParams); - setSphereType(aP0.XYZ(), aR1); - } - // 3. Cylinder - else if (aST == GeomAbs_Cylinder) { - gp_Cylinder aCyl = aGAS.Cylinder(); - gp_Pnt aP0 = aCyl.Location(); - gp_Ax3 aAx3 = aCyl.Position(); - double aR1 = aCyl.Radius(); - - double aUMin, aUMax, aVMin, aVMax; - BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax); - double dV = aVMax - aVMin; - - setCylinderType(aP0.XYZ(), aAx3.Direction().XYZ(), aR1, dV); - } - // 4. Cone - else if (aST == GeomAbs_Cone) { - gp_Cone aCone = aGAS.Cone(); - gp_Pnt aP0 = aCone.Location(); - gp_Ax3 aAx3 = aCone.Position(); - double aR1 = aCone.RefRadius(); - - double aUMin, aUMax, aVMin, aVMax; - BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax); - double aSemiAngle = fabs(aCone.SemiAngle()); - double dV = (aVMax - aVMin)*cos(aSemiAngle); - double aR2 = aR1 - (aVMax - aVMin)*sin(aSemiAngle); - - setConeType(aP0.XYZ(), aAx3.Direction().XYZ(), aR1, aR2, dV); + GeomPointPtr aStartPnt = theEdge->firstPoint(); + GeomPointPtr aEndPnt = theEdge->lastPoint(); + bool addStartEndPoints = false; + + if (theEdge->isLine()) { + myTypeLbl->setText(tr("Line segment")); + addStartEndPoints = true; } - // 5. Torus - else if (aST == GeomAbs_Torus) { - gp_Torus aTorus = aGAS.Torus(); - gp_Pnt aP0 = aTorus.Location(); - gp_Ax3 aAx3 = aTorus.Position(); - double aR1 = aTorus.MajorRadius(); - double aR2 = aTorus.MinorRadius(); - - setTorusType(aP0.XYZ(), aAx3.Direction().XYZ(), aR1, aR2); + else { + GeomCirclePtr aCircle = theEdge->circle(); + if (aCircle) { + addStartEndPoints = aStartPnt->distance(aEndPnt) >= Precision::Confusion(); + if (addStartEndPoints) + myTypeLbl->setText("Arc of circle"); + else + myTypeLbl->setText("Circle"); + + appendPointToParameters(tr("Center"), aCircle->center(), aParams); + appendDirToParameters(tr("Normal"), aCircle->normal(), aParams); + appendGroupNameToParameters(tr("Dimensions"), aParams); + appendNamedValueToParameters(tr("Radius"), aCircle->radius(), aParams); + } + else { + GeomEllipsePtr anEllipse = theEdge->ellipse(); + if (anEllipse) { + addStartEndPoints = aStartPnt->distance(aEndPnt) >= Precision::Confusion(); + if (addStartEndPoints) + myTypeLbl->setText("Arc of ellipse"); + else + myTypeLbl->setText("Ellipse"); + + appendPointToParameters(tr("Center"), anEllipse->center(), aParams); + appendDirToParameters(tr("Normal"), anEllipse->normal(), aParams); + appendGroupNameToParameters(tr("Dimensions"), aParams); + appendNamedValueToParameters(tr("Major radius"), anEllipse->majorRadius(), aParams); + appendNamedValueToParameters(tr("Minor radius"), anEllipse->minorRadius(), aParams); + } + else + // Common case + myTypeLbl->setText(tr("Edge")); + } } -} -//******************************************************************** -void XGUI_InspectionPanel::fillSolid(const TopoDS_Shape& theShape) -{ - myTypeLbl->setText(tr("Solid")); - TopoDS_Solid aSd = TopoDS::Solid(theShape); - processSphere(aSd); + if (addStartEndPoints) { + appendPointToParameters(tr("Start point"), aStartPnt, aParams); + appendPointToParameters(tr("End point"), aEndPnt, aParams); + } + myTypeParams->setText(aParams); } - - //******************************************************************** -bool IsEqual(const gp_Sphere& aSp1, const gp_Sphere& aSp2, const Standard_Real aTolLin) +void XGUI_InspectionPanel::fillWire(const GeomWirePtr& theWire) { - double aR1 = aSp1.Radius(); - double aR2 = aSp2.Radius(); - if (fabs(aR1 - aR2) > aTolLin) { - return false; + QString aParams; + appendNamedValueToParameters(tr("Closed"), theWire->isClosed(), aParams); + + // check the wire is a polygon + std::list aPolygonPoints; + if (theWire->isPolygon(aPolygonPoints)) { + myTypeLbl->setText(tr("Polygon")); + int aCornerIndex = 0; + for (std::list::const_iterator aPtIt = aPolygonPoints.begin(); + aPtIt != aPolygonPoints.end(); ++aPtIt) + appendPointToParameters(tr("Point") + " " + QString::number(++aCornerIndex), + *aPtIt, aParams); } - const gp_Pnt& aPC1 = aSp1.Position().Location(); - const gp_Pnt& aPC2 = aSp2.Position().Location(); - double aD2 = aPC1.SquareDistance(aPC2); - return (aD2 < (aTolLin*aTolLin)); -} + else + myTypeLbl->setText(tr("Wire")); + myTypeParams->setText(aParams); +} -bool XGUI_InspectionPanel::processSphere(const TopoDS_Solid& theSolid) +//******************************************************************** +void XGUI_InspectionPanel::fillFace(const GeomFacePtr& theFace) { - gp_Sphere aSphere[2]; - GeomAbs_SurfaceType aST; - Handle(Geom_Surface) aS; - GeomAdaptor_Surface aGAS; - - double aTol = Precision::Confusion(); - double aTolAng = Precision::Angular(); - - TopExp_Explorer aExp(theSolid, TopAbs_FACE); - int j; - for (j = 0; aExp.More(); aExp.Next(), ++j) { - const TopoDS_Face& aF = *((TopoDS_Face*)&aExp.Current()); - aS = BRep_Tool::Surface(aF); - aGAS.Load(aS); - aST = aGAS.GetType(); - if (aST != GeomAbs_Sphere) { - return false; + QString aParams; + // 1. Plane and planar faces + GeomPlanePtr aPlane = theFace->getPlane(); + if (aPlane) { + bool isCommonCase = true; + // Check face bounded by circle or ellipse + std::list aSubs = theFace->subShapes(GeomAPI_Shape::EDGE); + if (aSubs.size() == 1) { + GeomEdgePtr anEdge = aSubs.front()->edge(); + if (anEdge->isCircle() || anEdge->isEllipse()) { + fillEdge(anEdge); + isCommonCase = false; + } } - aSphere[j] = aGAS.Sphere(); - } - bool bIsEqual = IsEqual(aSphere[0], aSphere[1], aTol); - if (!bIsEqual) { - return false; - } - GProp_GProps aGProps; - bool bOnlyClosed = false; - double aVolume = aSphere[0].Volume(); - BRepGProp::VolumeProperties(theSolid, aGProps, aTol, bOnlyClosed); - - double aVolumeS = aGProps.Mass(); - if (aVolumeS < 0.) { - aVolumeS = -aVolumeS; - } - double dV = fabs(aVolumeS - aVolume); - if (dV > aTol) { - return false; + else { + // Check face bounded by a single wire which is rectangle + aSubs = theFace->subShapes(GeomAPI_Shape::WIRE); + if (aSubs.size() == 1) { + GeomWirePtr aWire = aSubs.front()->wire(); + std::list aCorners; + if (aWire->isRectangle(aCorners)) { + GeomPointPtr aBaseCorner = aCorners.front(); + aCorners.pop_front(); + + double aWidth = aBaseCorner->distance(aCorners.front()); + double aHeight = aBaseCorner->distance(aCorners.back()); + + myTypeLbl->setText(tr("Rectangle")); + appendPointToParameters(tr("Corner"), aBaseCorner, aParams); + appendDirToParameters(tr("Normal"), aPlane->direction(), aParams); + appendGroupNameToParameters(tr("Dimensions"), aParams); + appendNamedValueToParameters(tr("Width"), aWidth, aParams); + appendNamedValueToParameters(tr("Height"), aHeight, aParams); + myTypeParams->setText(aParams); + + isCommonCase = false; + } + } + } + + if (isCommonCase) + setPlaneType(tr("Plane"), aPlane); } - double aArea = aSphere[0].Area(); - BRepGProp::SurfaceProperties(theSolid, aGProps, aTol); - double aAreaS = aGProps.Mass(); - double dA = fabs(aAreaS - aArea); - if (dA > aTol) { - return false; + else { + // 2. Sphere + GeomSpherePtr aSphere = theFace->getSphere(); + if (aSphere) + setSphereType(tr("Sphere"), aSphere); + else { + // 3. Cylinder + GeomCylinderPtr aCylinder = theFace->getCylinder(); + if (aCylinder) + setCylinderType(tr("Cylinder"), aCylinder); + else { + // 4. Cone + GeomConePtr aCone = theFace->getCone(); + if (aCone) + setConeType(tr("Cone"), aCone); + else { + // 5. Torus + GeomTorusPtr aTorus = theFace->getTorus(); + if (aTorus) + setTorusType(tr("Torus"), aTorus); + else + // 6. Common case + myTypeLbl->setText(tr("Face")); + } + } + } } - gp_Pnt aP0 = aSphere[0].Location(); - double aR1 = aSphere[0].Radius(); - - setSphereType(aP0.XYZ(), aR1); - - return true; } - //******************************************************************** -void XGUI_InspectionPanel::fillContainer(const TopoDS_Shape& theShape) +void XGUI_InspectionPanel::fillShell(const GeomShellPtr& theShell) { - TopAbs_ShapeEnum aType = theShape.ShapeType(); - if (aType == TopAbs_SHELL) { - bool aIsClosed = BRep_Tool::IsClosed(theShape); - myTypeLbl->setText(tr("Shell")); - myTypeParams->setText(aIsClosed? tr("Closed") : tr("Non-closed")); - } else if (aType == TopAbs_WIRE) { - TopoDS_Wire aW = TopoDS::Wire(theShape); - bool isClosed = aW.Closed(); - myTypeLbl->setText(tr("Wire")); - myTypeParams->setText(isClosed ? tr("Closed") : tr("Non-closed")); + // 1. Sphere + GeomSpherePtr aSphere = theShell->getSphere(); + if (aSphere) + setSphereType(tr("Sphere"), aSphere); + else { + // 2. Cylinder + GeomCylinderPtr aCylinder = theShell->getCylinder(); + if (aCylinder) + setCylinderType(tr("Cylinder"), aCylinder); + else { + // 3. Cone + GeomConePtr aCone = theShell->getCone(); + if (aCone) + setConeType(tr("Cone"), aCone); + else { + // 4. Torus + GeomTorusPtr aTorus = theShell->getTorus(); + if (aTorus) + setTorusType(tr("Torus"), aTorus); + else { + // 5. Axis-aligned/Rotated Box + GeomBoxPtr aBox = theShell->getParallelepiped(); + if (aBox) { + if (aBox->isAxesAligned()) + setBoxType(tr("Box"), aBox); + else + setRotatedBoxType(tr("Rotated Box"), aBox); + } + else + // 6. Common case + myTypeLbl->setText(tr("Shell")); + } + } + } } } //******************************************************************** -#define TITLE(val) ("" + val + "") - -void XGUI_InspectionPanel::setCylinderType(const gp_XYZ& theLoc, - const gp_XYZ& theDir, double theRadius, double theHeight) +void XGUI_InspectionPanel::fillSolid(const GeomSolidPtr& theSolid) { - myTypeLbl->setText(tr("Cylinder")); - QString aParams = TITLE(tr("Center")) + - "
X: " + QString::number(theLoc.X()) + - "
Y: " + QString::number(theLoc.Y()) + - "
Z: " + QString::number(theLoc.Z()) + - "
" + TITLE(tr("Axis")) + - "
DX: " + QString::number(theDir.X()) + - "
DY: " + QString::number(theDir.Y()) + - "
DZ: " + QString::number(theDir.Z()) + - "
" + TITLE(tr("Dimensions")) + - "
" + tr("Radius: ") + QString::number(theRadius) + - "
" + tr("Height: ") + QString::number(theHeight); - - myTypeParams->setText(aParams); + // 1. Sphere + GeomSpherePtr aSphere = theSolid->getSphere(); + if (aSphere) + setSphereType(tr("Sphere"), aSphere); + else { + // 2. Cylinder + GeomCylinderPtr aCylinder = theSolid->getCylinder(); + if (aCylinder) + setCylinderType(tr("Cylinder"), aCylinder); + else { + // 3. Cone + GeomConePtr aCone = theSolid->getCone(); + if (aCone) + setConeType(tr("Cone"), aCone); + else { + // 4. Torus + GeomTorusPtr aTorus = theSolid->getTorus(); + if (aTorus) + setTorusType(tr("Torus"), aTorus); + else { + // 5. Axis-aligned/Rotated Box + GeomBoxPtr aBox = theSolid->getParallelepiped(); + if (aBox) { + if (aBox->isAxesAligned()) + setBoxType(tr("Box"), aBox); + else + setRotatedBoxType(tr("Rotated Box"), aBox); + } + else + // 6. Common case + myTypeLbl->setText(tr("Solid")); + } + } + } + } } //******************************************************************** -void XGUI_InspectionPanel::setSphereType(const gp_XYZ& theLoc, double theRadius) +void XGUI_InspectionPanel::fillContainer(const GeomShapePtr& theShape) { - myTypeLbl->setText(tr("Sphere")); - QString aParams = TITLE(tr("Center")) + - "
X: " + QString::number(theLoc.X()) + - "
Y: " + QString::number(theLoc.Y()) + - "
Z: " + QString::number(theLoc.Z()) + - "
" + TITLE(tr("Dimensions")) + - "
" + tr("Radius: ") + QString::number(theRadius); - myTypeParams->setText(aParams); -} + if (theShape->shapeType() == GeomAPI_Shape::COMPSOLID) + myTypeLbl->setText("CompSolid"); + else if (theShape->shapeType() == GeomAPI_Shape::COMPOUND) + myTypeLbl->setText("Compound"); -//******************************************************************** -void XGUI_InspectionPanel::setBoxType(double theX, double theY, double theZ, - double theXsize, double theYsize, double theZsize) -{ - myTypeLbl->setText(tr("Box")); - QString aParams = TITLE(tr("Position")) + - "
X: " + QString::number(theX) + - "
Y: " + QString::number(theY) + - "
Z: " + QString::number(theZ) + - "
" + TITLE(tr("Dimensions")) + - "
" + "Ax :" + QString::number(theXsize) + - "
" + "Ay :" + QString::number(theYsize) + - "
" + "Az :" + QString::number(theZsize); - myTypeParams->setText(aParams); -} + // fill bounding box + Bnd_Box aBB; + BRepBndLib::Add(theShape->impl(), aBB); -//******************************************************************** -void XGUI_InspectionPanel::setRotatedBoxType(double theX, double theY, double theZ, - double theZaxisX, double theZaxisY, double theZaxisZ, - double theXaxisX, double theXaxisY, double theXaxisZ, - double theXsize, double theYsize, double theZsize) -{ - myTypeLbl->setText(tr("Box")); - QString aParams = TITLE(tr("Position")) + - "
X: " + QString::number(theX) + - "
Y: " + QString::number(theY) + - "
Z: " + QString::number(theZ) + - "
" + TITLE(tr("Z axis")) + - "
DX: " + QString::number(theZaxisX) + - "
DY: " + QString::number(theZaxisY) + - "
DZ: " + QString::number(theZaxisZ) + - "
" + TITLE(tr("X axis")) + - "
DX: " + QString::number(theXaxisX) + - "
DY: " + QString::number(theXaxisY) + - "
DZ: " + QString::number(theXaxisZ) + - "
" + TITLE(tr("Dimensions")) + - "
" + "Ax :" + QString::number(theXsize) + - "
" + "Ay :" + QString::number(theYsize) + - "
" + "Az :" + QString::number(theZsize); - myTypeParams->setText(aParams); -} + gp_Pnt aMinPnt = aBB.CornerMin(); + GeomPointPtr aMinPoint(new GeomAPI_Pnt(aMinPnt.X(), aMinPnt.Y(), aMinPnt.Z())); -//******************************************************************** -void XGUI_InspectionPanel::setPlaneType(const gp_XYZ& theLoc, const gp_XYZ& theDir) -{ - myTypeLbl->setText(tr("Plane")); - QString aParams = TITLE(tr("Center")) + - "
X: " + QString::number(theLoc.X()) + - "
Y: " + QString::number(theLoc.Y()) + - "
Z: " + QString::number(theLoc.Z()) + - "
" + TITLE(tr("Normal")) + - "
DX: " + QString::number(theDir.X()) + - "
DY: " + QString::number(theDir.Y()) + - "
DZ: " + QString::number(theDir.Z()); - myTypeParams->setText(aParams); -} + gp_Pnt aMaxPnt = aBB.CornerMax(); + GeomPointPtr aMaxPoint(new GeomAPI_Pnt(aMaxPnt.X(), aMaxPnt.Y(), aMaxPnt.Z())); -//******************************************************************** -void XGUI_InspectionPanel::setVertexType(const gp_XYZ& theLoc) -{ - myTypeLbl->setText(tr("Vertex")); - QString aParams = TITLE(tr("Coordinates")) + - "
X: " + QString::number(theLoc.X()) + - "
Y: " + QString::number(theLoc.Y()) + - "
Z: " + QString::number(theLoc.Z()); - myTypeParams->setText(aParams); + QString aParams; + appendGroupNameToParameters(tr("Bounding box"), aParams); + appendPointToParameters(tr("Minimal corner"), aMinPoint, aParams); + appendPointToParameters(tr("Maximal corner"), aMaxPoint, aParams); } -//******************************************************************** -void XGUI_InspectionPanel::setCircleType(const gp_XYZ& theLoc, const gp_XYZ& theDir, - double theRadius) +void XGUI_InspectionPanel::setPlaneType(const QString& theTitle, + const std::shared_ptr& thePlane) { - myTypeLbl->setText(tr("Circle")); - QString aParams = TITLE(tr("Center")) + - "
X: " + QString::number(theLoc.X()) + - "
Y: " + QString::number(theLoc.Y()) + - "
Z: " + QString::number(theLoc.Z()) + - "
" + TITLE(tr("Normal")) + - "
DX: " + QString::number(theDir.X()) + - "
DY: " + QString::number(theDir.Y()) + - "
DZ: " + QString::number(theDir.Z()) + - "
" + TITLE(tr("Dimensions")) + - "
" + tr("Radius: ") + QString::number(theRadius); + myTypeLbl->setText(theTitle); + QString aParams; + appendPointToParameters(tr("Origin"), thePlane->location(), aParams); + appendDirToParameters(tr("Normal"), thePlane->direction(), aParams); myTypeParams->setText(aParams); } -//******************************************************************** -void XGUI_InspectionPanel::setArcType(const gp_XYZ& theLoc, const gp_XYZ& theDir, - double theRadius, const gp_XYZ& theP1, const gp_XYZ& theP2) +void XGUI_InspectionPanel::setSphereType(const QString& theTitle, + const std::shared_ptr& theSphere) { - myTypeLbl->setText(tr("Arc")); - QString aParams = TITLE(tr("Center")) + - "
X: " + QString::number(theLoc.X()) + - "
Y: " + QString::number(theLoc.Y()) + - "
Z: " + QString::number(theLoc.Z()) + - "
" + TITLE(tr("Normal")) + - "
DX: " + QString::number(theDir.X()) + - "
DY: " + QString::number(theDir.Y()) + - "
DZ: " + QString::number(theDir.Z()) + - "
" + TITLE(tr("Dimensions")) + - "
" + tr("Radius:") + QString::number(theRadius) + - "
" + TITLE(tr("Point 1")) + - "
X: " + QString::number(theP1.X()) + - "
Y: " + QString::number(theP1.Y()) + - "
Z: " + QString::number(theP1.Z()) + - "
" + TITLE(tr("Point 2")) + - "
X: " + QString::number(theP2.X()) + - "
Y: " + QString::number(theP2.Y()) + - "
Z: " + QString::number(theP2.Z()); + myTypeLbl->setText(theTitle); + QString aParams; + appendPointToParameters(tr("Center"), theSphere->center(), aParams); + appendGroupNameToParameters(tr("Dimensions"), aParams); + appendNamedValueToParameters(tr("Radius"), theSphere->radius(), aParams); myTypeParams->setText(aParams); } -//******************************************************************** -void XGUI_InspectionPanel::setEllipseType(const gp_XYZ& theLoc, const gp_XYZ& theDir, - double theMajorRad, double theMinorRad) +void XGUI_InspectionPanel::setCylinderType(const QString& theTitle, + const std::shared_ptr& theCyl) { - myTypeLbl->setText(tr("Ellipse")); - QString aParams = TITLE(tr("Center")) + - "
X: " + QString::number(theLoc.X()) + - "
Y: " + QString::number(theLoc.Y()) + - "
Z: " + QString::number(theLoc.Z()) + - "
" + TITLE(tr("Normal")) + - "
DX: " + QString::number(theDir.X()) + - "
DY: " + QString::number(theDir.Y()) + - "
DZ: " + QString::number(theDir.Z()) + - "
" + TITLE(tr("Dimensions")) + - "
" + tr("Major radius: ") + QString::number(theMajorRad) + - "
" + tr("Minor radius: ") + QString::number(theMinorRad); + myTypeLbl->setText(theTitle); + QString aParams; + appendPointToParameters(tr("Position"), theCyl->location(), aParams); + appendDirToParameters(tr("Axis"), theCyl->axis(), aParams); + appendGroupNameToParameters(tr("Dimensions"), aParams); + appendNamedValueToParameters(tr("Radius"), theCyl->radius(), aParams); + appendNamedValueToParameters(tr("Height"), theCyl->height(), aParams); myTypeParams->setText(aParams); } -//******************************************************************** -void XGUI_InspectionPanel::setEllipseArcType(const gp_XYZ& theLoc, const gp_XYZ& theDir, - double theMajorRad, double theMinorRad, const gp_XYZ& theP1, const gp_XYZ& theP2) +void XGUI_InspectionPanel::setConeType(const QString& theTitle, + const std::shared_ptr& theCone) { - myTypeLbl->setText(tr("Elliptical arc")); - QString aParams = TITLE(tr("Center")) + - "
X: " + QString::number(theLoc.X()) + - "
Y: " + QString::number(theLoc.Y()) + - "
Z: " + QString::number(theLoc.Z()) + - "
" + TITLE(tr("Normal")) + - "
DX: " + QString::number(theDir.X()) + - "
DY: " + QString::number(theDir.Y()) + - "
DZ: " + QString::number(theDir.Z()) + - "
" + TITLE(tr("Dimensions")) + - "
" + tr("Major radius:") + QString::number(theMajorRad) + - "
" + tr("Minor radius:") + QString::number(theMinorRad) + - "
" + TITLE(tr("Point 1")) + - "
X: " + QString::number(theP1.X()) + - "
Y: " + QString::number(theP1.Y()) + - "
Z: " + QString::number(theP1.Z()) + - "
" + TITLE(tr("Point 2")) + - "
X: " + QString::number(theP2.X()) + - "
Y: " + QString::number(theP2.Y()) + - "
Z: " + QString::number(theP2.Z()); + myTypeLbl->setText(theTitle); + QString aParams; + appendPointToParameters(tr("Position"), theCone->location(), aParams); + appendDirToParameters(tr("Axis"), theCone->axis(), aParams); + appendGroupNameToParameters(tr("Dimensions"), aParams); + appendNamedValueToParameters(tr("Radius 1"), theCone->radius1(), aParams); + appendNamedValueToParameters(tr("Radius 2"), theCone->radius2(), aParams); + appendNamedValueToParameters(tr("Height"), theCone->height(), aParams); myTypeParams->setText(aParams); } -void XGUI_InspectionPanel::setLineType(const gp_XYZ& theP1, const gp_XYZ& theP2) +void XGUI_InspectionPanel::setTorusType(const QString& theTitle, + const std::shared_ptr& theTorus) { - myTypeLbl->setText(tr("Line")); - QString aParams = TITLE(tr("Point 1")) + - "
X: " + QString::number(theP1.X()) + - "
Y: " + QString::number(theP1.Y()) + - "
Z: " + QString::number(theP1.Z()) + - "
" + TITLE(tr("Point 2")) + - "
X: " + QString::number(theP2.X()) + - "
Y: " + QString::number(theP2.Y()) + - "
Z: " + QString::number(theP2.Z()); + myTypeLbl->setText(theTitle); + QString aParams; + appendPointToParameters(tr("Center"), theTorus->center(), aParams); + appendDirToParameters(tr("Axis"), theTorus->direction(), aParams); + appendGroupNameToParameters(tr("Dimensions"), aParams); + appendNamedValueToParameters(tr("Major radius"), theTorus->majorRadius(), aParams); + appendNamedValueToParameters(tr("Minor radius"), theTorus->minorRadius(), aParams); myTypeParams->setText(aParams); } -void XGUI_InspectionPanel::setConeType(const gp_XYZ& theLoc, const gp_XYZ& theDir, - double theRad1, double theRad2, double theHeight) +void XGUI_InspectionPanel::setBoxType(const QString& theTitle, + const std::shared_ptr& theBox) { - myTypeLbl->setText(tr("Cone")); - QString aParams = TITLE(tr("Center")) + - "
X: " + QString::number(theLoc.X()) + - "
Y: " + QString::number(theLoc.Y()) + - "
Z: " + QString::number(theLoc.Z()) + - "
" + TITLE(tr("Axis")) + - "
DX: " + QString::number(theDir.X()) + - "
DY: " + QString::number(theDir.Y()) + - "
DZ: " + QString::number(theDir.Z()) + - "
" + TITLE(tr("Dimensions")) + - "
" + tr("Radius 1: ") + QString::number(theRad1) + - "
" + tr("Radius 2: ") + QString::number(theRad2) + - "
" + tr("Height: ") + QString::number(theHeight); - + myTypeLbl->setText(theTitle); + QString aParams; + appendPointToParameters(tr("Position"), theBox->axes()->origin(), aParams); + appendGroupNameToParameters(tr("Dimensions"), aParams); + appendNamedValueToParameters(tr("Width"), theBox->width(), aParams); + appendNamedValueToParameters(tr("Depth"), theBox->depth(), aParams); + appendNamedValueToParameters(tr("Height"), theBox->height(), aParams); myTypeParams->setText(aParams); } -void XGUI_InspectionPanel::setTorusType(const gp_XYZ& theLoc, const gp_XYZ& theDir, - double theRad1, double theRad2) +void XGUI_InspectionPanel::setRotatedBoxType(const QString& theTitle, + const std::shared_ptr& theBox) { - myTypeLbl->setText(tr("Torus")); - QString aParams = TITLE(tr("Center")) + - "
X: " + QString::number(theLoc.X()) + - "
Y: " + QString::number(theLoc.Y()) + - "
Z: " + QString::number(theLoc.Z()) + - "
" + TITLE(tr("Axis")) + - "
DX: " + QString::number(theDir.X()) + - "
DY: " + QString::number(theDir.Y()) + - "
DZ: " + QString::number(theDir.Z()) + - "
" + TITLE(tr("Dimensions")) + - "
" + tr("Radius 1: ") + QString::number(theRad1) + - "
" + tr("Radius 2: ") + QString::number(theRad2); - + myTypeLbl->setText(theTitle); + QString aParams; + std::shared_ptr anAxes = theBox->axes(); + appendPointToParameters(tr("Position"), anAxes->origin(), aParams); + appendDirToParameters(tr("Z axis"), anAxes->normal(), aParams); + appendDirToParameters(tr("X axis"), anAxes->dirX(), aParams); + appendGroupNameToParameters(tr("Dimensions"), aParams); + appendNamedValueToParameters(tr("Width"), theBox->width(), aParams); + appendNamedValueToParameters(tr("Depth"), theBox->depth(), aParams); + appendNamedValueToParameters(tr("Height"), theBox->height(), aParams); myTypeParams->setText(aParams); } diff --git a/src/XGUI/XGUI_InspectionPanel.h b/src/XGUI/XGUI_InspectionPanel.h index 537ae6f3b..b5d1a056f 100644 --- a/src/XGUI/XGUI_InspectionPanel.h +++ b/src/XGUI/XGUI_InspectionPanel.h @@ -23,17 +23,33 @@ #include "XGUI.h" -#include -#include - #include +#include + class XGUI_SelectionMgr; class QLineEdit; class QTableWidget; class QLabel; class QTextBrowser; +class TopoDS_Shape; + +class GeomAPI_Vertex; +class GeomAPI_Edge; +class GeomAPI_Wire; +class GeomAPI_Face; +class GeomAPI_Shell; +class GeomAPI_Solid; +class GeomAPI_Shape; + +class GeomAPI_Pln; +class GeomAPI_Sphere; +class GeomAPI_Cylinder; +class GeomAPI_Cone; +class GeomAPI_Torus; +class GeomAPI_Box; + /// Internal name of property panel widget const static char* INSPECTION_PANEL = "inspection_panel_dock"; @@ -68,60 +84,41 @@ private: void setName(const QString& theName); - // Set type parameters - void setCylinderType(const gp_XYZ& theLoc, const gp_XYZ& theDir, - double theRadius, double theHeight); - - void setConeType(const gp_XYZ& theLoc, const gp_XYZ& theDir, - double theRad1, double theRad2, double theHeight); - - void setTorusType(const gp_XYZ& theLoc, const gp_XYZ& theDir, - double theRad1, double theRad2); + void setShapeContent(const TopoDS_Shape& theShape); - void setSphereType(const gp_XYZ& theLoc, double theRadius); + void setShapeParams(const TopoDS_Shape& theShape); - void setBoxType(double theX, double theY, double theZ, - double theXsize, double theYsize, double theZsize); + void clearContent(); - void setRotatedBoxType(double theX, double theY, double theZ, - double theZaxisX, double theZaxisY, double theZaxisZ, - double theXaxisX, double theXaxisY, double theXaxisZ, - double theXsize, double theYsize, double theZsize); - void setPlaneType(const gp_XYZ& theLoc, const gp_XYZ& theDir); + void fillVertex(const std::shared_ptr& theVertex); - void setVertexType(const gp_XYZ& theLoc); + void fillEdge(const std::shared_ptr& theEdge); - void setCircleType(const gp_XYZ& theLoc, const gp_XYZ& theDir, double theRadius); + void fillWire(const std::shared_ptr& theWire); - void setArcType(const gp_XYZ& theLoc, const gp_XYZ& theDir, double theRadius, - const gp_XYZ& theP1, const gp_XYZ& theP2); + void fillFace(const std::shared_ptr& theFace); - void setEllipseType(const gp_XYZ& theLoc, const gp_XYZ& theDir, - double theMajorRad, double theMinorRad); + void fillShell(const std::shared_ptr& theShell); - void setEllipseArcType(const gp_XYZ& theLoc, const gp_XYZ& theDir, - double theMajorRad, double theMinorRad, const gp_XYZ& theP1, const gp_XYZ& theP2); + void fillSolid(const std::shared_ptr& theSolid); - void setLineType(const gp_XYZ& theP1, const gp_XYZ& theP2); + void fillContainer(const std::shared_ptr& theShape); - void setShapeContent(const TopoDS_Shape& theShape); - void setShapeParams(const TopoDS_Shape& theShape); - - void clearContent(); + void setPlaneType(const QString& theTitle, const std::shared_ptr& thePlane); - void fillVertex(const TopoDS_Shape& theShape); + void setSphereType(const QString& theTitle, const std::shared_ptr& theSphere); - void fillEdge(const TopoDS_Shape& theShape); + void setCylinderType(const QString& theTitle, const std::shared_ptr& theCyl); - void fillFace(const TopoDS_Shape& theShape); + void setConeType(const QString& theTitle, const std::shared_ptr& theCone); - void fillSolid(const TopoDS_Shape& theShape); + void setTorusType(const QString& theTitle, const std::shared_ptr& theTorus); - void fillContainer(const TopoDS_Shape& theShape); + void setBoxType(const QString& theTitle, const std::shared_ptr& theBox); - bool processSphere(const TopoDS_Solid& theSolid); + void setRotatedBoxType(const QString& theTitle, const std::shared_ptr& theBox); private: XGUI_SelectionMgr* mySelectionMgr;