X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_MacroCircle.cpp;h=b584a004eb5afae582a801a631b3771df3973b30;hb=12d2b665d46564704a8d0e94e3250abcf4b19dc1;hp=b865ec374d61420e52b206ee2984e08d2e79c00d;hpb=a87ec82289d152ffd66b1cb7133bfb5cbfe92281;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_MacroCircle.cpp b/src/SketchPlugin/SketchPlugin_MacroCircle.cpp index b865ec374..b584a004e 100644 --- a/src/SketchPlugin/SketchPlugin_MacroCircle.cpp +++ b/src/SketchPlugin/SketchPlugin_MacroCircle.cpp @@ -1,8 +1,22 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> - -// File: SketchPlugin_MacroCircle.cpp -// Created: 26 May 2014 -// Author: Artem ZHIDKOV +// 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 "SketchPlugin_MacroCircle.h" @@ -25,6 +39,7 @@ #include #include +#include #include #include #include @@ -96,16 +111,16 @@ void SketchPlugin_MacroCircle::execute() // message to init reentrant operation static Events_ID anId = SketchPlugin_MacroArcReentrantMessage::eventId(); std::shared_ptr aMessage = std::shared_ptr - (new SketchPlugin_MacroArcReentrantMessage(anId, 0)); + (new SketchPlugin_MacroArcReentrantMessage(anId, this)); std::string anEditType = string(EDIT_CIRCLE_TYPE())->value(); aMessage->setTypeOfCreation(!anEditType.empty() ? anEditType : aType); aMessage->setCreatedFeature(aCircle); Events_Loop::loop()->send(aMessage); - Events_Loop::loop()->flush(anId); } -std::string SketchPlugin_MacroCircle::processEvent(const std::shared_ptr& theMessage) +std::string SketchPlugin_MacroCircle::processEvent( + const std::shared_ptr& theMessage) { std::string aFilledAttributeName; std::shared_ptr aReentrantMessage = @@ -139,8 +154,19 @@ std::string SketchPlugin_MacroCircle::processEvent(const std::shared_ptr( attribute(aReferenceAttributeName)); if (aRefAttr.get()) { - if (anAttribute.get()) + if (anAttribute.get()) { + if (!anAttribute->owner().get() || !anAttribute->owner()->data()->isValid()) { + FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature(); + if (aCreatedFeature.get()) { + std::string anID = anAttribute->id(); + std::string anArcID; + if (anID == CENTER_POINT_ID()) + anArcID = SketchPlugin_Circle::CENTER_ID(); + anAttribute = aCreatedFeature->attribute(anArcID); + } + } aRefAttr->setAttr(anAttribute); + } else if (anObject.get()) { // if presentation of previous reentrant macro arc is used, the object is invalid, // we should use result of previous feature of the message(Arc) @@ -160,11 +186,11 @@ std::string SketchPlugin_MacroCircle::processEvent(const std::shared_ptrattribute(SketchPlugin_Circle::CENTER_ID()), ObjectPtr(), false); - SketchPlugin_Tools::createConstraint( + SketchPlugin_Tools::createCoincidenceOrTangency( this, PASSED_POINT_REF_ID(), AttributePtr(), theCircleFeature->lastResult(), true); } @@ -177,8 +203,10 @@ void SketchPlugin_MacroCircle::constraintsForCircleByThreePoints(FeaturePtr theC // Create constraints. ResultPtr aCircleResult = theCircleFeature->lastResult(); - for (int i = 0; i < 3; ++i) - SketchPlugin_Tools::createConstraint(this, aPointRef[i], AttributePtr(), aCircleResult, true); + for (int i = 0; i < 3; ++i) { + SketchPlugin_Tools::createCoincidenceOrTangency( + this, aPointRef[i], AttributePtr(), aCircleResult, true); + } } FeaturePtr SketchPlugin_MacroCircle::createCircleFeature() @@ -201,23 +229,35 @@ void SketchPlugin_MacroCircle::fillByCenterAndPassed() if (!aCenterAttr->isInitialized() || !aPassedAttr->isInitialized()) return; - AttributeRefAttrPtr aPassedRef = refattr(PASSED_POINT_REF_ID()); // Calculate circle parameters - std::shared_ptr aCenter = - std::dynamic_pointer_cast(aCenterAttr)->pnt(); + AttributeRefAttrPtr aCenterRef = refattr(CENTER_POINT_REF_ID()); + std::shared_ptr aCenter; + std::shared_ptr aCurve; + SketchPlugin_Tools::convertRefAttrToPointOrTangentCurve( + aCenterRef, aCenterAttr, aCurve, aCenter); + if (!aCenter) + aCenter = std::dynamic_pointer_cast(aCenterAttr)->pnt(); + AttributeRefAttrPtr aPassedRef = refattr(PASSED_POINT_REF_ID()); std::shared_ptr aPassedPoint; std::shared_ptr aTangentCurve; SketchPlugin_Tools::convertRefAttrToPointOrTangentCurve( aPassedRef, aPassedAttr, aTangentCurve, aPassedPoint); // Build a circle - std::shared_ptr aCircle; + GeomAlgoAPI_Circ2dBuilder aCircBuilder(SketchPlugin_Sketch::plane(sketch())); + aCircBuilder.setCenter(aCenter); if (aTangentCurve) { - std::shared_ptr anAxis = SketchPlugin_Sketch::plane(sketch()); - aCircle = std::shared_ptr(new GeomAPI_Circ2d(aCenter, aTangentCurve, anAxis)); + aCircBuilder.addTangentCurve(aTangentCurve); + + AttributePoint2DPtr aPassedPntAttr = + std::dynamic_pointer_cast(aPassedAttr); + if (aPassedPntAttr) + aCircBuilder.setClosestPoint(aPassedPntAttr->pnt()); } else - aCircle = std::shared_ptr(new GeomAPI_Circ2d(aCenter, aPassedPoint)); - if (aCircle->implPtr()) { + aCircBuilder.addPassingPoint(aPassedPoint); + + std::shared_ptr aCircle = aCircBuilder.circle(); + if (aCircle) { myCenter = aCircle->center(); myRadius = aCircle->radius(); } @@ -231,7 +271,9 @@ void SketchPlugin_MacroCircle::fillByThreePoints() std::string aPointRef[3] = { FIRST_POINT_REF_ID(), SECOND_POINT_REF_ID(), THIRD_POINT_REF_ID() }; - std::shared_ptr aPassedEntities[3]; + + GeomAlgoAPI_Circ2dBuilder aCircBuilder(SketchPlugin_Sketch::plane(sketch())); + for (int aPntIndex = 0; aPntIndex < 3; ++aPntIndex) { AttributePtr aPassedAttr = attribute(aPointAttr[aPntIndex]); if (!aPassedAttr->isInitialized()) @@ -245,15 +287,18 @@ void SketchPlugin_MacroCircle::fillByThreePoints() aPassedRef, aPassedAttr, aTangentCurve, aPassedPoint); if (aPassedPoint) - aPassedEntities[aPntIndex] = aPassedPoint; - else - aPassedEntities[aPntIndex] = aTangentCurve; + aCircBuilder.addPassingPoint(aPassedPoint); + else { + aCircBuilder.addTangentCurve(aTangentCurve); + AttributePoint2DPtr aPassedPoint = + std::dynamic_pointer_cast(aPassedAttr); + if (aPassedPoint) + aCircBuilder.setClosestPoint(aPassedPoint->pnt()); + } } - std::shared_ptr anAxis = SketchPlugin_Sketch::plane(sketch()); - std::shared_ptr aCircle = std::shared_ptr( - new GeomAPI_Circ2d(aPassedEntities[0], aPassedEntities[1], aPassedEntities[2], anAxis)); - if (aCircle->implPtr()) { + std::shared_ptr aCircle = aCircBuilder.circle(); + if (aCircle) { myCenter = aCircle->center(); myRadius = aCircle->radius(); } @@ -265,8 +310,11 @@ void SketchPlugin_MacroCircle::fillByTwoPassedPoints() SECOND_POINT_ID() }; std::string aPointRef[2] = { FIRST_POINT_REF_ID(), SECOND_POINT_REF_ID() }; + + GeomAlgoAPI_Circ2dBuilder aCircBuilder(SketchPlugin_Sketch::plane(sketch())); + std::shared_ptr aPassedPoints[2]; // there is possible only two passed points - std::shared_ptr aPassedEntities[3]; + bool hasTangentCurve = false; int aPntIndex = 0; for (; aPntIndex < 2; ++aPntIndex) { AttributePtr aPassedAttr = attribute(aPointAttr[aPntIndex]); @@ -281,31 +329,33 @@ void SketchPlugin_MacroCircle::fillByTwoPassedPoints() aPassedRef, aPassedAttr, aTangentCurve, aPassedPoint); if (aPassedPoint) { - aPassedEntities[aPntIndex] = aPassedPoint; + aCircBuilder.addPassingPoint(aPassedPoint); aPassedPoints[aPntIndex] = aPassedPoint; } else { - aPassedEntities[aPntIndex] = aTangentCurve; + hasTangentCurve = true; + aCircBuilder.addTangentCurve(aTangentCurve); // if the circle is tangent to any curve, // the third point will be initialized by the tangent point - aPassedEntities[2] = std::dynamic_pointer_cast(aPassedAttr)->pnt(); + aCircBuilder.addPassingPoint( + std::dynamic_pointer_cast(aPassedAttr)->pnt()); } } if (aPntIndex <= 1) return; std::shared_ptr aCircle; - if (aPassedEntities[2]) { - std::shared_ptr anAxis = SketchPlugin_Sketch::plane(sketch()); - aCircle = std::shared_ptr( - new GeomAPI_Circ2d(aPassedEntities[0], aPassedEntities[1], aPassedEntities[2], anAxis)); - } else { + + if (hasTangentCurve) + aCircle = aCircBuilder.circle(); + else { // the circle is defined by two points, calculate its parameters manually std::shared_ptr aCenter(new GeomAPI_Pnt2d( (aPassedPoints[0]->x() + aPassedPoints[1]->x()) * 0.5, (aPassedPoints[0]->y() + aPassedPoints[1]->y()) * 0.5)); aCircle = std::shared_ptr(new GeomAPI_Circ2d(aCenter, aPassedPoints[0])); } - if (aCircle->implPtr()) { + + if (aCircle) { myCenter = aCircle->center(); myRadius = aCircle->radius(); } @@ -382,6 +432,11 @@ void SketchPlugin_MacroCircle::attributeChanged(const std::string& theID) { AttributeDoublePtr aRadiusAttr = real(CIRCLE_RADIUS_ID()); bool aWasBlocked = data()->blockSendAttributeUpdated(true); + if(myCenter.get()) { + // center attribute is used in processEvent() to set reference to reentrant arc + std::dynamic_pointer_cast(attribute(CENTER_POINT_ID())) + ->setValue(myCenter); + } aRadiusAttr->setValue(myRadius); data()->blockSendAttributeUpdated(aWasBlocked, false); }