X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FGeomAlgoAPI%2FGeomAlgoAPI_Rotation.cpp;h=c8a76a01dbeaea3485077a75d65575ea4202b693;hb=a55586483e5dccc5466d6ec241e2147e210d839f;hp=c5244788b8949eab1b51c3e828023111ce93e93e;hpb=95eaef2c17309c871072a4cfb98f2df39badb48e;p=modules%2Fshaper.git diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp index c5244788b..c8a76a01d 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Rotation.cpp @@ -1,55 +1,186 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: GeomAlgoAPI_Rotation.cpp -// Created: 12 May 2015 -// Author: Dmitry Bobylev +// 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 + #include +#include +#include +#include + +#include + //================================================================================================= GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr theSourceShape, std::shared_ptr theAxis, double theAngle) { - build(theSourceShape, theAxis, theAngle); + myMethodType = BY_ANGLE; + mySourceShape = theSourceShape; + myAxis = theAxis; + myAngle = theAngle; +} + + +//================================================================================================= +GeomAlgoAPI_Rotation::GeomAlgoAPI_Rotation(std::shared_ptr theSourceShape, + std::shared_ptr theCenterPoint, + std::shared_ptr theStartPoint, + std::shared_ptr theEndPoint) +{ + myMethodType = BY_POINTS; + mySourceShape = theSourceShape; + myCenterPoint = theCenterPoint; + myStartPoint = theStartPoint; + myEndPoint = theEndPoint; } //================================================================================================= -void GeomAlgoAPI_Rotation::build(std::shared_ptr theSourceShape, - std::shared_ptr theAxis, - double theAngle) +bool GeomAlgoAPI_Rotation::check() { - if(!theSourceShape || !theAxis) { - return; + 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; + } + 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; + } + default: { + myError = "Rotation builder :: method not implemented."; + return false; + } } +} + +//================================================================================================= +void GeomAlgoAPI_Rotation::build() +{ + gp_Trsf* aTrsf = new gp_Trsf(); - const TopoDS_Shape& aSourceShape = theSourceShape->impl(); - const gp_Ax1& anAxis = theAxis->impl(); + 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; + } + } + + const TopoDS_Shape& aSourceShape = mySourceShape->impl(); if(aSourceShape.IsNull()) { + myError = "Rotation builder :: source shape does not contain any actual shape."; return; } - gp_Trsf* aTrsf = new gp_Trsf(); - aTrsf->SetRotation(anAxis, theAngle / 180.0 * M_PI); - - // Transform the shape with copying it. + // Transform the shape while copying it. BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, *aTrsf, true); if(!aBuilder) { + myError = "Rotation builder :: transform initialization failed."; return; } - this->setImpl(aBuilder); - this->setBuilderType(OCCT_BRepBuilderAPI_MakeShape); - if(aBuilder->IsDone() != Standard_True) { + 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)); - this->setShape(aShape); - this->setDone(true); + setShape(aShape); + setDone(true); }