#include <SketcherPrs_Tools.h>
#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
#include <ModelGeomAlgo_Point2D.h>
#include <ModelGeomAlgo_Shape.h>
return aPnt;
}
-std::set<FeaturePtr> findCoincidentConstraints(const FeaturePtr& theFeature)
+std::set<FeaturePtr> findCoincidentConstraints(const ObjectPtr& theObject)
{
std::set<FeaturePtr> aCoincident;
- const std::set<AttributePtr>& aRefsList = theFeature->data()->refsToMe();
+ const std::set<AttributePtr>& aRefsList = theObject->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());
// Useful to find points coincident to a given point.
class CoincidentPoints
{
+ static const int THE_DEFAULT_INDEX = -1;
+
public:
- void addCoincidence(const AttributePoint2DPtr& thePoint1,
- const AttributePoint2DPtr& thePoint2 = AttributePoint2DPtr())
+ void addCoincidence(const AttributePtr& thePoint1, const int theIndex1,
+ const AttributePtr& thePoint2, const int theIndex2)
{
- std::list< std::set<AttributePoint2DPtr> >::iterator aFound1 = find(thePoint1);
- std::list< std::set<AttributePoint2DPtr> >::iterator aFound2 = find(thePoint2);
+ auto aFound1 = find(thePoint1, theIndex1);
+ auto aFound2 = find(thePoint2, theIndex2);
if (aFound1 == myCoincidentPoints.end()) {
if (aFound2 == myCoincidentPoints.end()) {
- std::set<AttributePoint2DPtr> aNewSet;
- aNewSet.insert(thePoint1);
+ std::map<AttributePtr, std::set<int> > aNewSet;
+ aNewSet[thePoint1].insert(theIndex1);
if (thePoint2)
- aNewSet.insert(thePoint2);
+ aNewSet[thePoint2].insert(theIndex2);
myCoincidentPoints.push_back(aNewSet);
} else
- aFound2->insert(thePoint1);
+ (*aFound2)[thePoint1].insert(theIndex1);
} else if (aFound2 == myCoincidentPoints.end()) {
if (thePoint2)
- aFound1->insert(thePoint2);
+ (*aFound1)[thePoint2].insert(theIndex2);
} else {
- aFound1->insert(aFound2->begin(), aFound2->end());
+ for (auto it = aFound2->begin(); it != aFound2->end(); ++it)
+ (*aFound1)[it->first].insert(it->second.begin(), it->second.end());
myCoincidentPoints.erase(aFound2);
}
}
- std::set<AttributePoint2DPtr> coincidentPoints(const AttributePoint2DPtr& thePoint)
+ void coincidentPoints(const AttributePoint2DPtr& thePoint,
+ std::set<AttributePoint2DPtr>& thePoints,
+ std::map<AttributePoint2DArrayPtr, int>& thePointsInArray)
{
collectCoincidentPoints(thePoint);
- std::list< std::set<AttributePoint2DPtr> >::iterator aFound = find(thePoint);
- if (aFound == myCoincidentPoints.end())
- return std::set<AttributePoint2DPtr>();
- return *aFound;
+ auto aFound = find(thePoint, THE_DEFAULT_INDEX);
+ if (aFound != myCoincidentPoints.end()) {
+ for (auto it = aFound->begin(); it != aFound->end(); ++it) {
+ AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(it->first);
+ if (aPoint)
+ thePoints.insert(aPoint);
+ else {
+ AttributePoint2DArrayPtr aPointArray =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(it->first);
+ if (aPointArray)
+ thePointsInArray[aPointArray] = *it->second.begin();
+ }
+ }
+ }
}
private:
{
// iterate through coincideces for the given feature
std::set<FeaturePtr> aCoincidences = SketchPlugin_Tools::findCoincidentConstraints(theFeature);
- std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
+ if (theFeature->getKind() == SketchPlugin_Point::ID()) {
+ std::set<FeaturePtr> aCoincToRes =
+ SketchPlugin_Tools::findCoincidentConstraints(theFeature->lastResult());
+ aCoincidences.insert(aCoincToRes.begin(), aCoincToRes.end());
+ }\r std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
for (; aCIt != aCoincidences.end(); ++aCIt)
{
if (theCoincidences.find(*aCIt) != theCoincidences.end())
// iterate on coincident attributes
for (int i = 0, aPtInd = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
- if (aRefAttr && !aRefAttr->isObject())
- {
- FeaturePtr anOwner = ModelAPI_Feature::feature(aRefAttr->attr()->owner());
- if (anOwner != theFeature)
- coincidences(anOwner, theCoincidences);
+ if (!aRefAttr)
+ continue;
+ FeaturePtr anOwner;
+ if (aRefAttr->isObject()) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
+ if (aFeature->getKind() == SketchPlugin_Point::ID())
+ anOwner = aFeature;
}
+ else
+ anOwner = ModelAPI_Feature::feature(aRefAttr->attr()->owner());
+ if (anOwner && anOwner != theFeature)
+ coincidences(anOwner, theCoincidences);
}
}
}
// (two points may be coincident through the third point)
void collectCoincidentPoints(const AttributePoint2DPtr& thePoint)
{
- AttributePoint2DPtr aPoints[2];
+ AttributePtr aPoints[2];
+ int anIndicesInArray[2];
FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
std::set<FeaturePtr> aCoincidences;
std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
for (; aCIt != aCoincidences.end(); ++aCIt) {
- aPoints[0] = AttributePoint2DPtr();
- aPoints[1] = AttributePoint2DPtr();
+ aPoints[0] = aPoints[1] = AttributePtr();
+ anIndicesInArray[0] = anIndicesInArray[1] = THE_DEFAULT_INDEX;
for (int i = 0, aPtInd = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
- if (aRefAttr && !aRefAttr->isObject())
- aPoints[aPtInd++] = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
+ if (!aRefAttr)
+ continue;
+ if (aRefAttr->isObject()) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
+ if (aFeature && aFeature->getKind() == SketchPlugin_Point::ID())
+ aPoints[aPtInd++] = aFeature->attribute(SketchPlugin_Point::COORD_ID());
+ }
+ else {
+ AttributePoint2DPtr aPointAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
+ AttributePoint2DArrayPtr aPointArray =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(aRefAttr->attr());
+ if (aPointAttr)
+ aPoints[aPtInd++] = aPointAttr;
+ else if (aPointArray) {
+ AttributeIntegerPtr anIndexAttr = (*aCIt)->integer(i == 0 ?
+ SketchPlugin_ConstraintCoincidenceInternal::INDEX_ENTITY_A() :
+ SketchPlugin_ConstraintCoincidenceInternal::INDEX_ENTITY_B());
+ aPoints[aPtInd] = aPointArray;
+ anIndicesInArray[aPtInd++] = anIndexAttr->value();
+ }
+ }
}
if (aPoints[0] && aPoints[1])
- addCoincidence(aPoints[0], aPoints[1]);
+ addCoincidence(aPoints[0], anIndicesInArray[0], aPoints[1], anIndicesInArray[1]);
}
}
- std::list< std::set<AttributePoint2DPtr> >::iterator find(const AttributePoint2DPtr& thePoint)
+ std::list< std::map<AttributePtr, std::set<int> > >::iterator find(const AttributePtr& thePoint,
+ const int theIndex)
{
- std::list< std::set<AttributePoint2DPtr> >::iterator aSeek = myCoincidentPoints.begin();
- for (; aSeek != myCoincidentPoints.end(); ++aSeek)
- if (aSeek->find(thePoint) != aSeek->end())
+ auto aSeek = myCoincidentPoints.begin();
+ for (; aSeek != myCoincidentPoints.end(); ++aSeek) {
+ auto aFound = aSeek->find(thePoint);
+ if (aFound != aSeek->end() && aFound->second.find(theIndex) != aFound->second.end())
return aSeek;
+ }
return myCoincidentPoints.end();
}
private:
- std::list< std::set<AttributePoint2DPtr> > myCoincidentPoints;
+ std::list< std::map<AttributePtr, std::set<int> > > myCoincidentPoints;
};
std::set<AttributePoint2DPtr> findPointsCoincidentToPoint(const AttributePoint2DPtr& thePoint)
+{
+ std::set<AttributePoint2DPtr> aPoints;
+ std::map<AttributePoint2DArrayPtr, int> aPointsInArray;
+ findPointsCoincidentToPoint(thePoint, aPoints, aPointsInArray);
+ return aPoints;
+}
+
+void findPointsCoincidentToPoint(const AttributePoint2DPtr& thePoint,
+ std::set<AttributePoint2DPtr>& thePoints,
+ std::map<AttributePoint2DArrayPtr, int>& thePointsInArray)
{
CoincidentPoints aCoincidentPoints;
- return aCoincidentPoints.coincidentPoints(thePoint);
+ aCoincidentPoints.coincidentPoints(thePoint, thePoints, thePointsInArray);
}
+
void resetAttribute(SketchPlugin_Feature* theFeature,
const std::string& theId)
{