-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
-
-// File: SketchPlugin_Fillet.cpp
-// Created: 19 Mar 2015
-// Author: Artem ZHIDKOV
+// Copyright (C) 2014-2019 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_Fillet.h"
#include "SketchPlugin_Line.h"
#include "SketchPlugin_Point.h"
#include "SketchPlugin_Sketch.h"
+#include "SketchPlugin_ConstraintDistance.h"
#include "SketchPlugin_ConstraintEqual.h"
#include "SketchPlugin_ConstraintCoincidence.h"
#include "SketchPlugin_ConstraintLength.h"
#include "SketchPlugin_ConstraintRadius.h"
#include "SketchPlugin_Tools.h"
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_AttributeRefAttr.h>
#include <ModelAPI_Data.h>
#include <ModelAPI_Events.h>
std::shared_ptr<GeomAPI_XY>& theTangentA,
std::shared_ptr<GeomAPI_XY>& theTangentB);
-/// Get coincide edges for fillet
-static std::set<FeaturePtr> getCoincides(const FeaturePtr& theConstraintCoincidence);
-
static std::set<FeaturePtr> findFeaturesToRemove(const FeaturePtr theFeature,
const AttributePtr theAttribute);
SketchPlugin_Fillet::SketchPlugin_Fillet()
-: myFilletCreated(false)
+: myFilletCreated(false), myIsReversed(false)
{
+ myIsNotInversed[0] = myIsNotInversed[1] = true;
}
void SketchPlugin_Fillet::initAttributes()
if (isUpdateFlushed)
Events_Loop::loop()->setFlushed(anUpdateEvent, false);
- // Calculate Fillet parameters if does not yet
- if (!myBaseFeatures[0] || !myBaseFeatures[1])
- calculateFilletParameters();
+ // set flag here to avoid building Fillet presentation if "Redisplay" event appears
+ myFilletCreated = true;
- // Create arc feature.
- FeaturePtr aFilletArc = sketch()->addFeature(SketchPlugin_Arc::ID());
+ // create feature for fillet arc
+ FeaturePtr aFilletArc = createFilletArc();
+ if (!aFilletArc) {
+ setError("Error: unable to create a fillet arc.");
+ return;
+ }
- // Set arc attributes.
- bool aWasBlocked = aFilletArc->data()->blockSendAttributeUpdated(true);
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aFilletArc->attribute(SketchPlugin_Arc::CENTER_ID()))->setValue(myCenterXY->x(),
- myCenterXY->y());
- std::shared_ptr<GeomDataAPI_Point2D> aStartPoint =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aFilletArc->attribute(SketchPlugin_Arc::START_ID()));
- std::shared_ptr<GeomDataAPI_Point2D> aEndPoint =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aFilletArc->attribute(SketchPlugin_Arc::END_ID()));
- if(aStartPoint->isInitialized() && aEndPoint->isInitialized()
- && (aStartPoint->pnt()->xy()->distance(myTangentXY1) > tolerance
- || aEndPoint->pnt()->xy()->distance(myTangentXY2) > tolerance)) {
- std::dynamic_pointer_cast<SketchPlugin_Arc>(aFilletArc)->setReversed(false);
+ // collect features referred to the edges participating in fillet
+ AttributePoint2DPtr aFilletPoints[2];
+ int aFeatInd[2];
+ int anAttrInd[2];
+ std::set<FeaturePtr> aFeaturesToBeRemoved;
+ for (int i = 0; i < 2; ++i) {
+ bool isFirstIndex = (i == 0);
+ aFeatInd[i] = myIsReversed == isFirstIndex ? 1 : 0;
+ anAttrInd[i] = (myIsReversed == isFirstIndex ? 2 : 0) + (myIsNotInversed[aFeatInd[i]] ? 0 : 1);
+ aFilletPoints[i] = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ myBaseFeatures[aFeatInd[i]]->attribute(myFeatAttributes[anAttrInd[i]]));
+ std::set<FeaturePtr> aRemove =
+ findFeaturesToRemove(myBaseFeatures[aFeatInd[i]], aFilletPoints[i]);
+ aFeaturesToBeRemoved.insert(aRemove.begin(), aRemove.end());
}
- aStartPoint->setValue(myTangentXY1->x(), myTangentXY1->y());
- aEndPoint->setValue(myTangentXY2->x(), myTangentXY2->y());
- aFilletArc->data()->blockSendAttributeUpdated(aWasBlocked);
- aFilletArc->execute();
- // Delete features with refs to points of edges.
- std::shared_ptr<GeomDataAPI_Point2D> aStartPoint1;
- int aFeatInd1 = myIsReversed ? 1 : 0;
- int anAttrInd1 = (myIsReversed ? 2 : 0) + (myIsNotInversed[aFeatInd1] ? 0 : 1);
- aStartPoint1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- myBaseFeatures[aFeatInd1]->attribute(myFeatAttributes[anAttrInd1]));
- std::set<FeaturePtr> aFeaturesToBeRemoved1 =
- findFeaturesToRemove(myBaseFeatures[aFeatInd1], aStartPoint1);
-
- std::shared_ptr<GeomDataAPI_Point2D> aStartPoint2;
- int aFeatInd2 = myIsReversed ? 0 : 1;
- int anAttrInd2 = (myIsReversed ? 0 : 2) + (myIsNotInversed[aFeatInd2] ? 0 : 1);
- aStartPoint2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- myBaseFeatures[aFeatInd2]->attribute(myFeatAttributes[anAttrInd2]));
- std::set<FeaturePtr> aFeaturesToBeRemoved2 =
- findFeaturesToRemove(myBaseFeatures[aFeatInd2], aStartPoint2);
-
- aFeaturesToBeRemoved1.insert(aFeaturesToBeRemoved2.begin(), aFeaturesToBeRemoved2.end());
- ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToBeRemoved1);
- Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
+ // keep "distance" constraints and remove all other references
+ removeReferencesButKeepDistances(aFeaturesToBeRemoved, aFilletPoints);
// Update fillet edges.
recalculateAttributes(aFilletArc, SketchPlugin_Arc::START_ID(),
- myBaseFeatures[aFeatInd1], myFeatAttributes[anAttrInd1]);
+ myBaseFeatures[aFeatInd[0]], myFeatAttributes[anAttrInd[0]]);
recalculateAttributes(aFilletArc, SketchPlugin_Arc::END_ID(),
- myBaseFeatures[aFeatInd2], myFeatAttributes[anAttrInd2]);
+ myBaseFeatures[aFeatInd[1]], myFeatAttributes[anAttrInd[1]]);
+
+ FeaturePtr aConstraint;
// Create coincidence features.
- FeaturePtr aConstraint = sketch()->addFeature(SketchPlugin_ConstraintCoincidence::ID());
- AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
- aRefAttr->setAttr(aFilletArc->attribute(SketchPlugin_Arc::START_ID()));
- aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
- aRefAttr->setAttr(myBaseFeatures[aFeatInd1]->attribute(myFeatAttributes[anAttrInd1]));
- aConstraint->execute();
+ aConstraint = SketchPlugin_Tools::createConstraintAttrAttr(sketch(),
+ SketchPlugin_ConstraintCoincidence::ID(),
+ aFilletArc->attribute(SketchPlugin_Arc::START_ID()),
+ myBaseFeatures[aFeatInd[0]]->attribute(myFeatAttributes[anAttrInd[0]]));
ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent);
- aConstraint = sketch()->addFeature(SketchPlugin_ConstraintCoincidence::ID());
- aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
- aRefAttr->setAttr(aFilletArc->attribute(SketchPlugin_Arc::END_ID()));
- aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
- aRefAttr->setAttr(myBaseFeatures[aFeatInd2]->attribute(myFeatAttributes[anAttrInd2]));
- aConstraint->execute();
+ aConstraint = SketchPlugin_Tools::createConstraintAttrAttr(sketch(),
+ SketchPlugin_ConstraintCoincidence::ID(),
+ aFilletArc->attribute(SketchPlugin_Arc::END_ID()),
+ myBaseFeatures[aFeatInd[1]]->attribute(myFeatAttributes[anAttrInd[1]]));
ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent);
// Create tangent features.
for (int i = 0; i < 2; i++) {
- aConstraint = sketch()->addFeature(SketchPlugin_ConstraintTangent::ID());
- aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
- aRefAttr->setObject(aFilletArc->lastResult());
- aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
- bool isArc = myBaseFeatures[i]->getKind() == SketchPlugin_Arc::ID();
- aRefAttr->setObject(isArc ? myBaseFeatures[i]->lastResult() :
- myBaseFeatures[i]->firstResult());
+ aConstraint = SketchPlugin_Tools::createConstraintObjectObject(sketch(),
+ SketchPlugin_ConstraintTangent::ID(),
+ aFilletArc->lastResult(),
+ myBaseFeatures[i]->lastResult());
aConstraint->execute();
ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent);
}
// Send events to update the sub-features by the solver.
- if(isUpdateFlushed) {
+ if (isUpdateFlushed)
Events_Loop::loop()->setFlushed(anUpdateEvent, true);
- }
-
- myFilletCreated = true;
}
AISObjectPtr SketchPlugin_Fillet::getAISObject(AISObjectPtr thePrevious)
anAISObject = AISObjectPtr(new GeomAPI_AISObject);
}
anAISObject->createShape(anArcShape);
+ bool isAxiliary = false;
+ AttributeBooleanPtr aAttr = boolean(AUXILIARY_ID());
+ if (aAttr.get())
+ isAxiliary = aAttr->value();
+ SketchPlugin_Tools::customizeFeaturePrs(anAISObject, isAxiliary);
return anAISObject;
}
if (!aFilletPoint2D.get())
return false;
- if (!findFeaturesContainingFilletPoint(aFilletPoint2D)) {
+ std::set<AttributePoint2DPtr> aCoincidentPoints =
+ SketchPlugin_Tools::findPointsCoincidentToPoint(aFilletPoint2D);
+ std::set<FeaturePtr> aFilletFeatures;
+ for (std::set<AttributePoint2DPtr>::iterator aCPIt = aCoincidentPoints.begin();
+ aCPIt != aCoincidentPoints.end(); ++aCPIt) {
+ std::shared_ptr<SketchPlugin_Feature> anOwner =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(
+ ModelAPI_Feature::feature((*aCPIt)->owner()));
+ if (anOwner && !anOwner->isExternal())
+ aFilletFeatures.insert(anOwner);
+ }
+ if (aFilletFeatures.size() != 2) {
setError("Error: Selected point does not have two suitable edges for fillet.");
return false;
}
+ std::set<FeaturePtr>::iterator aFIt = aFilletFeatures.begin();
+ myBaseFeatures[0] = *aFIt;
+ myBaseFeatures[1] = *(++aFIt);
+
std::shared_ptr<GeomAPI_Pnt2d> aFilletPnt2d = aFilletPoint2D->pnt();
double aRadius = calculateFilletRadius(myBaseFeatures);
return true;
}
-bool SketchPlugin_Fillet::findFeaturesContainingFilletPoint(
- std::shared_ptr<GeomDataAPI_Point2D> theFilletPoint)
+FeaturePtr SketchPlugin_Fillet::createFilletArc()
{
- // Obtain constraint coincidence for the fillet point.
- FeaturePtr aConstraintCoincidence;
- const std::set<AttributePtr>& aRefsList = theFilletPoint->owner()->data()->refsToMe();
- for(std::set<AttributePtr>::const_iterator anIt = aRefsList.cbegin();
- anIt != aRefsList.cend();
- ++anIt) {
- std::shared_ptr<ModelAPI_Attribute> anAttr = (*anIt);
- FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anAttr->owner());
- if(aFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
- AttributeRefAttrPtr anAttrRefA =
- aFeature->refattr(SketchPlugin_ConstraintCoincidence::ENTITY_A());
- AttributeRefAttrPtr anAttrRefB =
- aFeature->refattr(SketchPlugin_ConstraintCoincidence::ENTITY_B());
- if(anAttrRefA.get() && !anAttrRefA->isObject()) {
- AttributePtr anAttrA = anAttrRefA->attr();
- if(theFilletPoint == anAttrA) {
- aConstraintCoincidence = aFeature;
- break;
+ // Calculate Fillet parameters if does not yet
+ if (!myBaseFeatures[0] || !myBaseFeatures[1])
+ calculateFilletParameters();
+
+ // fix for issue #2810 (sometimes, myCenterXY is NULL, fillet should report an error)
+ if (!myCenterXY)
+ return FeaturePtr();
+
+ // Create arc feature.
+ FeaturePtr aFilletArc = sketch()->addFeature(SketchPlugin_Arc::ID());
+
+ // Set arc attributes.
+ bool aWasBlocked = aFilletArc->data()->blockSendAttributeUpdated(true);
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aFilletArc->attribute(SketchPlugin_Arc::CENTER_ID()))->setValue(myCenterXY->x(),
+ myCenterXY->y());
+ std::shared_ptr<GeomDataAPI_Point2D> aStartPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aFilletArc->attribute(SketchPlugin_Arc::START_ID()));
+ std::shared_ptr<GeomDataAPI_Point2D> aEndPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aFilletArc->attribute(SketchPlugin_Arc::END_ID()));
+ if(aStartPoint->isInitialized() && aEndPoint->isInitialized()
+ && (aStartPoint->pnt()->xy()->distance(myTangentXY1) > tolerance
+ || aEndPoint->pnt()->xy()->distance(myTangentXY2) > tolerance)) {
+ std::dynamic_pointer_cast<SketchPlugin_Arc>(aFilletArc)->setReversed(false);
+ }
+ aStartPoint->setValue(myTangentXY1->x(), myTangentXY1->y());
+ aEndPoint->setValue(myTangentXY2->x(), myTangentXY2->y());
+ aFilletArc->data()->blockSendAttributeUpdated(aWasBlocked);
+ aFilletArc->execute();
+
+ return aFilletArc;
+}
+
+FeaturePtr SketchPlugin_Fillet::createFilletApex(const GeomPnt2dPtr& theCoordinates)
+{
+ FeaturePtr anApex = sketch()->addFeature(SketchPlugin_Point::ID());
+ AttributePoint2DPtr aCoord = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ anApex->attribute(SketchPlugin_Point::COORD_ID()));
+ aCoord->setValue(theCoordinates);
+ anApex->boolean(SketchPlugin_Point::AUXILIARY_ID())->setValue(true);
+
+ // additional coincidence constraints
+ static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
+ FeaturePtr aConstraint;
+ for (int i = 0; i < 2; i++) {
+ aConstraint = SketchPlugin_Tools::createConstraintAttrObject(sketch(),
+ SketchPlugin_ConstraintCoincidence::ID(),
+ aCoord,
+ myBaseFeatures[i]->lastResult());
+ aConstraint->execute();
+ ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent);
+ }
+
+ return anApex;
+}
+
+struct Length {
+ AttributePtr myPoints[2];
+ std::string myValueText;
+ double myValueDouble;
+ GeomPnt2dPtr myFlyoutPoint;
+ int myLocationType;
+};
+
+void SketchPlugin_Fillet::removeReferencesButKeepDistances(
+ std::set<FeaturePtr>& theFeaturesToRemove,
+ const AttributePoint2DPtr theFilletPoints[2])
+{
+ FeaturePtr aFilletApex;
+ std::list<Length> aLengthToDistance;
+
+ std::set<FeaturePtr>::iterator aFeat = theFeaturesToRemove.begin();
+ while (aFeat != theFeaturesToRemove.end()) {
+ std::shared_ptr<SketchPlugin_ConstraintDistance> aDistance =
+ std::dynamic_pointer_cast<SketchPlugin_ConstraintDistance>(*aFeat);
+ if (aDistance) {
+ if (!aFilletApex)
+ aFilletApex = createFilletApex(theFilletPoints[0]->pnt());
+ // update attributes of distance constraints
+ bool isUpdated = false;
+ for (int attrInd = 0; attrInd < CONSTRAINT_ATTR_SIZE && !isUpdated; ++attrInd) {
+ AttributeRefAttrPtr aRefAttr =
+ aDistance->refattr(SketchPlugin_Constraint::ATTRIBUTE(attrInd));
+ if (aRefAttr && !aRefAttr->isObject() &&
+ (aRefAttr->attr() == theFilletPoints[0] || aRefAttr->attr() == theFilletPoints[1])) {
+ aRefAttr->setAttr(aFilletApex->attribute(SketchPlugin_Point::COORD_ID()));
+ isUpdated = true;
}
}
- if(anAttrRefB.get() && !anAttrRefB->isObject()) {
- AttributePtr anAttrB = anAttrRefB->attr();
- if(theFilletPoint == anAttrB) {
- aConstraintCoincidence = aFeature;
- break;
+ // avoid distance from removing if it is updated
+ std::set<FeaturePtr>::iterator aKeepIt = aFeat++;
+ if (isUpdated)
+ theFeaturesToRemove.erase(aKeepIt);
+
+ } else {
+ std::shared_ptr<SketchPlugin_ConstraintLength> aLength =
+ std::dynamic_pointer_cast<SketchPlugin_ConstraintLength>(*aFeat);
+ if (aLength) {
+ if (!aFilletApex)
+ aFilletApex = createFilletApex(theFilletPoints[0]->pnt());
+ // remove Length, but create new distance constraint
+ AttributeRefAttrPtr aRefAttr =
+ aLength->refattr(SketchPlugin_Constraint::ENTITY_A());
+ FeaturePtr aLine = ModelAPI_Feature::feature(aRefAttr->object());
+ if (aLine) {
+ aLengthToDistance.push_back(Length());
+ Length& aNewLength = aLengthToDistance.back();
+ // main attrbutes
+ for (int i = 0; i < 2; ++i) {
+ AttributePtr anAttr = aLine->attribute(
+ i == 0 ? SketchPlugin_Line::START_ID() : SketchPlugin_Line::END_ID());
+ if (anAttr == theFilletPoints[0] || anAttr == theFilletPoints[1])
+ aNewLength.myPoints[i] = aFilletApex->attribute(SketchPlugin_Point::COORD_ID());
+ else
+ aNewLength.myPoints[i] = anAttr;
+ }
+ // value
+ AttributeDoublePtr aValue = aLength->real(SketchPlugin_Constraint::VALUE());
+ aNewLength.myValueDouble = aValue->value();
+ aNewLength.myValueText = aValue->text();
+ // auxiliary attributes
+ AttributePoint2DPtr aFlyoutAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLength->attribute(SketchPlugin_ConstraintLength::FLYOUT_VALUE_PNT()));
+ if (aFlyoutAttr && aFlyoutAttr->isInitialized())
+ aNewLength.myFlyoutPoint = SketchPlugin_Tools::flyoutPointCoordinates(aLength);
+ AttributeIntegerPtr aLocationAttr =
+ aLength->integer(SketchPlugin_ConstraintLength::LOCATION_TYPE_ID());
+ if (aLocationAttr && aLocationAttr->isInitialized())
+ aNewLength.myLocationType = aLocationAttr->value();
+ else
+ aNewLength.myLocationType = -1;
}
}
+
+ ++aFeat;
}
}
- if(!aConstraintCoincidence.get())
- return false;
-
- // Get coincide edges.
- std::set<FeaturePtr> anEdgeFeatures = getCoincides(aConstraintCoincidence);
- std::set<FeaturePtr>::iterator aLinesIt = anEdgeFeatures.begin();
- for (int i = 0; aLinesIt != anEdgeFeatures.end() && i < 2; ++aLinesIt, ++i)
- myBaseFeatures[i] = *aLinesIt;
+ // remove references
+ ModelAPI_Tools::removeFeaturesAndReferences(theFeaturesToRemove);
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
- return myBaseFeatures[0] && myBaseFeatures[1];
+ // restore Length constraints as point-point distances
+ FeaturePtr aConstraint;
+ std::list<Length>::iterator anIt = aLengthToDistance.begin();
+ for (; anIt != aLengthToDistance.end(); ++anIt) {
+ aConstraint = SketchPlugin_Tools::createConstraintAttrAttr(sketch(),
+ SketchPlugin_ConstraintDistance::ID(), anIt->myPoints[0], anIt->myPoints[1]);
+ // set value
+ AttributeDoublePtr aValue = aConstraint->real(SketchPlugin_Constraint::VALUE());
+ if (anIt->myValueText.empty())
+ aValue->setValue(anIt->myValueDouble);
+ else
+ aValue->setText(anIt->myValueText);
+ // set flyout point if exists
+ if (anIt->myFlyoutPoint) {
+ AttributePoint2DPtr aFlyoutAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aConstraint->attribute(SketchPlugin_ConstraintDistance::FLYOUT_VALUE_PNT()));
+ aFlyoutAttr->setValue(anIt->myFlyoutPoint);
+ }
+ // set location type if initialized
+ if (anIt->myLocationType >= 0) {
+ AttributeIntegerPtr aLocationType =
+ aConstraint->integer(SketchPlugin_ConstraintDistance::LOCATION_TYPE_ID());
+ aLocationType->setValue(anIt->myLocationType);
+ }
+ aConstraint->execute();
+ ModelAPI_EventCreator::get()->sendUpdated(aConstraint,
+ Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+ }
}
// ========= Auxiliary functions =================
if (anEdge)
aLengths[i] = anEdge->length();
}
- return std::min(aLengths[0], aLengths[1]) / 6.0;
-}
-
-std::set<FeaturePtr> getCoincides(const FeaturePtr& theConstraintCoincidence)
-{
- std::set<FeaturePtr> aCoincides;
-
- std::shared_ptr<GeomAPI_Pnt2d> aFilletPnt =
- SketchPlugin_Tools::getCoincidencePoint(theConstraintCoincidence);
-
- SketchPlugin_Tools::findCoincidences(theConstraintCoincidence,
- SketchPlugin_ConstraintCoincidence::ENTITY_A(),
- aCoincides);
- SketchPlugin_Tools::findCoincidences(theConstraintCoincidence,
- SketchPlugin_ConstraintCoincidence::ENTITY_B(),
- aCoincides);
-
- // Remove points from set of coincides.
- std::set<FeaturePtr> aNewSetOfCoincides;
- for(std::set<FeaturePtr>::iterator anIt = aCoincides.begin(); anIt != aCoincides.end(); ++anIt) {
- std::shared_ptr<SketchPlugin_SketchEntity> aSketchEntity =
- std::dynamic_pointer_cast<SketchPlugin_SketchEntity>(*anIt);
- if(aSketchEntity.get() && aSketchEntity->isCopy()) {
- continue;
- }
- if((*anIt)->getKind() == SketchPlugin_Line::ID()) {
- aNewSetOfCoincides.insert(*anIt);
- } else if((*anIt)->getKind() == SketchPlugin_Arc::ID()) {
- AttributePtr anAttrCenter = (*anIt)->attribute(SketchPlugin_Arc::CENTER_ID());
- std::shared_ptr<GeomDataAPI_Point2D> aPointCenter2D =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttrCenter);
- if(aPointCenter2D.get() && aFilletPnt->isEqual(aPointCenter2D->pnt())) {
- continue;
- }
- aNewSetOfCoincides.insert(*anIt);
- }
- }
- aCoincides = aNewSetOfCoincides;
-
- // If we still have more than two coincides remove auxilary entities from set of coincides.
- if(aCoincides.size() > 2) {
- aNewSetOfCoincides.clear();
- for(std::set<FeaturePtr>::iterator
- anIt = aCoincides.begin(); anIt != aCoincides.end(); ++anIt) {
- if(!(*anIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value()) {
- aNewSetOfCoincides.insert(*anIt);
- }
- }
- aCoincides = aNewSetOfCoincides;
- }
-
- return aCoincides;
+ return (aLengths[0] < aLengths[1] ? aLengths[0] : aLengths[1]) / 6.0;
}
std::set<FeaturePtr> findFeaturesToRemove(const FeaturePtr theFeature,