X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_Projection.cpp;h=afedd33e3a3fdb7f48a988a1027d4c9be05243cb;hb=cdbbde4803e9c320204d537d22af4ac7ef024962;hp=e0e6222bccc7da99c49019f70065687d0a3053c3;hpb=52b0fdb3bbe3b4ca84519c9dd752f89a73bf6c05;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Projection.cpp b/src/SketchPlugin/SketchPlugin_Projection.cpp index e0e6222bc..afedd33e3 100644 --- a/src/SketchPlugin/SketchPlugin_Projection.cpp +++ b/src/SketchPlugin/SketchPlugin_Projection.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2020 CEA/DEN, EDF R&D +// Copyright (C) 2014-2021 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 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -59,6 +60,12 @@ #include static const double tolerance = 1.e-7; +static const std::string THE_KEEP_REF("true"); + +static bool isKeepReference(AttributeStringPtr theAttr) +{ + return !theAttr || !theAttr->isInitialized() || theAttr->value() == THE_KEEP_REF; +} SketchPlugin_Projection::SketchPlugin_Projection() @@ -71,6 +78,7 @@ void SketchPlugin_Projection::initDerivedClassAttributes() { data()->addAttribute(EXTERNAL_FEATURE_ID(), ModelAPI_AttributeSelection::typeId()); data()->addAttribute(PROJECTED_FEATURE_ID(), ModelAPI_AttributeRefAttr::typeId()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PROJECTED_FEATURE_ID()); data()->attribute(PROJECTED_FEATURE_ID())->setIsArgument(false); data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId()); @@ -81,6 +89,22 @@ void SketchPlugin_Projection::initDerivedClassAttributes() ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), AUXILIARY_ID()); } +void SketchPlugin_Projection::initDerivedClassAttributes2() +{ + AttributePtr aKeepRefAttr = + data()->addAttribute(KEEP_REFERENCE_ID(), ModelAPI_AttributeString::typeId()); + if (!aKeepRefAttr->isInitialized()) { + std::dynamic_pointer_cast(aKeepRefAttr)->setValue(THE_KEEP_REF); + } + + data()->addAttribute(MAKE_FIXED(), ModelAPI_AttributeBoolean::typeId()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), MAKE_FIXED()); + + data()->addAttribute(FIXED_CONSTRAINT_ID(), ModelAPI_AttributeReference::typeId()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FIXED_CONSTRAINT_ID()); + data()->attribute(FIXED_CONSTRAINT_ID())->setIsArgument(false); +} + void SketchPlugin_Projection::execute() { AttributeRefAttrPtr aRefAttr = data()->refattr(PROJECTED_FEATURE_ID()); @@ -88,7 +112,7 @@ void SketchPlugin_Projection::execute() return; FeaturePtr aProjection = ModelAPI_Feature::feature(aRefAttr->object()); - if (!lastResult().get()) { + if (isKeepReference(string(KEEP_REFERENCE_ID())) && !lastResult().get()) { bool hasProjResult = aProjection->lastResult().get() != NULL; ResultConstructionPtr aConstr = document()->createConstruction(data()); if (hasProjResult) @@ -106,6 +130,16 @@ void SketchPlugin_Projection::execute() computeProjection(EXTERNAL_FEATURE_ID()); } +bool SketchPlugin_Projection::isMacro() const +{ + if (!data() || !data()->isValid()) + return false; + + AttributeStringPtr aKeepRefAttr = + const_cast(this)->string(KEEP_REFERENCE_ID()); + return !isKeepReference(aKeepRefAttr); +} + void SketchPlugin_Projection::attributeChanged(const std::string& theID) { if ((theID == EXTERNAL_FEATURE_ID() || theID == EXTERNAL_ID()) && !myIsComputing) { @@ -233,25 +267,52 @@ void SketchPlugin_Projection::computeProjection(const std::string& theID) if (!isProjected) return; // projection is not computed, stop processing - aProjection->boolean(COPY_ID())->setValue(true); + bool keepBackRef = isKeepReference(string(KEEP_REFERENCE_ID())); + + aProjection->boolean(COPY_ID())->setValue(keepBackRef); aProjection->execute(); aRefAttr->setObject(aProjection); restoreCurrentFeature(); - if (theID == EXTERNAL_FEATURE_ID()) { - selection(EXTERNAL_ID())->selectValue(aExtFeature); + AttributeBooleanPtr aMakeFixedAttr = boolean(MAKE_FIXED()); + bool isMakeFixed = aMakeFixedAttr && aMakeFixedAttr->isInitialized() && aMakeFixedAttr->value(); + + AttributeReferencePtr aFixedConstrAttr = reference(FIXED_CONSTRAINT_ID()); + FeaturePtr aFixedConstraint; + if (aFixedConstrAttr && aFixedConstrAttr->isInitialized()) + aFixedConstraint = ModelAPI_Feature::feature(aFixedConstrAttr->value()); - if (aResult) { - aResult->setShape(aProjection->lastResult()->shape()); - setResult(aResult); - GeomShapePtr anEmptyVal; - aProjection->selection(EXTERNAL_ID())->setValue(lastResult(), anEmptyVal); + if (keepBackRef) { + if (theID == EXTERNAL_FEATURE_ID()) { + selection(EXTERNAL_ID())->selectValue(aExtFeature); - static const Events_ID anEvent = Events_Loop::eventByName(EVENT_VISUAL_ATTRIBUTES); - ModelAPI_EventCreator::get()->sendUpdated(aProjection, anEvent, false); + if (aResult) { + aResult->setShape(aProjection->lastResult()->shape()); + setResult(aResult); + GeomShapePtr anEmptyVal; + aProjection->selection(EXTERNAL_ID())->setValue(lastResult(), anEmptyVal); + } } } + else if (isMakeFixed) { + // fix the projected entity with the Fixed constraint + if (!aFixedConstraint) + aFixedConstraint = sketch()->addFeature(SketchPlugin_ConstraintRigid::ID()); + aFixedConstraint->refattr(SketchPlugin_Constraint::ENTITY_A())->setObject( + aProjection->lastResult()); + } + + + // remove Fixed constraint in case of redundance + if (aFixedConstraint && (keepBackRef || !isMakeFixed)) { + document()->removeFeature(aFixedConstraint); + aFixedConstraint = FeaturePtr(); + } + aFixedConstrAttr->setValue(aFixedConstraint); + + static const Events_ID anEvent = Events_Loop::eventByName(EVENT_VISUAL_ATTRIBUTES); + ModelAPI_EventCreator::get()->sendUpdated(aProjection, anEvent, false); } bool SketchPlugin_Projection::rebuildProjectedFeature( @@ -334,7 +395,7 @@ bool SketchPlugin_Projection::projectEdge(FeaturePtr& theProjection, const GeomE if (aProjectedCurve->isCircle()) { if (aProjectedCurve->isTrimmed()) { // ARC is a projection - isOk = fillArc(theProjection, aProjectedCurve, aSketchPlane); + isOk = fillArc(theProjection, aProjectedCurve, aSketchPlane, theEdge); } else { // CIRCLE is a projection @@ -344,7 +405,7 @@ bool SketchPlugin_Projection::projectEdge(FeaturePtr& theProjection, const GeomE else if (aProjectedCurve->isEllipse()) { if (aProjectedCurve->isTrimmed()) { // ELLIPTIC ARC is a projection - isOk = fillEllipticArc(theProjection, aProjectedCurve, aSketchPlane); + isOk = fillEllipticArc(theProjection, aProjectedCurve, aSketchPlane, theEdge); } else { // ELLIPSE is a projection @@ -359,7 +420,8 @@ bool SketchPlugin_Projection::projectEdge(FeaturePtr& theProjection, const GeomE bool SketchPlugin_Projection::fillArc(FeaturePtr& theProjection, const GeomCurvePtr& theArc, - const GeomPlanePtr& thePlane) + const GeomPlanePtr& thePlane, + const GeomEdgePtr& theOriginalEdge) { rebuildProjectedFeature(theProjection, ARC_PROJECTION(), SketchPlugin_Arc::ID()); @@ -371,6 +433,13 @@ bool SketchPlugin_Projection::fillArc(FeaturePtr& theProjection, bool isInversed = aNormalsDot < 0.; + GeomCirclePtr anOriginalCircle = theOriginalEdge->circle(); + if (anOriginalCircle) { + double aCirclesDot = anOriginalCircle->normal()->dot(aCircle.normal()); + if (aCirclesDot < 0.) + isInversed = !isInversed; + } + GeomPointPtr aCenter = thePlane->project(aCircle.center()); GeomPnt2dPtr aCenterInSketch = sketch()->to2D(aCenter); @@ -447,7 +516,8 @@ bool SketchPlugin_Projection::fillEllipse(FeaturePtr& theProjection, bool SketchPlugin_Projection::fillEllipticArc(FeaturePtr& theProjection, const GeomCurvePtr& theEllipticArc, - const GeomPlanePtr& thePlane) + const GeomPlanePtr& thePlane, + const GeomEdgePtr& theOriginalEdge) { rebuildProjectedFeature(theProjection, ARC_PROJECTION(), SketchPlugin_EllipticArc::ID()); @@ -459,6 +529,13 @@ bool SketchPlugin_Projection::fillEllipticArc(FeaturePtr& theProjection, bool isInversed = aNormalsDot < 0.; + GeomEllipsePtr anOriginalEllipse = theOriginalEdge->ellipse(); + if (anOriginalEllipse) { + double anEllipsesDot = anOriginalEllipse->normal()->dot(anEllipse.normal()); + if (anEllipsesDot < 0.) + isInversed = !isInversed; + } + GeomPointPtr aCenter = thePlane->project(anEllipse.center()); GeomPnt2dPtr aCenterInSketch = sketch()->to2D(aCenter); GeomPointPtr aFocus = thePlane->project(anEllipse.firstFocus());