-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
-
-// File: SketchPlugin_Tools.cpp
-// Created: 07 July 2015
-// Author: Sergey POKHODENKO
+// 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<mailto:webmaster.salome@opencascade.com>
+//
#include "SketchPlugin_Tools.h"
+#include "SketchPlugin_ConstraintCoincidence.h"
+#include "SketchPlugin_ConstraintTangent.h"
+#include "SketchPlugin_Point.h"
+#include "SketchPlugin_SketchEntity.h"
+
+#include <SketcherPrs_Tools.h>
+
+#include <ModelAPI_AttributeDouble.h>
+
#include <GeomDataAPI_Point.h>
#include <GeomDataAPI_Point2D.h>
-#include <ModelAPI_AttributeDouble.h>
-#include <SketcherPrs_Tools.h>
-#include <SketchPlugin_ConstraintCoincidence.h>
-#include <SketchPlugin_SketchEntity.h>
namespace SketchPlugin_Tools {
void clearExpressions(AttributePtr theAttribute)
{
// Double
- AttributeDoublePtr anAttributeDouble =
+ AttributeDoublePtr anAttributeDouble =
std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttribute);
if (anAttributeDouble.get())
clearExpressions(anAttributeDouble);
// Point
- AttributePointPtr anAttributePoint =
+ AttributePointPtr anAttributePoint =
std::dynamic_pointer_cast<GeomDataAPI_Point>(theAttribute);
if (anAttributePoint.get())
clearExpressions(anAttributePoint);
// Point2D
- AttributePoint2DPtr anAttributePoint2D =
+ AttributePoint2DPtr anAttributePoint2D =
std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
if (anAttributePoint2D.get())
clearExpressions(anAttributePoint2D);
if (!theFeature.get())
return;
- std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
+ std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
std::list<AttributePtr>::iterator anAttributeIt = anAttributes.begin();
for (; anAttributeIt != anAttributes.end(); ++anAttributeIt) {
clearExpressions(*anAttributeIt);
std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(const FeaturePtr theStartCoin)
{
- std::shared_ptr<GeomAPI_Pnt2d> aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(),
- SketchPlugin_Constraint::ENTITY_A());
+ std::shared_ptr<GeomAPI_Pnt2d> aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(),
+ SketchPlugin_Constraint::ENTITY_A());
if (aPnt.get() == NULL)
aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), SketchPlugin_Constraint::ENTITY_B());
return aPnt;
}
+std::set<FeaturePtr> findCoincidentConstraints(const FeaturePtr& theFeature)
+{
+ std::set<FeaturePtr> aCoincident;
+ const std::set<AttributePtr>& aRefsList = theFeature->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator aIt;
+ for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
+ FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*aIt)->owner());
+ if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID())
+ aCoincident.insert(aConstrFeature);
+ }
+ return aCoincident;
+}
+
void findCoincidences(const FeaturePtr theStartCoin,
const std::string& theAttr,
std::set<FeaturePtr>& theList)
return;
}
theList.insert(aObj);
- const std::set<AttributePtr>& aRefsList = aObj->data()->refsToMe();
- std::set<AttributePtr>::const_iterator aIt;
- for(aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
- std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
- FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
- if(aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
- std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincidencePoint(aConstrFeature);
- if(aPnt.get() && aOrig->isEqual(aPnt)) {
- findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(), theList);
- findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(), theList);
- }
+ std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(aObj);
+ std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
+ for (; aCIt != aCoincidences.end(); ++aCIt) {
+ FeaturePtr aConstrFeature = *aCIt;
+ std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincidencePoint(aConstrFeature);
+ if(aPnt.get() && aOrig->isEqual(aPnt)) {
+ findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(), theList);
+ findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(), theList);
}
}
}
}
-void updateMultiAttribute(const AttributePtr& theFirstAngleAttribute,
- const AttributePtr& theSecondAngleAttribute,
- const int& theValue,
- const bool toMultiply)
+std::set<FeaturePtr> findFeaturesCoincidentToPoint(const AttributePoint2DPtr& thePoint)
{
- if (theValue == 0 || !theFirstAngleAttribute->isInitialized())
- return;
+ std::set<FeaturePtr> aCoincidentFeatures;
+
+ FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
+ aCoincidentFeatures.insert(anOwner);
- AttributeDoublePtr aDoubleFirstAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
- theFirstAngleAttribute);
- double aValue = aDoubleFirstAttr->value();
+ std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(anOwner);
+ std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
+ for (; aCIt != aCoincidences.end(); ++aCIt) {
+ bool isPointUsedInCoincidence = false;
+ AttributeRefAttrPtr anOtherCoincidentAttr;
+ for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
+ AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
+ if (!aRefAttr)
+ continue;
+ if (!aRefAttr->isObject() && aRefAttr->attr() == thePoint)
+ isPointUsedInCoincidence = true;
+ else
+ anOtherCoincidentAttr = aRefAttr;
+ }
+
+ if (isPointUsedInCoincidence) {
+ ObjectPtr anObj;
+ if (anOtherCoincidentAttr->isObject())
+ anObj = anOtherCoincidentAttr->object();
+ else
+ anObj = anOtherCoincidentAttr->attr()->owner();
+ aCoincidentFeatures.insert(ModelAPI_Feature::feature(anObj));
+ }
+ }
- AttributeDoublePtr aDoubleSecondAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
- theSecondAngleAttribute);
- if (toMultiply)
- aDoubleSecondAttr->setValue(aValue*theValue);
- else
- aDoubleSecondAttr->setValue(aValue/theValue);
+ return aCoincidentFeatures;
}
-void updateMultiAttribute(const AttributePtr& theFirstAttribute,
- const AttributePtr& theSecondAttribute,
- const AttributePtr& theModifiedAttribute,
- const int& theValue,
- const bool toMultiply)
+// Container for point-point coincidences.
+// Useful to find points coincident to a given point.
+class CoincidentPoints
{
- if (theValue == 0 || !theFirstAttribute->isInitialized()
- || !theSecondAttribute->isInitialized())
- return;
+public:
+ void addCoincidence(const AttributePoint2DPtr& thePoint1,
+ const AttributePoint2DPtr& thePoint2 = AttributePoint2DPtr())
+ {
+ std::list< std::set<AttributePoint2DPtr> >::iterator aFound1 = find(thePoint1);
+ std::list< std::set<AttributePoint2DPtr> >::iterator aFound2 = find(thePoint2);
+ if (aFound1 == myCoincidentPoints.end()) {
+ std::set<AttributePoint2DPtr> aNewSet;
+ aNewSet.insert(thePoint1);
+ if (thePoint2)
+ aNewSet.insert(thePoint2);
+ myCoincidentPoints.push_back(aNewSet);
+ } else if (aFound2 == myCoincidentPoints.end()) {
+ if (thePoint2)
+ aFound1->insert(thePoint2);
+ } else {
+ aFound1->insert(aFound2->begin(), aFound2->end());
+ myCoincidentPoints.erase(aFound2);
+ }
+ }
- std::shared_ptr<GeomDataAPI_Point2D> aFirstPoint =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theFirstAttribute);
- std::shared_ptr<GeomDataAPI_Point2D> aSecondPoint =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theSecondAttribute);
- std::shared_ptr<GeomDataAPI_Point2D> aModifiedPoint =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theModifiedAttribute);
+ std::set<AttributePoint2DPtr> coincidentPoints(const AttributePoint2DPtr& thePoint)
+ {
+ std::list< std::set<AttributePoint2DPtr> >::iterator aFound = find(thePoint);
+ if (aFound == myCoincidentPoints.end())
+ return std::set<AttributePoint2DPtr>();
+ return *aFound;
+ }
- if (!aFirstPoint.get() || !aSecondPoint.get() || !aModifiedPoint.get())
- return;
+private:
+ std::list< std::set<AttributePoint2DPtr> >::iterator find(const AttributePoint2DPtr& thePoint)
+ {
+ std::list< std::set<AttributePoint2DPtr> >::iterator aSeek = myCoincidentPoints.begin();
+ for (; aSeek != myCoincidentPoints.end(); ++aSeek)
+ if (aSeek->find(thePoint) != aSeek->end())
+ return aSeek;
+ return myCoincidentPoints.end();
+ }
+
+private:
+ std::list< std::set<AttributePoint2DPtr> > myCoincidentPoints;
+};
+
+std::set<AttributePoint2DPtr> findPointsCoincidentToPoint(const AttributePoint2DPtr& thePoint)
+{
+ CoincidentPoints aCoincidentPoints;
+ AttributePoint2DPtr aPoints[2];
+
+ FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
+ std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(anOwner);
+ std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
+ for (; aCIt != aCoincidences.end(); ++aCIt) {
+ aPoints[0] = AttributePoint2DPtr();
+ aPoints[1] = AttributePoint2DPtr();
+ for (int i = 0, aPtInd = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
+ AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
+ if (!aRefAttr)
+ continue;
+ if (!aRefAttr->isObject())
+ aPoints[aPtInd++] = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
+ }
- if (aFirstPoint->pnt()->isEqual(aSecondPoint->pnt()))
- aModifiedPoint->setValue(aFirstPoint->pnt());
- else {
- double aDx = aSecondPoint->x() - aFirstPoint->x();
- double aDy = aSecondPoint->y() - aFirstPoint->y();
+ if (aPoints[0])
+ aCoincidentPoints.addCoincidence(aPoints[0], aPoints[1]);
+ }
- double aX = toMultiply ? aDx * theValue : aDx / theValue;
- double anY = toMultiply ? aDy * theValue : aDy / theValue;
+ return aCoincidentPoints.coincidentPoints(thePoint);
+}
- aModifiedPoint->setValue(aFirstPoint->x() + aX, aFirstPoint->y() + anY);
+void resetAttribute(SketchPlugin_Feature* theFeature,
+ const std::string& theId)
+{
+ AttributePtr anAttr = theFeature->attribute(theId);
+ if(anAttr.get()) {
+ anAttr->reset();
}
}
+void createConstraint(SketchPlugin_Feature* theFeature,
+ const std::string& theId,
+ const AttributePtr theAttr,
+ const ObjectPtr theObject,
+ const bool theIsCanBeTangent)
+{
+ AttributeRefAttrPtr aRefAttr = theFeature->refattr(theId);
+ if(aRefAttr.get() && aRefAttr->isInitialized()) {
+ FeaturePtr aConstraint;
+ if(!theIsCanBeTangent) {
+ aConstraint = theFeature->sketch()
+ ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
+ } else {
+ if(aRefAttr->isObject()) {
+ ObjectPtr anObject = aRefAttr->object();
+ FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+ if(aFeature->getKind() == SketchPlugin_Point::ID()) {
+ aConstraint = theFeature->sketch()
+ ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
+ } else {
+ aConstraint = theFeature->sketch()
+ ->addFeature(SketchPlugin_ConstraintTangent::ID());
+ }
+ } else {
+ aConstraint = theFeature->sketch()
+ ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
+ }
+ }
+ AttributeRefAttrPtr aRefAttrA = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
+ aRefAttr->isObject() ? aRefAttrA->setObject(aRefAttr->object())
+ : aRefAttrA->setAttr(aRefAttr->attr());
+ AttributeRefAttrPtr aRefAttrB = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_B());
+ if(theObject.get()) {
+ aRefAttrB->setObject(theObject);
+ } else if(theAttr.get()) {
+ aRefAttrB->setAttr(theAttr);
+ }
+ }
+}
+
+void convertRefAttrToPointOrTangentCurve(const AttributeRefAttrPtr& theRefAttr,
+ const AttributePtr& theDefaultAttr,
+ std::shared_ptr<GeomAPI_Shape>& theTangentCurve,
+ std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint)
+{
+ AttributePtr anAttr = theDefaultAttr;
+ if (theRefAttr->isObject()) {
+ FeaturePtr aTgFeature = ModelAPI_Feature::feature(theRefAttr->object());
+ if (aTgFeature) {
+ if (aTgFeature->getKind() != SketchPlugin_Point::ID()) {
+ theTangentCurve = aTgFeature->lastResult()->shape();
+ return;
+ }
+ anAttr = aTgFeature->attribute(SketchPlugin_Point::COORD_ID());
+ }
+ } else
+ anAttr = theRefAttr->attr();
+
+ thePassingPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr)->pnt();
+}
+
} // namespace SketchPlugin_Tools