X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGeomAlgoAPI%2FGeomAlgoAPI_Rotation.cpp;h=c8a76a01dbeaea3485077a75d65575ea4202b693;hb=a55586483e5dccc5466d6ec241e2147e210d839f;hp=21815311070d170e47f4c714519a95895bfec868;hpb=c39f725bfe98395871c5853dacb89ab1a6ecc6f2;p=modules%2Fshaper.git diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp index 218153110..c8a76a01d 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp @@ -1,113 +1,186 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#include "GeomAlgoAPI_Rotation.h" + +#include -// File: GeomAlgoAPI_Rotation.cpp -// Created: 12 May 2015 -// Author: Dmitry Bobylev - -#include +#include -#include +#include +#include +#include -#include -#include #include -#include //================================================================================================= GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr theSourceShape, std::shared_ptr theAxis, - double theAngle, - bool theSimpleTransform) -: myDone(false), - myShape(new GeomAPI_Shape()), - myMap(new GeomAPI_DataMapOfShapeShape()), - myMkShape(new GeomAlgoAPI_MakeShape()) + double theAngle) { - build(theSourceShape, theAxis, theAngle, theSimpleTransform); + myMethodType = BY_ANGLE; + mySourceShape = theSourceShape; + myAxis = theAxis; + myAngle = theAngle; } + //================================================================================================= -void GeomAlgoAPI_Rotation::build(std::shared_ptr theSourceShape, - std::shared_ptr theAxis, - double theAngle, - bool theSimpleTransform) +GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + std::shared_ptr theStartPoint, + std::shared_ptr theEndPoint) { - if(!theSourceShape || !theAxis) { - return; - } - - const TopoDS_Shape& aSourceShape = theSourceShape->impl(); - const gp_Ax1& anAxis = theAxis->impl(); - - if(aSourceShape.IsNull()) { - return; - } + myMethodType = BY_POINTS; + mySourceShape = theSourceShape; + myCenterPoint = theCenterPoint; + myStartPoint = theStartPoint; + myEndPoint = theEndPoint; +} - gp_Trsf aTrsf; - aTrsf.SetRotation(anAxis, theAngle / 180.0 * M_PI); - - TopoDS_Shape aResult; - // Transform the shape with copying it. - if (theSimpleTransform) { - TopLoc_Location aDelta(aTrsf); - aResult = aSourceShape.Moved(aDelta); - myDone = true; // is OK for sure - } else { - BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true); - if(!aBuilder) { - return; +//================================================================================================= +bool GeomAlgoAPI_Rotation::check() +{ + switch (myMethodType) { + case BY_ANGLE: { + if (!myAxis) { + myError = "Rotation builder :: axis is not valid."; + return false; + } + if (!mySourceShape) { + myError = "Rotation builder :: source shape is not valid."; + return false; + } + return true; } - - myDone = aBuilder->IsDone() == Standard_True; - - if(!myDone) { - return; + case BY_POINTS: { + if (!myCenterPoint) { + myError = "Rotation builder :: center point is not valid."; + return false; + } + if (!myStartPoint) { + myError = "Rotation builder :: start point is not valid."; + return false; + } + if (!myEndPoint) { + myError = "Rotation builder :: end point is not valid."; + return false; + } + if (!mySourceShape) { + myError = "Rotation builder :: source shape is not valid."; + return false; + } + if(myCenterPoint->distance(myStartPoint) < Precision::Confusion()) { + myError = "Rotation builder :: center point and start point coincide."; + return false; + } + if(myCenterPoint->distance(myEndPoint) < Precision::Confusion()) { + myError = "Rotation builder :: center point and end point coincide."; + return false; + } + if(myStartPoint->distance(myEndPoint) < Precision::Confusion()) { + myError = "Rotation builder :: start point and end point coincide."; + return false; + } + std::shared_ptr aCenterPointXYZ = myCenterPoint->xyz(); + std::shared_ptr aStartPointXYZ = myStartPoint->xyz(); + std::shared_ptr aEndPointXYZ = myEndPoint->xyz(); + std::shared_ptr vectCenterPointStartPoint = + aStartPointXYZ->decreased(aCenterPointXYZ); + std::shared_ptr vectCenterPointEndPoint = + aEndPointXYZ->decreased(aCenterPointXYZ); + std::shared_ptr crossProduct = + vectCenterPointStartPoint->cross(vectCenterPointEndPoint); + std::shared_ptr aOriginPnt = + std::shared_ptr(new GeomAPI_Pnt(0.,0.,0.)); + std::shared_ptr aOriginXYZ = aOriginPnt->xyz(); + + if (crossProduct->distance(aOriginXYZ) < Precision::Confusion()) { + myError = "Rotation builder :: center point, start point and end point are on a line."; + return false; + } + return true; } - - aResult = aBuilder->Shape(); - // Fill data map to keep correct orientation of sub-shapes. - for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More(); anExp.Next()) { - std::shared_ptr aCurrentShape(new GeomAPI_Shape()); - aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); - myMap->bind(aCurrentShape, aCurrentShape); + default: { + myError = "Rotation builder :: method not implemented."; + return false; } - myMkShape->setImpl(aBuilder); } - - myShape->setImpl(new TopoDS_Shape(aResult)); } //================================================================================================= -const bool GeomAlgoAPI_Rotation::isValid() const +void GeomAlgoAPI_Rotation::build() { - BRepCheck_Analyzer aChecker(myShape->impl()); - return (aChecker.IsValid() == Standard_True); -} + gp_Trsf* aTrsf = new gp_Trsf(); -//================================================================================================= -const bool GeomAlgoAPI_Rotation::hasVolume() const -{ - bool hasVolume(false); - if(isValid() && (GeomAlgoAPI_ShapeProps::volume(myShape) > Precision::Confusion())) { - hasVolume = true; + switch (myMethodType) { + case BY_ANGLE: { + const gp_Ax1& anAxis = myAxis->impl(); + aTrsf->SetRotation(anAxis, myAngle/180.0*M_PI); + break; + } + case BY_POINTS: { + const gp_Pnt& aCenterPoint = myCenterPoint->impl(); + const gp_Pnt& aStartPoint = myStartPoint->impl(); + const gp_Pnt& aEndPoint = myEndPoint->impl(); + gp_Vec aVec1(aCenterPoint, aStartPoint); + gp_Vec aVec2(aCenterPoint, aEndPoint); + gp_Dir aDir(aVec1^aVec2); + gp_Ax1 anAxis(aCenterPoint, aDir); + double anAngle = aVec1.Angle(aVec2); + if (fabs(anAngle) < Precision::Angular()) anAngle += 2.*M_PI; + aTrsf->SetRotation(anAxis, anAngle); + break; + } + default: { + myError = "Rotation builder :: method not supported"; + return; + } } - return hasVolume; -} -//================================================================================================= -const std::shared_ptr& GeomAlgoAPI_Rotation::shape() const -{ - return myShape; -} + const TopoDS_Shape& aSourceShape = mySourceShape->impl(); -//================================================================================================= -std::shared_ptr GeomAlgoAPI_Rotation::mapOfShapes() const -{ - return myMap; -} + if(aSourceShape.IsNull()) { + myError = "Rotation builder :: source shape does not contain any actual shape."; + return; + } -//================================================================================================= -std::shared_ptr GeomAlgoAPI_Rotation::makeShape() const -{ - return myMkShape; + // Transform the shape while copying it. + BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, *aTrsf, true); + if(!aBuilder) { + myError = "Rotation builder :: transform initialization failed."; + return; + } + + setImpl(aBuilder); + setBuilderType(OCCT_BRepBuilderAPI_MakeShape); + + if(!aBuilder->IsDone()) { + myError = "Rotation builder :: algorithm failed."; + return; + } + + TopoDS_Shape aResult = aBuilder->Shape(); + + std::shared_ptr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aResult)); + setShape(aShape); + setDone(true); }