X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_Circle.cpp;h=1b5878b191e2ec74f00f8ce7cd071533d3d6b345;hb=88ee9b2b81cf93a6324336b57e30cc8a3a487499;hp=858c2e7efaf1fd77540610d742acb797bece4351;hpb=cba7009cf317edc3f92cf2ae3f5d729c171dea3a;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Circle.cpp b/src/SketchPlugin/SketchPlugin_Circle.cpp index 858c2e7ef..1b5878b19 100644 --- a/src/SketchPlugin/SketchPlugin_Circle.cpp +++ b/src/SketchPlugin/SketchPlugin_Circle.cpp @@ -1,8 +1,21 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> - -// File: SketchPlugin_Circle.cpp -// Created: 26 May 2014 -// Author: Artem ZHIDKOV +// Copyright (C) 2014-2022 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 "SketchPlugin_Circle.h" #include "SketchPlugin_Sketch.h" @@ -16,6 +29,8 @@ #include #include +#include +#include #include #include #include @@ -23,60 +38,13 @@ #include #include -namespace { - static const std::string& CIRCLE_TYPE() - { - static const std::string TYPE("CircleType"); - return TYPE; - } - static const std::string CIRCLE_TYPE_CENTER_AND_RADIUS() - { - static const std::string TYPE("CenterRadius"); - return TYPE; - } - static const std::string CIRCLE_TYPE_THREE_POINTS() - { - static const std::string TYPE("ThreePoints"); - return TYPE; - } +#include - static const std::string& FIRST_POINT_ID() - { - static const std::string FIRST_PNT("FirstPoint"); - return FIRST_PNT; - } - static const std::string& SECOND_POINT_ID() - { - static const std::string SECOND_PNT("SecondPoint"); - return SECOND_PNT; - } - static const std::string& THIRD_POINT_ID() - { - static const std::string THIRD_PNT("ThirdPoint"); - return THIRD_PNT; - } - static const std::string& POINT_ID(int theIndex) - { - switch (theIndex) { - case 1: return FIRST_POINT_ID(); - case 2: return SECOND_POINT_ID(); - case 3: return THIRD_POINT_ID(); - } - - static const std::string DUMMY; - return DUMMY; - } -} - -static void calculateCircleOnThreePoints(const std::shared_ptr& theFirstPnt, - const std::shared_ptr& theSecondPnt, - const std::shared_ptr& theThirdPnt, - std::shared_ptr& theCenter, - double& theRadius); +const double tolerance = 1e-7; SketchPlugin_Circle::SketchPlugin_Circle() - : SketchPlugin_SketchEntity() +: SketchPlugin_SketchEntity() { } @@ -84,102 +52,47 @@ void SketchPlugin_Circle::initDerivedClassAttributes() { data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId()); data()->addAttribute(RADIUS_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID()); - - data()->addAttribute(CIRCLE_TYPE(), ModelAPI_AttributeString::typeId()); - data()->addAttribute(FIRST_POINT_ID(), GeomDataAPI_Point2D::typeId()); - data()->addAttribute(SECOND_POINT_ID(), GeomDataAPI_Point2D::typeId()); - data()->addAttribute(THIRD_POINT_ID(), GeomDataAPI_Point2D::typeId()); - std::dynamic_pointer_cast( - data()->attribute(CIRCLE_TYPE()))->setValue(CIRCLE_TYPE_CENTER_AND_RADIUS()); } void SketchPlugin_Circle::execute() { SketchPlugin_Sketch* aSketch = sketch(); - if (aSketch) { - std::list > aShapes; - - // compute a circle point in 3D view - std::shared_ptr aCenterAttr = std::dynamic_pointer_cast< - GeomDataAPI_Point2D>(data()->attribute(CENTER_ID())); - AttributeDoublePtr aRadiusAttr = - std::dynamic_pointer_cast(data()->attribute(RADIUS_ID())); - if (aCenterAttr->isInitialized() && aRadiusAttr->isInitialized()) { - std::shared_ptr aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y())); - //std::cout<<"Execute circle "<x()<<" "<y()<<" "<z()< aNDir = std::dynamic_pointer_cast( - aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID())); - std::shared_ptr aNormal(new GeomAPI_Dir(aNDir->x(), aNDir->y(), aNDir->z())); - // compute the circle radius - double aRadius = aRadiusAttr->value(); - - std::shared_ptr aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircle( - aCenter, aNormal, aRadius); - aShapes.push_back(aCircleShape); - std::shared_ptr aConstr2 = document()->createConstruction( - data(), 1); - aConstr2->setShape(aCircleShape); - aConstr2->setIsInHistory(false); - setResult(aConstr2, 1); - } + if(!aSketch) { + return; } -} -AISObjectPtr SketchPlugin_Circle::getAISObject(AISObjectPtr thePrevious) -{ - SketchPlugin_Sketch* aSketch = sketch(); - if (aSketch) { - // compute a circle point in 3D view - std::shared_ptr aCenterAttr = std::dynamic_pointer_cast< - GeomDataAPI_Point2D>(data()->attribute(CENTER_ID())); - AttributeDoublePtr aRadiusAttr = - std::dynamic_pointer_cast(attribute(RADIUS_ID())); - if (aCenterAttr->isInitialized() && aRadiusAttr->isInitialized()) { - std::shared_ptr aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y())); + // Compute a circle in 3D view. + std::shared_ptr aCenterAttr = + std::dynamic_pointer_cast(data()->attribute(CENTER_ID())); + AttributeDoublePtr aRadiusAttr = real(RADIUS_ID()); + if(!aCenterAttr->isInitialized() || !aRadiusAttr->isInitialized()) { + return; + } - // make a visible circle - std::shared_ptr aNDir = std::dynamic_pointer_cast( - aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID())); - std::shared_ptr aNormal = aNDir->dir(); + double aRadius = aRadiusAttr->value(); + if(aRadius < tolerance) { + return; + } - double aRadius = aRadiusAttr->value(); - std::shared_ptr aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircle( - aCenter, aNormal, aRadius); - if (aCircleShape && aRadius != 0) { - std::list > aShapes; - // make a visible point - std::shared_ptr aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter); - aShapes.push_back(aCenterPointShape); - aShapes.push_back(aCircleShape); + // Make a visible point. + SketchPlugin_Sketch::createPoint2DResult(this, sketch(), CENTER_ID(), 0); - std::shared_ptr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes); - AISObjectPtr anAIS = thePrevious; - if (!anAIS) - anAIS = AISObjectPtr(new GeomAPI_AISObject); - anAIS->createShape(aCompound); - anAIS->setWidth(3); - return anAIS; - } - } - } - return AISObjectPtr(); -} + // Make a visible circle. + std::shared_ptr aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y())); + std::shared_ptr aNDir = std::dynamic_pointer_cast( + aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID())); + std::shared_ptr aNormal(new GeomAPI_Dir(aNDir->x(), aNDir->y(), aNDir->z())); -void SketchPlugin_Circle::move(double theDeltaX, double theDeltaY) -{ - std::shared_ptr aData = data(); - if (!aData->isValid()) - return; + std::shared_ptr aCircleShape = + GeomAlgoAPI_EdgeBuilder::lineCircle(aCenter, aNormal, aRadius); - std::shared_ptr aPoint1 = std::dynamic_pointer_cast( - aData->attribute(CENTER_ID())); - aPoint1->move(theDeltaX, theDeltaY); + std::shared_ptr aResult = document()->createConstruction(data(), 1); + aResult->setShape(aCircleShape); + aResult->setIsInHistory(false); + setResult(aResult, 1); } bool SketchPlugin_Circle::isFixed() { @@ -190,118 +103,20 @@ void SketchPlugin_Circle::attributeChanged(const std::string& theID) { // the second condition for unability to move external segments anywhere if (theID == EXTERNAL_ID() || isFixed()) { std::shared_ptr aSelection = data()->selection(EXTERNAL_ID())->value(); + if (!aSelection) { + // empty shape in selection shows that the shape is equal to context + ResultPtr anExtRes = selection(EXTERNAL_ID())->context(); + if (anExtRes) + aSelection = anExtRes->shape(); + } // update arguments due to the selection value if (aSelection && !aSelection->isNull() && aSelection->isEdge()) { std::shared_ptr anEdge( new GeomAPI_Edge(aSelection)); std::shared_ptr aCirc = anEdge->circle(); - std::shared_ptr aCenterAttr = + std::shared_ptr aCenterAttr = std::dynamic_pointer_cast(attribute(CENTER_ID())); aCenterAttr->setValue(sketch()->to2D(aCirc->center())); real(RADIUS_ID())->setValue(aCirc->radius()); } } - else if (theID == CENTER_ID() || theID == RADIUS_ID()) { - std::string aType = std::dynamic_pointer_cast( - data()->attribute(CIRCLE_TYPE()))->value(); - if (aType == CIRCLE_TYPE_THREE_POINTS()) - return; - - std::shared_ptr aCenterAttr = - std::dynamic_pointer_cast(attribute(CENTER_ID())); - if (!aCenterAttr->isInitialized()) - return; - AttributeDoublePtr aRadiusAttr = - std::dynamic_pointer_cast(attribute(RADIUS_ID())); - if (!aRadiusAttr->isInitialized()) - return; - - // check the execute() was called and the shape was built - if (!lastResult()) - return; - - data()->blockSendAttributeUpdated(true); - std::shared_ptr aFirstPnt = - std::dynamic_pointer_cast(attribute(FIRST_POINT_ID())); - std::shared_ptr aSecondPnt = - std::dynamic_pointer_cast(attribute(SECOND_POINT_ID())); - std::shared_ptr aThirdPnt = - std::dynamic_pointer_cast(attribute(THIRD_POINT_ID())); - double aRadius = aRadiusAttr->value(); - aFirstPnt->setValue(aCenterAttr->x() + aRadius, aCenterAttr->y()); - aSecondPnt->setValue(aCenterAttr->x(), aCenterAttr->y() + aRadius); - aThirdPnt->setValue(aCenterAttr->x() - aRadius, aCenterAttr->y()); - data()->blockSendAttributeUpdated(false); - } - else if (theID == FIRST_POINT_ID() || theID == SECOND_POINT_ID() || theID == THIRD_POINT_ID()) { - std::string aType = std::dynamic_pointer_cast( - data()->attribute(CIRCLE_TYPE()))->value(); - if (aType == CIRCLE_TYPE_CENTER_AND_RADIUS()) - return; - - data()->blockSendAttributeUpdated(true); - - std::shared_ptr aPoints[3]; - int aNbInitialized = 0; - for (int i = 1; i <= 3; ++i) { - std::shared_ptr aCurPnt = - std::dynamic_pointer_cast(attribute(POINT_ID(i))); - if (aCurPnt->isInitialized()) - aPoints[aNbInitialized++] = aCurPnt->pnt(); - } - - std::shared_ptr aCenterAttr = std::dynamic_pointer_cast< - GeomDataAPI_Point2D>(data()->attribute(CENTER_ID())); - AttributeDoublePtr aRadiusAttr = - std::dynamic_pointer_cast(data()->attribute(RADIUS_ID())); - - if (aNbInitialized == 1) - aCenterAttr->setValue(aPoints[0]->x(), aPoints[0]->y()); - else if (aNbInitialized == 2) { - std::shared_ptr aCoord = - aPoints[0]->xy()->added(aPoints[1]->xy())->multiplied(0.5); - double aRadius = aPoints[0]->distance(aPoints[1]) * 0.5; - aCenterAttr->setValue(aCoord->x(), aCoord->y()); - aRadiusAttr->setValue(aRadius); - } else { - std::shared_ptr aCenter; - double aRadius; - calculateCircleOnThreePoints(aPoints[0], aPoints[1], aPoints[2], aCenter, aRadius); - if (aCenter) { - aCenterAttr->setValue(aCenter->x(), aCenter->y()); - aRadiusAttr->setValue(aRadius); - } - } - - data()->blockSendAttributeUpdated(false); - } -} - - - - -// ========== Auxiliary functions ========================= -void calculateCircleOnThreePoints(const std::shared_ptr& theFirstPnt, - const std::shared_ptr& theSecondPnt, - const std::shared_ptr& theThirdPnt, - std::shared_ptr& theCenter, - double& theRadius) -{ - std::shared_ptr aVec12 = theSecondPnt->xy()->decreased(theFirstPnt->xy()); - std::shared_ptr aVec23 = theThirdPnt->xy()->decreased(theSecondPnt->xy()); - std::shared_ptr aVec31 = theFirstPnt->xy()->decreased(theThirdPnt->xy()); - // square of parallelogram - double aSquare2 = aVec12->cross(aVec23); - aSquare2 *= aSquare2 * 2.0; - if (aSquare2 < 1.e-20) - return; - // coefficients to calculate center - double aCoeff1 = aVec23->dot(aVec23) / aSquare2 * aVec12->dot(aVec31->multiplied(-1.0)); - double aCoeff2 = aVec31->dot(aVec31) / aSquare2 * aVec23->dot(aVec12->multiplied(-1.0)); - double aCoeff3 = aVec12->dot(aVec12) / aSquare2 * aVec31->dot(aVec23->multiplied(-1.0)); - // center - std::shared_ptr aCenter = theFirstPnt->xy()->multiplied(aCoeff1)->added( - theSecondPnt->xy()->multiplied(aCoeff2))->added(theThirdPnt->xy()->multiplied(aCoeff3)); - theCenter = std::shared_ptr(new GeomAPI_Pnt2d(aCenter)); - // radius - theRadius = theFirstPnt->distance(theCenter); }