X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_Tools.cpp;h=710c6fd18d3a6ceedf4b9a5153fabec1b1f9fc5f;hb=06e7f5859095193fc7f498bd89a7d28009794f53;hp=68765a14e9620b12df1d15b5c1c00f9648d186a1;hpb=042b38afc4aec55ce1868c3025d8a4ca514587e1;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Tools.cpp b/src/SketchPlugin/SketchPlugin_Tools.cpp index 68765a14e..710c6fd18 100644 --- a/src/SketchPlugin/SketchPlugin_Tools.cpp +++ b/src/SketchPlugin/SketchPlugin_Tools.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2019 CEA/DEN, EDF R&D +// Copyright (C) 2014-2023 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -20,6 +20,7 @@ #include "SketchPlugin_Tools.h" #include "SketchPlugin_Arc.h" +#include "SketchPlugin_BSpline.h" #include "SketchPlugin_Circle.h" #include "SketchPlugin_ConstraintCoincidence.h" #include "SketchPlugin_ConstraintCoincidenceInternal.h" @@ -36,7 +37,11 @@ #include +#include + #include +#include +#include #include #include @@ -60,17 +65,17 @@ namespace SketchPlugin_Tools { void clearExpressions(AttributeDoublePtr theAttribute) { - theAttribute->setText(std::string()); + theAttribute->setText(std::wstring()); } void clearExpressions(AttributePointPtr theAttribute) { - theAttribute->setText(std::string(), std::string(), std::string()); + theAttribute->setText(std::wstring(), std::wstring(), std::wstring()); } void clearExpressions(AttributePoint2DPtr theAttribute) { - theAttribute->setText(std::string(), std::string()); + theAttribute->setText(std::wstring(), std::wstring()); } void clearExpressions(AttributePtr theAttribute) @@ -113,10 +118,10 @@ std::shared_ptr getCoincidencePoint(const FeaturePtr theStartCoin return aPnt; } -std::set findCoincidentConstraints(const FeaturePtr& theFeature) +std::set findCoincidentConstraints(const ObjectPtr& theObject) { std::set aCoincident; - const std::set& aRefsList = theFeature->data()->refsToMe(); + const std::set& aRefsList = theObject->data()->refsToMe(); std::set::const_iterator aIt; for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { FeaturePtr aConstrFeature = std::dynamic_pointer_cast((*aIt)->owner()); @@ -149,8 +154,8 @@ void findCoincidences(const FeaturePtr theStartCoin, std::set::const_iterator aCIt = aCoincidences.begin(); for (; aCIt != aCoincidences.end(); ++aCIt) { FeaturePtr aConstrFeature = *aCIt; - std::shared_ptr aPnt = getCoincidencePoint(aConstrFeature); - if(aPnt.get() && aOrig->isEqual(aPnt)) { + std::shared_ptr aPnt2d = getCoincidencePoint(aConstrFeature); + if(aPnt2d.get() && aOrig->isEqual(aPnt2d)) { findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(), theList, theIsAttrOnly); findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(), @@ -199,26 +204,29 @@ std::set findFeaturesCoincidentToPoint(const AttributePoint2DPtr& th // 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 >::iterator aFound1 = find(thePoint1); - std::list< std::set >::iterator aFound2 = find(thePoint2); + auto aFound1 = find(thePoint1, theIndex1); + auto aFound2 = find(thePoint2, theIndex2); if (aFound1 == myCoincidentPoints.end()) { if (aFound2 == myCoincidentPoints.end()) { - std::set aNewSet; - aNewSet.insert(thePoint1); + std::map > 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); } } @@ -227,10 +235,35 @@ public: { collectCoincidentPoints(thePoint); - std::list< std::set >::iterator aFound = find(thePoint); - if (aFound == myCoincidentPoints.end()) - return std::set(); - return *aFound; + std::set aCoincPoints; + 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(it->first); + if (aPoint) + aCoincPoints.insert(aPoint); + else { + AttributePoint2DArrayPtr aPointArray = + std::dynamic_pointer_cast(it->first); + if (aPointArray) { + // this is a B-spline feature, the connection is possible + // to the first or the last point + FeaturePtr anOwner = ModelAPI_Feature::feature(aPointArray->owner()); + if (it->second.find(0) != it->second.end()) { + AttributePoint2DPtr aFirstPoint = std::dynamic_pointer_cast( + anOwner->attribute(SketchPlugin_BSpline::START_ID())); + aCoincPoints.insert(aFirstPoint); + } + if (it->second.find(aPointArray->size() - 1) != it->second.end()) { + AttributePoint2DPtr aFirstPoint = std::dynamic_pointer_cast( + anOwner->attribute(SketchPlugin_BSpline::END_ID())); + aCoincPoints.insert(aFirstPoint); + } + } + } + } + } + return aCoincPoints; } private: @@ -239,6 +272,11 @@ private: { // iterate through coincideces for the given feature std::set aCoincidences = SketchPlugin_Tools::findCoincidentConstraints(theFeature); + if (theFeature->getKind() == SketchPlugin_Point::ID()) { + std::set aCoincToRes = + SketchPlugin_Tools::findCoincidentConstraints(theFeature->lastResult()); + aCoincidences.insert(aCoincToRes.begin(), aCoincToRes.end()); + } std::set::const_iterator aCIt = aCoincidences.begin(); for (; aCIt != aCoincidences.end(); ++aCIt) { @@ -246,14 +284,20 @@ private: continue; // already processed theCoincidences.insert(*aCIt); // iterate on coincident attributes - for (int i = 0, aPtInd = 0; i < CONSTRAINT_ATTR_SIZE; ++i) { + for (int i = 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); } } } @@ -262,7 +306,8 @@ private: // (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 aCoincidences; @@ -270,30 +315,69 @@ private: std::set::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(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(aRefAttr->attr()); + AttributePoint2DArrayPtr aPointArray = + std::dynamic_pointer_cast(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 >::iterator find(const AttributePoint2DPtr& thePoint) + std::list< std::map > >::iterator find(const AttributePtr& thePoint, + const int theIndex) { - std::list< std::set >::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; + } + // nothing is found, but if the point is a B-spline boundary point, lets check it as poles array + FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner()); + if (anOwner->getKind() == SketchPlugin_BSpline::ID()) { + AttributePtr aPointsArray; + int anIndex = -1; + if (thePoint->id() == SketchPlugin_BSpline::START_ID()) { + aPointsArray = anOwner->attribute(SketchPlugin_BSpline::POLES_ID()); + anIndex = 0; + } + else if (thePoint->id() == SketchPlugin_BSpline::END_ID()) { + aPointsArray = anOwner->attribute(SketchPlugin_BSpline::POLES_ID()); + anIndex = std::dynamic_pointer_cast(aPointsArray)->size() - 1; + } + if (aPointsArray) + return find(aPointsArray, anIndex); + } return myCoincidentPoints.end(); } private: - std::list< std::set > myCoincidentPoints; + std::list< std::map > > myCoincidentPoints; }; std::set findPointsCoincidentToPoint(const AttributePoint2DPtr& thePoint) @@ -302,6 +386,7 @@ std::set findPointsCoincidentToPoint(const AttributePoint2D return aCoincidentPoints.coincidentPoints(thePoint); } + void resetAttribute(SketchPlugin_Feature* theFeature, const std::string& theId) { @@ -463,7 +548,8 @@ void createAuxiliaryPointOnEllipse(const FeaturePtr& theEllipseFeature, aCoord->setValue(anElPoint->x(), anElPoint->y()); aPointFeature->execute(); - std::string aName = theEllipseFeature->name() + "_" + theEllipsePoint; + std::wstring aName = theEllipseFeature->name() + L"_" + + Locale::Convert::toWString(theEllipsePoint); aPointFeature->data()->setName(aName); aPointFeature->lastResult()->data()->setName(aName); @@ -496,8 +582,8 @@ void createAuxiliaryAxisOfEllipse(const FeaturePtr& theEllipseFeature, aLineEnd->setValue(aEndPoint->x(), aEndPoint->y()); aLineFeature->execute(); - std::string aName = theEllipseFeature->name() + "_" + - (theStartPoint == SketchPlugin_Ellipse::MAJOR_AXIS_START_ID() ? "major_axis" : "minor_axis"); + std::wstring aName = theEllipseFeature->name() + L"_" + + (theStartPoint == SketchPlugin_Ellipse::MAJOR_AXIS_START_ID() ? L"major_axis" : L"minor_axis"); aLineFeature->data()->setName(aName); aLineFeature->lastResult()->data()->setName(aName); @@ -564,13 +650,13 @@ void setDimensionColor(const AISObjectPtr& theDimPrs) theDimPrs->setColor(aColor[0], aColor[1], aColor[2]); } -void replaceInName(ObjectPtr theObject, const std::string& theSource, const std::string& theDest) +void replaceInName(ObjectPtr theObject, const std::wstring& theSource, const std::wstring& theDest) { - std::string aName = theObject->data()->name(); + std::wstring aName = theObject->data()->name(); size_t aPos = aName.find(theSource); - if (aPos != std::string::npos) { - std::string aNewName = aName.substr(0, aPos) + theDest - + aName.substr(aPos + theSource.size()); + if (aPos != std::wstring::npos) { + std::wstring aNewName = aName.substr(0, aPos) + theDest + + aName.substr(aPos + theSource.size()); theObject->data()->setName(aNewName); } } @@ -600,6 +686,10 @@ void SketchPlugin_SegmentationTools::getFeaturePoints(const FeaturePtr& theFeatu aStartAttributeName = SketchPlugin_EllipticArc::START_POINT_ID(); anEndAttributeName = SketchPlugin_EllipticArc::END_POINT_ID(); } + else if (aFeatureKind == SketchPlugin_BSpline::ID()) { + aStartAttributeName = SketchPlugin_BSpline::START_ID(); + anEndAttributeName = SketchPlugin_BSpline::END_ID(); + } if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) { theStartPointAttr = std::dynamic_pointer_cast( theFeature->attribute(aStartAttributeName)); @@ -761,9 +851,9 @@ void SketchPlugin_SegmentationTools::fillObjectShapes( // collect all intersection points with other edges for Trim operation only std::list aFeatures; for (int i = 0; i < aSketch->numberOfSubs(); i++) { - FeaturePtr aFeature = aSketch->subFeature(i); - if (aFeature.get() && aFeature->getKind() != SketchPlugin_Projection::ID()) - aFeatures.push_back(aFeature); + FeaturePtr aSubFeature = aSketch->subFeature(i); + if (aSubFeature.get() && aSubFeature->getKind() != SketchPlugin_Projection::ID()) + aFeatures.push_back(aSubFeature); } ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPoints); }