X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_MacroCircle.cpp;h=0310207db3954ce6be56f2f2a96883bdfe57ef9a;hb=205dad6e3d828218e87f8dc050a41cb1af7eaa65;hp=375fec58813de9bd1457a0d19192ca2d23130620;hpb=0a88f0478c0d467fd412f5337775ee7353665537;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_MacroCircle.cpp b/src/SketchPlugin/SketchPlugin_MacroCircle.cpp index 375fec588..0310207db 100644 --- a/src/SketchPlugin/SketchPlugin_MacroCircle.cpp +++ b/src/SketchPlugin/SketchPlugin_MacroCircle.cpp @@ -7,29 +7,27 @@ #include "SketchPlugin_MacroCircle.h" #include "SketchPlugin_Circle.h" -//#include "SketchPlugin_ConstraintCoincidence.h" #include "SketchPlugin_Point.h" #include "SketchPlugin_Tools.h" +#include "SketchPlugin_MacroArcReentrantMessage.h" -#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 const double tolerance = 1e-7; @@ -38,9 +36,9 @@ namespace { static const std::string& POINT_ID(int theIndex) { switch (theIndex) { - case 1: return SketchPlugin_MacroCircle::FIRST_POINT_ID(); - case 2: return SketchPlugin_MacroCircle::SECOND_POINT_ID(); - case 3: return SketchPlugin_MacroCircle::THIRD_POINT_ID(); + case 1: return SketchPlugin_MacroCircle::FIRST_POINT_ID(); + case 2: return SketchPlugin_MacroCircle::SECOND_POINT_ID(); + case 3: return SketchPlugin_MacroCircle::THIRD_POINT_ID(); } static const std::string DUMMY; @@ -51,13 +49,14 @@ namespace { SketchPlugin_MacroCircle::SketchPlugin_MacroCircle() : SketchPlugin_SketchEntity(), -myRadius(0) + myRadius(0.0) { } void SketchPlugin_MacroCircle::initAttributes() { data()->addAttribute(CIRCLE_TYPE(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(EDIT_CIRCLE_TYPE(), ModelAPI_AttributeString::typeId()); data()->addAttribute(CENTER_POINT_ID(), GeomDataAPI_Point2D::typeId()); data()->addAttribute(CENTER_POINT_REF_ID(), ModelAPI_AttributeRefAttr::typeId()); @@ -74,56 +73,142 @@ void SketchPlugin_MacroCircle::initAttributes() data()->addAttribute(CIRCLE_RADIUS_ID(), ModelAPI_AttributeDouble::typeId()); data()->addAttribute(AUXILIARY_ID(), ModelAPI_AttributeBoolean::typeId()); + string(EDIT_CIRCLE_TYPE())->setValue(""); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CENTER_POINT_REF_ID()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PASSED_POINT_REF_ID()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FIRST_POINT_REF_ID()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SECOND_POINT_REF_ID()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), THIRD_POINT_REF_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EDIT_CIRCLE_TYPE()); } void SketchPlugin_MacroCircle::execute() { + FeaturePtr aCircle = createCircleFeature(); + std::string aType = string(CIRCLE_TYPE())->value(); if (aType == CIRCLE_TYPE_BY_CENTER_AND_PASSED_POINTS()) - createCircleByCenterAndPassed(); + constraintsForCircleByCenterAndPassed(aCircle); else if (aType == CIRCLE_TYPE_BY_THREE_POINTS()) - createCircleByThreePoints(); + constraintsForCircleByThreePoints(aCircle); + + // message to init reentrant operation + static Events_ID anId = SketchPlugin_MacroArcReentrantMessage::eventId(); + std::shared_ptr aMessage = std::shared_ptr + (new SketchPlugin_MacroArcReentrantMessage(anId, 0)); - myCenter.reset(); - myRadius = 0; + std::string anEditType = string(EDIT_CIRCLE_TYPE())->value(); + aMessage->setTypeOfCreation(!anEditType.empty() ? anEditType : aType); + aMessage->setCreatedFeature(aCircle); + Events_Loop::loop()->send(aMessage); } -static void convertToPointOrTangent(const AttributeRefAttrPtr& theRefAttr, - const AttributePtr& theBaseAttr, - std::shared_ptr& thePassingPoint, - std::shared_ptr& theTangentCurve) +std::string SketchPlugin_MacroCircle::processEvent( + const std::shared_ptr& theMessage) { - AttributePtr anAttr = theBaseAttr; - if (theRefAttr->isObject()) { - FeaturePtr aTgFeature = ModelAPI_Feature::feature(theRefAttr->object()); - if (aTgFeature) { - if (aTgFeature->getKind() != SketchPlugin_Point::ID()) { - theTangentCurve = aTgFeature->lastResult()->shape(); - return; + std::string aFilledAttributeName; + std::shared_ptr aReentrantMessage = + std::dynamic_pointer_cast(theMessage); + if (aReentrantMessage.get()) { + FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature(); + std::string aCircleType = aReentrantMessage->typeOfCreation(); + + string(CIRCLE_TYPE())->setValue(aCircleType); + + aFilledAttributeName = CIRCLE_TYPE(); + ObjectPtr anObject = aReentrantMessage->selectedObject(); + AttributePtr anAttribute = aReentrantMessage->selectedAttribute(); + std::shared_ptr aClickedPoint = aReentrantMessage->clickedPoint(); + + if (aClickedPoint.get() && (anObject.get() || anAttribute.get())) { + std::string aReferenceAttributeName; + if (aCircleType == CIRCLE_TYPE_BY_CENTER_AND_PASSED_POINTS()) { + aFilledAttributeName = CENTER_POINT_ID(); + aReferenceAttributeName = CENTER_POINT_REF_ID(); + } + else { + aFilledAttributeName = FIRST_POINT_ID(); + aReferenceAttributeName = FIRST_POINT_REF_ID(); + } + // fill 2d point attribute + AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast( + attribute(aFilledAttributeName)); + aPointAttr->setValue(aClickedPoint); + // fill reference attribute + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( + attribute(aReferenceAttributeName)); + if (aRefAttr.get()) { + if (anAttribute.get()) + 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) + if (!anObject->data()->isValid()) { + FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature(); + anObject = aCreatedFeature->lastResult(); + } + aRefAttr->setObject(anObject); + } } - anAttr = aTgFeature->attribute(SketchPlugin_Point::COORD_ID()); } - } else - anAttr = theRefAttr->attr(); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); + } + return aFilledAttributeName; +} - thePassingPoint = std::dynamic_pointer_cast(anAttr)->pnt(); +void SketchPlugin_MacroCircle::constraintsForCircleByCenterAndPassed(FeaturePtr theCircleFeature) +{ + // Create constraints. + SketchPlugin_Tools::createConstraint( + this, CENTER_POINT_REF_ID(), + theCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID()), + ObjectPtr(), false); + SketchPlugin_Tools::createConstraint( + this, PASSED_POINT_REF_ID(), AttributePtr(), + theCircleFeature->lastResult(), true); +} + +void SketchPlugin_MacroCircle::constraintsForCircleByThreePoints(FeaturePtr theCircleFeature) +{ + std::string aPointRef[3] = { FIRST_POINT_REF_ID(), + SECOND_POINT_REF_ID(), + THIRD_POINT_REF_ID() }; + + // Create constraints. + ResultPtr aCircleResult = theCircleFeature->lastResult(); + for (int i = 0; i < 3; ++i) + SketchPlugin_Tools::createConstraint(this, aPointRef[i], AttributePtr(), aCircleResult, true); +} + +FeaturePtr SketchPlugin_MacroCircle::createCircleFeature() +{ + FeaturePtr aCircleFeature = sketch()->addFeature(SketchPlugin_Circle::ID()); + std::dynamic_pointer_cast( + aCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID()))->setValue(myCenter->x(), + myCenter->y()); + aCircleFeature->real(SketchPlugin_Circle::RADIUS_ID())->setValue(myRadius); + aCircleFeature->boolean(SketchPlugin_Circle::AUXILIARY_ID()) + ->setValue(boolean(AUXILIARY_ID())->value()); + aCircleFeature->execute(); + return aCircleFeature; } -void SketchPlugin_MacroCircle::createCircleByCenterAndPassed() +void SketchPlugin_MacroCircle::fillByCenterAndPassed() { + AttributePtr aCenterAttr = attribute(CENTER_POINT_ID()); AttributePtr aPassedAttr = attribute(PASSED_POINT_ID()); + if (!aCenterAttr->isInitialized() || !aPassedAttr->isInitialized()) + return; + AttributeRefAttrPtr aPassedRef = refattr(PASSED_POINT_REF_ID()); // Calculate circle parameters std::shared_ptr aCenter = - std::dynamic_pointer_cast(attribute(CENTER_POINT_ID()))->pnt(); + std::dynamic_pointer_cast(aCenterAttr)->pnt(); std::shared_ptr aPassedPoint; std::shared_ptr aTangentCurve; - convertToPointOrTangent(aPassedRef, aPassedAttr, aPassedPoint, aTangentCurve); + SketchPlugin_Tools::convertRefAttrToPointOrTangentCurve( + aPassedRef, aPassedAttr, aTangentCurve, aPassedPoint); // Build a circle std::shared_ptr aCircle; @@ -132,24 +217,13 @@ void SketchPlugin_MacroCircle::createCircleByCenterAndPassed() aCircle = std::shared_ptr(new GeomAPI_Circ2d(aCenter, aTangentCurve, anAxis)); } else aCircle = std::shared_ptr(new GeomAPI_Circ2d(aCenter, aPassedPoint)); - - // Create circle feature. - FeaturePtr aCircleFeature = createCircleFeature(aCircle); - - // Create constraints. - SketchPlugin_Tools::createConstraint(this, - CENTER_POINT_REF_ID(), - aCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID()), - NULL, - false); - SketchPlugin_Tools::createConstraint(this, - PASSED_POINT_REF_ID(), - NULL, - aCircleFeature->lastResult(), - true); + if (aCircle->implPtr()) { + myCenter = aCircle->center(); + myRadius = aCircle->radius(); + } } -void SketchPlugin_MacroCircle::createCircleByThreePoints() +void SketchPlugin_MacroCircle::fillByThreePoints() { std::string aPointAttr[3] = { FIRST_POINT_ID(), SECOND_POINT_ID(), @@ -158,56 +232,89 @@ void SketchPlugin_MacroCircle::createCircleByThreePoints() SECOND_POINT_REF_ID(), THIRD_POINT_REF_ID() }; std::shared_ptr aPassedEntities[3]; - for (int i = 0; i < 3; ++i) { - AttributePtr aPassedAttr = attribute(aPointAttr[i]); - AttributeRefAttrPtr aPassedRef = refattr(aPointRef[i]); + for (int aPntIndex = 0; aPntIndex < 3; ++aPntIndex) { + AttributePtr aPassedAttr = attribute(aPointAttr[aPntIndex]); + if (!aPassedAttr->isInitialized()) + break; + + AttributeRefAttrPtr aPassedRef = refattr(aPointRef[aPntIndex]); // calculate circle parameters std::shared_ptr aPassedPoint; std::shared_ptr aTangentCurve; - convertToPointOrTangent(aPassedRef, aPassedAttr, aPassedPoint, aTangentCurve); + SketchPlugin_Tools::convertRefAttrToPointOrTangentCurve( + aPassedRef, aPassedAttr, aTangentCurve, aPassedPoint); if (aPassedPoint) - aPassedEntities[i] = aPassedPoint; + aPassedEntities[aPntIndex] = aPassedPoint; else - aPassedEntities[i] = aTangentCurve; + aPassedEntities[aPntIndex] = aTangentCurve; } 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)); - - // Create circle feature. - FeaturePtr aCircleFeature = createCircleFeature(aCircle); - ResultPtr aCircleResult = aCircleFeature->lastResult(); - - // Create constraints. - for (int i = 0; i < 3; ++i) - SketchPlugin_Tools::createConstraint(this, aPointRef[i], NULL, aCircleResult, true); + if (aCircle->implPtr()) { + myCenter = aCircle->center(); + myRadius = aCircle->radius(); + } } -FeaturePtr SketchPlugin_MacroCircle::createCircleFeature( - const std::shared_ptr& theCircle) +void SketchPlugin_MacroCircle::fillByTwoPassedPoints() { - FeaturePtr aCircleFeature = sketch()->addFeature(SketchPlugin_Circle::ID()); - std::shared_ptr aCenter = theCircle->center(); - std::dynamic_pointer_cast( - aCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID()))->setValue(aCenter->x(), - aCenter->y()); - aCircleFeature->real(SketchPlugin_Circle::RADIUS_ID())->setValue(theCircle->radius()); - aCircleFeature->boolean(SketchPlugin_Circle::AUXILIARY_ID()) - ->setValue(boolean(AUXILIARY_ID())->value()); - aCircleFeature->execute(); - return aCircleFeature; + std::string aPointAttr[2] = { FIRST_POINT_ID(), + SECOND_POINT_ID() }; + std::string aPointRef[2] = { FIRST_POINT_REF_ID(), + SECOND_POINT_REF_ID() }; + std::shared_ptr aPassedPoints[2]; // there is possible only two passed points + std::shared_ptr aPassedEntities[3]; + int aPntIndex = 0; + for (; aPntIndex < 2; ++aPntIndex) { + AttributePtr aPassedAttr = attribute(aPointAttr[aPntIndex]); + if (!aPassedAttr->isInitialized()) + break; + + AttributeRefAttrPtr aPassedRef = refattr(aPointRef[aPntIndex]); + // calculate circle parameters + std::shared_ptr aPassedPoint; + std::shared_ptr aTangentCurve; + SketchPlugin_Tools::convertRefAttrToPointOrTangentCurve( + aPassedRef, aPassedAttr, aTangentCurve, aPassedPoint); + + if (aPassedPoint) { + aPassedEntities[aPntIndex] = aPassedPoint; + aPassedPoints[aPntIndex] = aPassedPoint; + } else { + aPassedEntities[aPntIndex] = 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(); + } + } + 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 { + // 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()) { + myCenter = aCircle->center(); + myRadius = aCircle->radius(); + } } AISObjectPtr SketchPlugin_MacroCircle::getAISObject(AISObjectPtr thePrevious) { - if(!myCenter.get() || myRadius < tolerance) { - return AISObjectPtr(); - } - SketchPlugin_Sketch* aSketch = sketch(); - if(!aSketch) { + if(!aSketch || !myCenter || myRadius == 0) { return AISObjectPtr(); } @@ -237,34 +344,25 @@ AISObjectPtr SketchPlugin_MacroCircle::getAISObject(AISObjectPtr thePrevious) } void SketchPlugin_MacroCircle::attributeChanged(const std::string& theID) { - // If circle type switched reset according attributes. + double aRadius = 0.0; + // If circle type switched reset all attributes. if(theID == CIRCLE_TYPE()) { - std::string aType = string(CIRCLE_TYPE())->value(); - if(aType == CIRCLE_TYPE_BY_CENTER_AND_PASSED_POINTS()) { - resetAttribute(CENTER_POINT_ID()); - resetAttribute(PASSED_POINT_ID()); - } else if(aType == CIRCLE_TYPE_BY_THREE_POINTS()) { - resetAttribute(FIRST_POINT_ID()); - resetAttribute(SECOND_POINT_ID()); - resetAttribute(THIRD_POINT_ID()); - } - myCenter.reset(); - myRadius = 0; - } else if(theID == CENTER_POINT_ID() || theID == PASSED_POINT_ID()) { - std::shared_ptr aCenterPointAttr = - std::dynamic_pointer_cast(attribute(CENTER_POINT_ID())); - if(!aCenterPointAttr->isInitialized()) { - return; - } - std::shared_ptr aPassedPointAttr = - std::dynamic_pointer_cast(attribute(PASSED_POINT_ID())); - if(!aPassedPointAttr->isInitialized()) { - return; - } - - myCenter = aCenterPointAttr->pnt(); - myRadius = myCenter->distance(aPassedPointAttr->pnt()); - } else if(theID == FIRST_POINT_ID() || theID == SECOND_POINT_ID() || theID == THIRD_POINT_ID()) { + SketchPlugin_Tools::resetAttribute(this, CENTER_POINT_ID()); + SketchPlugin_Tools::resetAttribute(this, CENTER_POINT_REF_ID()); + SketchPlugin_Tools::resetAttribute(this, PASSED_POINT_ID()); + SketchPlugin_Tools::resetAttribute(this, PASSED_POINT_REF_ID()); + SketchPlugin_Tools::resetAttribute(this, FIRST_POINT_ID()); + SketchPlugin_Tools::resetAttribute(this, FIRST_POINT_REF_ID()); + SketchPlugin_Tools::resetAttribute(this, SECOND_POINT_ID()); + SketchPlugin_Tools::resetAttribute(this, SECOND_POINT_REF_ID()); + SketchPlugin_Tools::resetAttribute(this, THIRD_POINT_ID()); + SketchPlugin_Tools::resetAttribute(this, THIRD_POINT_REF_ID()); + } else if(theID == CENTER_POINT_ID() || theID == PASSED_POINT_ID() || + theID == CENTER_POINT_REF_ID() || theID == PASSED_POINT_REF_ID()) + fillByCenterAndPassed(); + else if(theID == FIRST_POINT_ID() || theID == FIRST_POINT_REF_ID() || + theID == SECOND_POINT_ID() || theID == SECOND_POINT_REF_ID() || + theID == THIRD_POINT_ID() || theID == THIRD_POINT_REF_ID()) { std::shared_ptr aPoints[3]; int aNbInitialized = 0; for(int i = 1; i <= 3; ++i) { @@ -274,21 +372,12 @@ void SketchPlugin_MacroCircle::attributeChanged(const std::string& theID) { aPoints[aNbInitialized++] = aCurPnt->pnt(); } - if(aNbInitialized == 1) { + if(aNbInitialized == 1) return; - } else if(aNbInitialized == 2) { - std::shared_ptr aCenterXY = - aPoints[0]->xy()->added(aPoints[1]->xy())->multiplied(0.5); - myCenter.reset(new GeomAPI_Pnt2d(aCenterXY->x(), aCenterXY->y())); - myRadius = aPoints[0]->distance(aPoints[1]) * 0.5; - } else { - std::shared_ptr aCircle( - new GeomAPI_Circ2d(aPoints[0], aPoints[1], aPoints[2])); - myCenter = aCircle->center(); - if(myCenter.get()) { - myRadius = aCircle->radius(); - } - } + else if(aNbInitialized == 2) + fillByTwoPassedPoints(); + else + fillByThreePoints(); } AttributeDoublePtr aRadiusAttr = real(CIRCLE_RADIUS_ID()); @@ -296,11 +385,3 @@ void SketchPlugin_MacroCircle::attributeChanged(const std::string& theID) { aRadiusAttr->setValue(myRadius); data()->blockSendAttributeUpdated(aWasBlocked, false); } - -void SketchPlugin_MacroCircle::resetAttribute(const std::string& theId) -{ - AttributePtr anAttr = attribute(theId); - if(anAttr.get()) { - anAttr->reset(); - } -}