X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_MacroCircle.cpp;h=e0c178ddd78f70f2a940676330d8b2a8bbd3e132;hb=86cf314c1ec34383f29d0948c894579de3372b1e;hp=b545ccdd24a2ee61bc45c4c6306118f9ec002408;hpb=7ce002afbdd690bc3b278a15fe88439af53ac9e7;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_MacroCircle.cpp b/src/SketchPlugin/SketchPlugin_MacroCircle.cpp index b545ccdd2..e0c178ddd 100644 --- a/src/SketchPlugin/SketchPlugin_MacroCircle.cpp +++ b/src/SketchPlugin/SketchPlugin_MacroCircle.cpp @@ -9,22 +9,23 @@ #include "SketchPlugin_Circle.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 @@ -49,13 +50,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()); @@ -72,82 +74,164 @@ 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; +} + +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); +} - thePassingPoint = std::dynamic_pointer_cast(anAttr)->pnt(); +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; + 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)); - } else - aCircle = std::shared_ptr(new GeomAPI_Circ2d(aCenter, aPassedPoint)); + aCircBuilder.addTangentCurve(aTangentCurve); - // Create circle feature. - FeaturePtr aCircleFeature = createCircleFeature(aCircle); + AttributePoint2DPtr aPassedPntAttr = + std::dynamic_pointer_cast(aPassedAttr); + if (aPassedPntAttr) + aCircBuilder.setClosestPoint(aPassedPntAttr->pnt()); + } else + aCircBuilder.addPassingPoint(aPassedPoint); - // 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); + std::shared_ptr aCircle = aCircBuilder.circle(); + if (aCircle) { + myCenter = aCircle->center(); + myRadius = aCircle->radius(); + } } -void SketchPlugin_MacroCircle::createCircleByThreePoints() +void SketchPlugin_MacroCircle::fillByThreePoints() { std::string aPointAttr[3] = { FIRST_POINT_ID(), SECOND_POINT_ID(), @@ -155,57 +239,100 @@ void SketchPlugin_MacroCircle::createCircleByThreePoints() std::string aPointRef[3] = { FIRST_POINT_REF_ID(), 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]); + + GeomAlgoAPI_Circ2dBuilder aCircBuilder(SketchPlugin_Sketch::plane(sketch())); + + 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; - else - aPassedEntities[i] = 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)); - - // 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); + std::shared_ptr aCircle = aCircBuilder.circle(); + if (aCircle) { + 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() }; + + GeomAlgoAPI_Circ2dBuilder aCircBuilder(SketchPlugin_Sketch::plane(sketch())); + + std::shared_ptr aPassedPoints[2]; // there is possible only two passed points + bool hasTangentCurve = false; + 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) { + aCircBuilder.addPassingPoint(aPassedPoint); + aPassedPoints[aPntIndex] = aPassedPoint; + } else { + hasTangentCurve = true; + aCircBuilder.addTangentCurve(aTangentCurve); + // if the circle is tangent to any curve, + // the third point will be initialized by the tangent point + aCircBuilder.addPassingPoint( + std::dynamic_pointer_cast(aPassedAttr)->pnt()); + } + } + if (aPntIndex <= 1) + return; + + std::shared_ptr aCircle; + + 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) { + 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(); } @@ -235,39 +362,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()) { - 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()); - } else if(aType == CIRCLE_TYPE_BY_THREE_POINTS()) { - 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()); - } - 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) { @@ -277,21 +390,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());