From f67ce3bc59a476ac462b865a8f08d92cd93497cb Mon Sep 17 00:00:00 2001 From: nds Date: Wed, 24 Aug 2016 16:39:06 +0300 Subject: [PATCH] Issue #1664 In the Sketcher, add the function Split a segment --- src/Model/Model_AttributeReference.cpp | 18 +- src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp | 48 ++ src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h | 15 + src/ModuleBase/CMakeLists.txt | 2 + src/ModuleBase/ModuleBase_Tools.cpp | 27 +- .../SketchPlugin_ConstraintSplit.cpp | 639 ++++++++++++++---- .../SketchPlugin_ConstraintSplit.h | 73 +- 7 files changed, 640 insertions(+), 182 deletions(-) diff --git a/src/Model/Model_AttributeReference.cpp b/src/Model/Model_AttributeReference.cpp index dc1a3994d..b4d5acbee 100644 --- a/src/Model/Model_AttributeReference.cpp +++ b/src/Model/Model_AttributeReference.cpp @@ -79,12 +79,14 @@ ObjectPtr Model_AttributeReference::value() } } } else { // internal ref - std::shared_ptr aDoc = std::dynamic_pointer_cast( - owner()->document()); - if (aDoc) { - TDF_Label aRefLab = myRef->Get(); - if (!aRefLab.IsNull()) { // it may happen with old document, issue #285 - return aDoc->objects()->object(aRefLab); + if (owner().get()) { + std::shared_ptr aDoc = std::dynamic_pointer_cast( + owner()->document()); + if (aDoc) { + TDF_Label aRefLab = myRef->Get(); + if (!aRefLab.IsNull()) { // it may happen with old document, issue #285 + return aDoc->objects()->object(aRefLab); + } } } } @@ -117,8 +119,8 @@ void Model_AttributeReference::setObject(const std::shared_ptr& { if (owner() != theObject) { ModelAPI_AttributeReference::setObject(theObject); - std::shared_ptr aDoc = - std::dynamic_pointer_cast(owner()->document()); + //std::shared_ptr aDoc = + // std::dynamic_pointer_cast(owner()->document()); } } diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp index f27954b10..2e81b4f34 100755 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp @@ -162,4 +162,52 @@ namespace ModelGeomAlgo_Point2D { return isInside; } + std::string doubleToString(double theValue) + { + std::string aValueStr; + char aBuf[50]; + int n = sprintf(aBuf, "%g", theValue); + aValueStr = std::string(aBuf); + return aValueStr; + } + + std::string getPontAttributesInfo(const std::shared_ptr& theFeature, + const std::set >& theAttributesOnly) + { + std::string anInfo; + + std::list anAttrs = theFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); + std::list::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end(); + + for(; anIt != aLast; anIt++) { + AttributePtr anAttribute = *anIt; + if (anAttribute.get() && (theAttributesOnly.empty() || + theAttributesOnly.find(anAttribute) != theAttributesOnly.end())) { + if (!anInfo.empty()) { + anInfo.append(", "); + anInfo.append("\n"); + } + anInfo.append(" " + getPointAttributeInfo(anAttribute)); + } + } + return anInfo; + } + + std::string getPointAttributeInfo(const std::shared_ptr& theAttribute) + { + std::string anInfo; + std::string aValue = "not defined"; + std::string aType = theAttribute->attributeType(); + if (aType == GeomDataAPI_Point2D::typeId()) { + std::shared_ptr aPoint = std::dynamic_pointer_cast( + theAttribute); + if (aPoint.get() && aPoint->isInitialized()) { + aValue = std::string("(" + doubleToString(aPoint->x()) + ", "+ doubleToString(aPoint->y()) + ")"); + } + } + anInfo.append(theAttribute->id() + ": " + aValue); + + return anInfo; + } + } // namespace ModelGeomAlgo_Point2D diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h index 826dde4a6..940a869c8 100755 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h @@ -80,6 +80,21 @@ namespace ModelGeomAlgo_Point2D { MODELGEOMALGO_EXPORT bool isPointOnEdge(const std::shared_ptr theBaseShape, const std::shared_ptr& thePoint, std::shared_ptr& theProjectedPoint); + + /// Return feature name, kind and point values united in a string info + /// \param theFeature an investigated feature + /// \param theAttributesOnly a container of necessary attributes, if empty, all + /// \return string value + MODELGEOMALGO_EXPORT std::string getPontAttributesInfo( + const std::shared_ptr& theFeature, + const std::set >& theAttributesOnly); + + /// Return point attribute string info + /// \param theAttribute an investigated attribute + /// \return string value + MODELGEOMALGO_EXPORT std::string getPointAttributeInfo( + const std::shared_ptr& theAttribute); + } #endif diff --git a/src/ModuleBase/CMakeLists.txt b/src/ModuleBase/CMakeLists.txt index 74a793206..4e444009e 100644 --- a/src/ModuleBase/CMakeLists.txt +++ b/src/ModuleBase/CMakeLists.txt @@ -131,6 +131,7 @@ SET(PROJECT_LIBRARIES Config Events ModelAPI + ModelGeomAlgo GeomAPI GeomDataAPI GeomAlgoAPI @@ -158,6 +159,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/Config ${PROJECT_SOURCE_DIR}/src/Events ${PROJECT_SOURCE_DIR}/src/ModelAPI + ${PROJECT_SOURCE_DIR}/src/ModelGeomAlgo ${PROJECT_SOURCE_DIR}/src/GeomDataAPI ${PROJECT_SOURCE_DIR}/src/GeomAPI ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI diff --git a/src/ModuleBase/ModuleBase_Tools.cpp b/src/ModuleBase/ModuleBase_Tools.cpp index 6ca02d6ac..1a436ee44 100755 --- a/src/ModuleBase/ModuleBase_Tools.cpp +++ b/src/ModuleBase/ModuleBase_Tools.cpp @@ -33,6 +33,8 @@ #include #include +#include + #include #include @@ -313,26 +315,11 @@ QString objectInfo(const ObjectPtr& theObj, const bool isUseAttributesInfo) .c_str()); } if (isUseAttributesInfo) { - std::list anAttrs = aFeature->data()->attributes(""); - std::list::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end(); - QStringList aValues; - for(; anIt != aLast; anIt++) { - AttributePtr anAttr = *anIt; - QString aValue = "not defined"; - std::string aType = anAttr->attributeType(); - if (aType == GeomDataAPI_Point2D::typeId()) { - std::shared_ptr aPoint = std::dynamic_pointer_cast( - anAttr); - if (aPoint.get()) - aValue = QString("(%1, %2)").arg(aPoint->x()).arg(aPoint->y()); - } - else if (aType == ModelAPI_AttributeRefAttr::typeId()) { - } - - aValues.push_back(QString("%1: %2").arg(anAttr->id().c_str()).arg(aValue).toStdString().c_str()); - } - if (!aValues.empty()) - aFeatureStr.append(QString(", attributes: %1").arg(aValues.join(", ").toStdString().c_str())); + std::set > anAttributes; + std::string aPointsInfo = ModelGeomAlgo_Point2D::getPontAttributesInfo(aFeature, + anAttributes).c_str(); + if (!aPointsInfo.empty()) + aFeatureStr.append(QString(", attributes: %1").arg(aPointsInfo.c_str()).toStdString().c_str()); } } diff --git a/src/SketchPlugin/SketchPlugin_ConstraintSplit.cpp b/src/SketchPlugin/SketchPlugin_ConstraintSplit.cpp index e53185f41..fccbf1df4 100755 --- a/src/SketchPlugin/SketchPlugin_ConstraintSplit.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintSplit.cpp @@ -27,55 +27,20 @@ #include #include -//#include #include -//#include -//#include -// #include #include #include -//#include -//#include -//#include -// #include #include -// -//#include -// -//const double tolerance = 1.e-7; -//const double paramTolerance = 1.e-4; - -///// \brief Attract specified point on theNewArc to the attribute of theFeature -//static void recalculateAttributes(FeaturePtr theNewArc, const std::string& theNewArcAttribute, -// FeaturePtr theFeature, const std::string& theFeatureAttribute); -// -///// \brief Calculates center of fillet arc and coordinates of tangency points -//static void calculateFilletCenter(FeaturePtr theFeatureA, FeaturePtr theFeatureB, -// double theRadius, bool theNotInversed[2], -// std::shared_ptr& theCenter, -// std::shared_ptr& theTangentA, -// std::shared_ptr& theTangentB); -// -///// Get point on 1/3 length of edge from fillet point -//static void getPointOnEdge(const FeaturePtr theFeature, -// const std::shared_ptr theFilletPoint, -// std::shared_ptr& thePoint); -// -///// Get distance from point to feature -//static double getProjectionDistance(const FeaturePtr theFeature, -// const std::shared_ptr thePoint); -// -///// Get coincide edges for fillet -//static std::set getCoincides(const FeaturePtr& theConstraintCoincidence); + +#define DEBUG_SPLIT +#ifdef DEBUG_SPLIT +#include +#endif SketchPlugin_ConstraintSplit::SketchPlugin_ConstraintSplit() -//: myListOfPointsChangedInCode(false), -// myRadiusChangedByUser(false), -// myRadiusChangedInCode(false), -// myRadiusInitialized(false) { } @@ -84,9 +49,6 @@ void SketchPlugin_ConstraintSplit::initAttributes() data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeReference::typeId()); data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId()); - - //data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId()); - //data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttrList::typeId()); } void SketchPlugin_ConstraintSplit::execute() @@ -125,76 +87,140 @@ void SketchPlugin_ConstraintSplit::execute() std::map aCoincidenceToPoint; getConstraints(aFeaturesToDelete, aTangentFeatures, aCoincidenceToFeature, aCoincidenceToPoint); +#ifdef DEBUG_SPLIT + std::cout << std::endl; + std::cout << "SketchPlugin_ConstraintSplit::execute()" << std::endl; + std::cout << std::endl; + + std::cout << "SKETCH FEATURES (before split):" << std::endl; + SketchPlugin_Sketch* aSketch = sketch(); + for (int i = 0, aNbSubs = aSketch->numberOfSubs(); i < aNbSubs; i++) { + std::cout << getFeatureInfo(aSketch->subFeature(i), false) << std::endl; + std::cout << std::endl; + } + + std::cout << std::endl; + std::cout << "IN PARAMETERS" << std::endl; + std::cout << "Base feature:" << getFeatureInfo(aBaseFeature) << std::endl; + std::cout << std::endl; + + if (!aCoincidenceToFeature.empty()) { + std::cout << "Coincidences to base feature[" << aCoincidenceToFeature.size() << "]: " << std::endl; + std::map::const_iterator anIt = aCoincidenceToFeature.begin(), + aLast = aCoincidenceToFeature.end(); + for (int i = 1; anIt != aLast; anIt++, i++) { + FeaturePtr aFeature = (*anIt).first; + std::string anAttributeId = (*anIt).second.first; + std::shared_ptr aPointAttr = (*anIt).second.second; + + std::cout << i << "-" << getFeatureInfo(aFeature) << std::endl; + std::cout << " -Attribute to correct:" << anAttributeId << std::endl; + std::cout << " -Point attribute:" << ModelGeomAlgo_Point2D::getPointAttributeInfo(aPointAttr) << std::endl; + } + } + + if (!aCoincidenceToPoint.empty()) { + std::cout << "Coincidences to points on base feature[" << aCoincidenceToPoint.size() << "]: " << std::endl; + std::map::const_iterator anIt = aCoincidenceToPoint.begin(), + aLast = aCoincidenceToPoint.end(); + for (int i = 1; anIt != aLast; anIt++, i++) { + FeaturePtr aFeature = (*anIt).first; + std::string anAttributeId = (*anIt).second.first; + std::shared_ptr aPointAttr = (*anIt).second.second; + + std::cout << i << "-" << getFeatureInfo(aFeature) << std::endl; + std::cout << " -Attribute to correct:" << anAttributeId << std::endl; + std::cout << " -Point attribute:" << ModelGeomAlgo_Point2D::getPointAttributeInfo(aPointAttr) << std::endl; + } + } +#endif + +#ifdef DEBUG_SPLIT + std::cout << std::endl; + std::cout << "---- SPLIT ----" << std::endl; + std::cout << std::endl; +#endif std::string aFeatureKind = aBaseFeature->getKind(); FeaturePtr aSplitFeature, anAfterFeature; std::set aFurtherCoincidences; - /*if (aFeatureKind == SketchPlugin_Line::ID()) - splitLine(aSplitFeature, anOtherFeatures); - else*/ if (aFeatureKind == SketchPlugin_Arc::ID()) - splitArc(aSplitFeature, aBaseFeature, anAfterFeature, aFurtherCoincidences); - /*if (aFeatureKind == SketchPlugin_Circle::ID()) - splitCircle(aSplitFeature, anOtherFeatures); - FeaturePtr aSplitFeature; - std::set anOtherFeatures;*/ - - //setConstraints(aSplitFeature, aBaseFeature, anAfterFeature, aFeaturesToDelete, aTangentFeatures, - // aCoincidenceToFeature, aCoincidenceToPoint); - if (true) { + std::set aCreatedFeatures; + if (aFeatureKind == SketchPlugin_Line::ID()) + splitLine(aSplitFeature, aBaseFeature, anAfterFeature, aFurtherCoincidences, aCreatedFeatures); + else if (aFeatureKind == SketchPlugin_Arc::ID()) + splitArc(aSplitFeature, aBaseFeature, anAfterFeature, aFurtherCoincidences, aCreatedFeatures); + if (aFeatureKind == SketchPlugin_Circle::ID()) { + FeaturePtr aCircleFeature = aBaseFeature; + splitCircle(aSplitFeature, aBaseFeature, anAfterFeature, aFurtherCoincidences, aCreatedFeatures); + aFeaturesToDelete.insert(aCircleFeature); + aBaseObjectAttr->setObject(ResultPtr()); // as circle is removed, temporary fill this attribute + } + +#ifdef DEBUG_SPLIT + std::cout << "OUT PARAMETERS" << std::endl; + std::cout << "Base modified feature:" << getFeatureInfo(aBaseFeature) << std::endl; + std::cout << "Split feature:" << getFeatureInfo(aSplitFeature) << std::endl; + std::cout << "After feature:" << getFeatureInfo(anAfterFeature) << std::endl; + std::cout << std::endl; + + std::cout << "Created features by split:[" << aCreatedFeatures.size() << "]" << std::endl; + std::set::const_iterator aFIt = aCreatedFeatures.begin(), + aFLast = aCreatedFeatures.end(); + for (; aFIt != aFLast; aFIt++) { + std::cout << getFeatureInfo(*aFIt) << std::endl; + } + std::cout << std::endl; + + std::cout << "Attributes for further Coincidences:" << std::endl; + std::set::const_iterator anIt = aFurtherCoincidences.begin(), + aLast = aFurtherCoincidences.end(); + for (; anIt != aLast; anIt++) { + AttributePtr anAttribute = *anIt; + FeaturePtr aFeature = ModelAPI_Feature::feature(anAttribute->owner()); + std::cout << ModelGeomAlgo_Point2D::getPointAttributeInfo(anAttribute) + << " [" << getFeatureInfo(aFeature, false) << "]" << std::endl; + } +#endif + std::set aFeatureResults; aFeatureResults.insert(getFeatureResult(aBaseFeature)); if (anAfterFeature.get() && anAfterFeature != aBaseFeature) aFeatureResults.insert(getFeatureResult(anAfterFeature)); // coincidence to feature - std::map::const_iterator aCIt = aCoincidenceToFeature.begin(), - aCLast = aCoincidenceToFeature.end(); - for (; aCIt != aCLast; aCIt++) { - FeaturePtr aCoincFeature = aCIt->first; - std::string anAttributeId = aCIt->second.first; - AttributePoint2DPtr aCoincPoint = aCIt->second.second; - std::set::const_iterator aFCIt = aFurtherCoincidences.begin(), - aFCLast = aFurtherCoincidences.end(); - std::shared_ptr aCoincPnt = aCoincPoint->pnt(); - AttributePoint2DPtr aFeaturePointAttribute; - for (; aFCIt != aFCLast && !aFeaturePointAttribute.get(); aFCIt++) { - AttributePoint2DPtr aFCAttribute = *aFCIt; - if (aCoincPnt->isEqual(aFCAttribute->pnt())) - aFeaturePointAttribute = aFCAttribute; - } - if (aFeaturePointAttribute.get()) { - aCoincFeature->refattr(anAttributeId)->setAttr(aFeaturePointAttribute); - } - else { - /// find feature by shape intersected the point - ResultPtr aResultForCoincidence = *(aFeatureResults.begin()); - - if (aFeatureResults.size() > 1) { // try to find point on additional feature - ResultPtr anAddtionalResult = *(aFeatureResults.begin()++); - GeomShapePtr aShape = anAddtionalResult->shape(); - - std::shared_ptr aPnt2d = aCoincPoint->pnt(); - std::shared_ptr aPoint = sketch()->to3D(aPnt2d->x(), aPnt2d->y()); - - std::shared_ptr aProjectedPoint; - if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, aPoint, aProjectedPoint)) - aResultForCoincidence = anAddtionalResult; - } - aCoincFeature->refattr(anAttributeId)->setObject(aResultForCoincidence); - } - } + updateCoincidenceConstraintsToFeature(aCoincidenceToFeature, aFurtherCoincidences, + aFeatureResults); // coincidence to points + updateCoincidenceConstraintsToFeature(aCoincidenceToPoint, aFurtherCoincidences, + std::set()); // TODO // tangency // TODO - } + // delete constraints +#ifdef DEBUG_SPLIT + std::cout << "remove features and references:" << std::endl; + std::set::const_iterator aDIt = aFeaturesToDelete.begin(), + aDLast = aFeaturesToDelete.end(); + for (; aDIt != aDLast; aDIt++) { + std::cout << getFeatureInfo(*aDIt, false) << std::endl; + std::cout << std::endl; + } +#endif ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete); // Send events to update the sub-features by the solver. if(isUpdateFlushed) { Events_Loop::loop()->setFlushed(anUpdateEvent, true); } + +#ifdef DEBUG_SPLIT + std::cout << "SKETCH FEATURES (after split):" << std::endl; + for (int i = 0, aNbSubs = aSketch->numberOfSubs(); i < aNbSubs; i++) { + std::cout << getFeatureInfo(aSketch->subFeature(i), false) << std::endl; + std::cout << std::endl; + } +#endif } bool SketchPlugin_ConstraintSplit::isMacro() const @@ -258,7 +284,10 @@ void SketchPlugin_ConstraintSplit::getConstraints(std::set& theFeatu FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature); - const std::set& aRefsList = aBaseFeatureResult->data()->refsToMe(); + std::set aRefsList = aBaseFeatureResult->data()->refsToMe(); + std::set aFRefsList = aBaseFeature->data()->refsToMe(); + aRefsList.insert(aFRefsList.begin(), aFRefsList.end()); + std::set::const_iterator aIt; for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { std::shared_ptr aAttr = (*aIt); @@ -302,25 +331,26 @@ void SketchPlugin_ConstraintSplit::getConstraints(std::set& theFeatu FeaturePtr aFeature = anAttrA->isObject() ? ModelAPI_Feature::feature(anAttrA->object()) : FeaturePtr(); isToFeature = aFeature.get() && aFeature == aBaseFeature; - anAttributeToBeModified = SketchPlugin_Constraint::ENTITY_B(); + anAttributeToBeModified = anAttrA->id(); if (!isToFeature) { aFeature = anAttrB->isObject() ? ModelAPI_Feature::feature(anAttrB->object()) : FeaturePtr(); isToFeature = aFeature.get() && aFeature == aBaseFeature; - anAttributeToBeModified = SketchPlugin_Constraint::ENTITY_A(); + anAttributeToBeModified = anAttrB->id(); } if (isToFeature) aCoincidentPoint = SketchPlugin_ConstraintCoincidence::getPoint(aRefFeature); } if (!isToFeature) { /// coincidence to point on base feature AttributePtr anAttribute; + if (!anAttrA->isObject()) { AttributePtr aCurAttribute = anAttrA->attr(); if (aCurAttribute.get()) { FeaturePtr aCurFeature = ModelAPI_Feature::feature(aCurAttribute->owner()); if (aCurFeature.get() && aCurFeature == aBaseFeature) { anAttribute = anAttrA->attr(); - anAttributeToBeModified = SketchPlugin_Constraint::ENTITY_A(); + anAttributeToBeModified = anAttrA->id(); } } } @@ -330,7 +360,7 @@ void SketchPlugin_ConstraintSplit::getConstraints(std::set& theFeatu FeaturePtr aCurFeature = ModelAPI_Feature::feature(aCurAttribute->owner()); if (aCurFeature.get() && aCurFeature == aBaseFeature) { anAttribute = anAttrB->attr(); - anAttributeToBeModified = SketchPlugin_Constraint::ENTITY_B(); + anAttributeToBeModified = anAttrB->id(); } } } @@ -351,30 +381,176 @@ void SketchPlugin_ConstraintSplit::getConstraints(std::set& theFeatu } } -/*void SketchPlugin_ConstraintSplit::setConstraints(const FeaturePtr& theSplitFeature, - const FeaturePtr& theBaseFeature, - const FeaturePtr& theAfterFeature, - const std::set>& theFeaturesToDelete, - const std::map, std::shared_ptr >& theTangentFeatures, - const std::map, std::shared_ptr >& theCoincidenceToFeature, - const std::map, std::shared_ptr >& theCoincidenceToPoint) +void SketchPlugin_ConstraintSplit::updateCoincidenceConstraintsToFeature( + const std::map, IdToPointPair>& theCoincidenceToFeature, + const std::set >& theFurtherCoincidences, + const std::set& theFeatureResults) { - // coincidence to feature + if (theCoincidenceToFeature.empty()) + return; + + std::map::const_iterator aCIt = theCoincidenceToFeature.begin(), + aCLast = theCoincidenceToFeature.end(); +#ifdef DEBUG_SPLIT + std::cout << std::endl; + std::cout << "Coincidences to feature(modified):"<< std::endl; +#endif + for (; aCIt != aCLast; aCIt++) { + FeaturePtr aCoincFeature = aCIt->first; + std::string anAttributeId = aCIt->second.first; + AttributePoint2DPtr aCoincPoint = aCIt->second.second; + std::set::const_iterator aFCIt = theFurtherCoincidences.begin(), + aFCLast = theFurtherCoincidences.end(); + std::shared_ptr aCoincPnt = aCoincPoint->pnt(); + AttributePoint2DPtr aFeaturePointAttribute; + for (; aFCIt != aFCLast && !aFeaturePointAttribute.get(); aFCIt++) { + AttributePoint2DPtr aFCAttribute = *aFCIt; + if (aCoincPnt->isEqual(aFCAttribute->pnt())) + aFeaturePointAttribute = aFCAttribute; + } + if (aFeaturePointAttribute.get()) { + aCoincFeature->refattr(anAttributeId)->setAttr(aFeaturePointAttribute); + } + else { + /// find feature by shape intersected the point + ResultPtr aResultForCoincidence = *(theFeatureResults.begin()); + if (theFeatureResults.size() > 1) { // try to find point on additional feature + ResultPtr anAddtionalResult = *(theFeatureResults.begin()++); + GeomShapePtr aShape = anAddtionalResult->shape(); - // coincidence to points + std::shared_ptr aPnt2d = aCoincPoint->pnt(); + std::shared_ptr aPoint = sketch()->to3D(aPnt2d->x(), aPnt2d->y()); - // tangency + std::shared_ptr aProjectedPoint; + if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, aPoint, aProjectedPoint)) + aResultForCoincidence = anAddtionalResult; + } + aCoincFeature->refattr(anAttributeId)->setObject(aResultForCoincidence); + } +#ifdef DEBUG_SPLIT + std::cout << " -" << getFeatureInfo(aCoincFeature) << std::endl; +#endif + } +} - // delete constraints +void SketchPlugin_ConstraintSplit::splitLine(FeaturePtr& theSplitFeature, + FeaturePtr& theBaseFeatureModified, + FeaturePtr& theAfterFeature, + std::set& thePoints, + std::set& theCreatedFeatures) +{ + std::set aCreatedFeatures; + FeaturePtr aConstraintFeature; + theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature + + SketchPlugin_Sketch* aSketch = sketch(); + if (!aSketch) + return; + + AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( + data()->attribute(SketchPlugin_Constraint::VALUE())); + FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); + std::string aFeatureKind = aBaseFeature->getKind(); + if (aFeatureKind != SketchPlugin_Line::ID()) + return; + + AttributePoint2DPtr aFirstPointAttr = getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A())); + AttributePoint2DPtr aSecondPointAttr = getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B())); + AttributePoint2DPtr aStartPointAttr, anEndPointAttr; + getFeaturePoints(aStartPointAttr, anEndPointAttr); + if (!aStartPointAttr.get() && !anEndPointAttr.get()) { + setError("Error: Feature has no start and end points."); + return; + } + + arrangePoints(aStartPointAttr, anEndPointAttr, aFirstPointAttr, aSecondPointAttr); + + /// split feature + theSplitFeature = createLineFeature(aBaseFeature, aFirstPointAttr, aSecondPointAttr); + theCreatedFeatures.insert(theSplitFeature); + + // before split feature + if (!aStartPointAttr->pnt()->isEqual(aFirstPointAttr->pnt())) { + theBaseFeatureModified = aBaseFeature; ///< use base feature to store all constraints here + /// move end arc point to start of split + } + + // after split feature + if (!aSecondPointAttr->pnt()->isEqual(anEndPointAttr->pnt())) { + FeaturePtr aFeature; + if (!theBaseFeatureModified.get()) { + aFeature = aBaseFeature; ///< use base feature to store all constraints here + fillAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), aSecondPointAttr); + aFeature->execute(); // to update result + } + else { + aFeature = createLineFeature(aBaseFeature, aSecondPointAttr, anEndPointAttr); + theCreatedFeatures.insert(aFeature); + } + aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), + theSplitFeature->attribute(SketchPlugin_Line::END_ID()), + aFeature->attribute(SketchPlugin_Line::START_ID())); + theCreatedFeatures.insert(aConstraintFeature); + + thePoints.insert(std::dynamic_pointer_cast + (aFeature->attribute(SketchPlugin_Line::START_ID()))); + thePoints.insert(std::dynamic_pointer_cast + (aFeature->attribute(SketchPlugin_Line::END_ID()))); + + if (!theBaseFeatureModified.get()) + theBaseFeatureModified = aFeature; + else + theAfterFeature = aFeature; + } + else + thePoints.insert(std::dynamic_pointer_cast + (theSplitFeature->attribute(SketchPlugin_Line::END_ID()))); + + // base split, that is defined before split feature should be changed at end + // (after the after feature creation). Otherwise modified value will be used in after feature + // before split feature + if (!aStartPointAttr->pnt()->isEqual(aFirstPointAttr->pnt())) { + /// move end arc point to start of split + fillAttribute(theBaseFeatureModified->attribute(SketchPlugin_Line::END_ID()), aFirstPointAttr); + theBaseFeatureModified->execute(); // to update result + aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), + theBaseFeatureModified->attribute(SketchPlugin_Line::END_ID()), + theSplitFeature->attribute(SketchPlugin_Line::START_ID())); + theCreatedFeatures.insert(aConstraintFeature); + + thePoints.insert(std::dynamic_pointer_cast + (theBaseFeatureModified->attribute(SketchPlugin_Line::START_ID()))); + thePoints.insert(std::dynamic_pointer_cast + (theBaseFeatureModified->attribute(SketchPlugin_Line::END_ID()))); + } + else + thePoints.insert(std::dynamic_pointer_cast + (theSplitFeature->attribute(SketchPlugin_Line::START_ID()))); -}*/ + // additional constraints between split and base features + aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintParallel::ID(), + getFeatureResult(aBaseFeature), + getFeatureResult(theSplitFeature)); + theCreatedFeatures.insert(aConstraintFeature); + if (theAfterFeature.get()) { + aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintParallel::ID(), + getFeatureResult(aBaseFeature), + getFeatureResult(theAfterFeature)); + theCreatedFeatures.insert(aConstraintFeature); + } +} void SketchPlugin_ConstraintSplit::splitArc(FeaturePtr& theSplitFeature, - FeaturePtr& theBaseFeature, + FeaturePtr& theBaseFeatureModified, FeaturePtr& theAfterFeature, - std::set& thePoints) + std::set& thePoints, + std::set& theCreatedFeatures) { + std::set aCreatedFeatures; + FeaturePtr aConstraintFeature; + theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature + SketchPlugin_Sketch* aSketch = sketch(); if (!aSketch) return; @@ -399,34 +575,38 @@ void SketchPlugin_ConstraintSplit::splitArc(FeaturePtr& theSplitFeature, /// split feature theSplitFeature = createArcFeature(aBaseFeature, aFirstPointAttr, aSecondPointAttr); + theCreatedFeatures.insert(theSplitFeature); // before split feature if (!aStartPointAttr->pnt()->isEqual(aFirstPointAttr->pnt())) { - theBaseFeature = aBaseFeature; ///< use base feature to store all constraints here + theBaseFeatureModified = aBaseFeature; ///< use base feature to store all constraints here /// move end arc point to start of split } // after split feature if (!aSecondPointAttr->pnt()->isEqual(anEndPointAttr->pnt())) { FeaturePtr aFeature; - if (!theBaseFeature.get()) { + if (!theBaseFeatureModified.get()) { aFeature = aBaseFeature; ///< use base feature to store all constraints here fillAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), aSecondPointAttr); aFeature->execute(); // to update result } - else + else { aFeature = createArcFeature(aBaseFeature, aSecondPointAttr, anEndPointAttr); - - createConstraint(SketchPlugin_ConstraintCoincidence::ID(), + theCreatedFeatures.insert(aFeature); + } + aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), theSplitFeature->attribute(SketchPlugin_Arc::END_ID()), aFeature->attribute(SketchPlugin_Arc::START_ID())); + theCreatedFeatures.insert(aConstraintFeature); + thePoints.insert(std::dynamic_pointer_cast - (theBaseFeature->attribute(SketchPlugin_Arc::START_ID()))); + (aFeature->attribute(SketchPlugin_Arc::START_ID()))); thePoints.insert(std::dynamic_pointer_cast - (theBaseFeature->attribute(SketchPlugin_Arc::END_ID()))); + (aFeature->attribute(SketchPlugin_Arc::END_ID()))); - if (!theBaseFeature.get()) - theBaseFeature = aFeature; + if (!theBaseFeatureModified.get()) + theBaseFeatureModified = aFeature; else theAfterFeature = aFeature; } @@ -439,33 +619,99 @@ void SketchPlugin_ConstraintSplit::splitArc(FeaturePtr& theSplitFeature, // before split feature if (!aStartPointAttr->pnt()->isEqual(aFirstPointAttr->pnt())) { /// move end arc point to start of split - fillAttribute(theBaseFeature->attribute(SketchPlugin_Arc::END_ID()), aFirstPointAttr); - theBaseFeature->execute(); // to update result - createConstraint(SketchPlugin_ConstraintCoincidence::ID(), - theBaseFeature->attribute(SketchPlugin_Arc::END_ID()), + fillAttribute(theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()), aFirstPointAttr); + theBaseFeatureModified->execute(); // to update result + aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), + theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()), theSplitFeature->attribute(SketchPlugin_Arc::START_ID())); + theCreatedFeatures.insert(aConstraintFeature); + thePoints.insert(std::dynamic_pointer_cast - (theBaseFeature->attribute(SketchPlugin_Arc::START_ID()))); + (theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID()))); thePoints.insert(std::dynamic_pointer_cast - (theBaseFeature->attribute(SketchPlugin_Arc::END_ID()))); + (theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()))); } else thePoints.insert(std::dynamic_pointer_cast (theSplitFeature->attribute(SketchPlugin_Arc::START_ID()))); // additional constraints between split and base features - createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), getFeatureResult(aBaseFeature), + aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), + getFeatureResult(aBaseFeature), getFeatureResult(theSplitFeature)); - createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), getFeatureResult(theSplitFeature), - getFeatureResult(aBaseFeature)); + theCreatedFeatures.insert(aConstraintFeature); + aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), + getFeatureResult(theSplitFeature), + getFeatureResult(aBaseFeature)); + theCreatedFeatures.insert(aConstraintFeature); if (theAfterFeature.get()) { - createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), getFeatureResult(aBaseFeature), - getFeatureResult(theAfterFeature)); - createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), getFeatureResult(theSplitFeature), - getFeatureResult(theAfterFeature)); + aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), + getFeatureResult(aBaseFeature), + getFeatureResult(theAfterFeature)); + theCreatedFeatures.insert(aConstraintFeature); + aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), + getFeatureResult(theSplitFeature), + getFeatureResult(theAfterFeature)); + theCreatedFeatures.insert(aConstraintFeature); } } +void SketchPlugin_ConstraintSplit::splitCircle(FeaturePtr& theSplitFeature, + FeaturePtr& theBaseFeatureModified, + FeaturePtr& theAfterFeature, + std::set& thePoints, + std::set& theCreatedFeatures) +{ + std::set aCreatedFeatures; + FeaturePtr aConstraintFeature; + theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature + + SketchPlugin_Sketch* aSketch = sketch(); + if (!aSketch) + return; + + AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( + data()->attribute(SketchPlugin_Constraint::VALUE())); + FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); + std::string aFeatureKind = aBaseFeature->getKind(); + if (aFeatureKind != SketchPlugin_Circle::ID()) + return; + + AttributePoint2DPtr aFirstPointAttr = getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A())); + AttributePoint2DPtr aSecondPointAttr = getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B())); + + /// split feature + theSplitFeature = createArcFeature(aBaseFeature, aFirstPointAttr, aSecondPointAttr); + bool aSplitReversed = std::dynamic_pointer_cast(theSplitFeature)->isReversed(); + theCreatedFeatures.insert(theSplitFeature); + + /// base feature is a left part of the circle + theBaseFeatureModified = createArcFeature(aBaseFeature, aFirstPointAttr, aSecondPointAttr); + std::dynamic_pointer_cast(theBaseFeatureModified)->setReversed(!aSplitReversed); + theBaseFeatureModified->execute(); + theCreatedFeatures.insert(theBaseFeatureModified); + + thePoints.insert(std::dynamic_pointer_cast + (theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID()))); + thePoints.insert(std::dynamic_pointer_cast + (theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()))); + + // additional constraints between split and base features + aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), + theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()), + theSplitFeature->attribute(SketchPlugin_Arc::START_ID())); + theCreatedFeatures.insert(aConstraintFeature); + aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), + theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID()), + theSplitFeature->attribute(SketchPlugin_Arc::END_ID())); + theCreatedFeatures.insert(aConstraintFeature); + + aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), + getFeatureResult(theSplitFeature), + getFeatureResult(theBaseFeatureModified)); + theCreatedFeatures.insert(aConstraintFeature); +} + void SketchPlugin_ConstraintSplit::arrangePoints(const AttributePoint2DPtr& theStartPointAttr, const AttributePoint2DPtr& theEndPointAttr, AttributePoint2DPtr& theFirstPointAttr, @@ -492,6 +738,28 @@ void SketchPlugin_ConstraintSplit::fillAttribute(const AttributePtr& theModified aModifiedAttribute->setValue(aSourceAttribute->pnt()); } +FeaturePtr SketchPlugin_ConstraintSplit::createLineFeature(const FeaturePtr& theBaseFeature, + const AttributePtr& theFirstPointAttr, + const AttributePtr& theSecondPointAttr) +{ + FeaturePtr aFeature; + SketchPlugin_Sketch* aSketch = sketch(); + if (!aSketch || !theBaseFeature.get()) + return aFeature; + + aFeature = aSketch->addFeature(SketchPlugin_Line::ID()); + // update fillet arc: make the arc correct for sure, so, it is not needed to process the "attribute updated" + // by arc; moreover, it may cause cyclicity in hte mechanism of updater + aFeature->data()->blockSendAttributeUpdated(true); + + fillAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPointAttr); + fillAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPointAttr); + aFeature->data()->blockSendAttributeUpdated(false); + aFeature->execute(); // to obtain result + + return aFeature; +} + FeaturePtr SketchPlugin_ConstraintSplit::createArcFeature(const FeaturePtr& theBaseFeature, const AttributePtr& theFirstPointAttr, const AttributePtr& theSecondPointAttr) @@ -501,15 +769,25 @@ FeaturePtr SketchPlugin_ConstraintSplit::createArcFeature(const FeaturePtr& theB if (!aSketch || !theBaseFeature.get()) return aFeature; - aFeature = aSketch->addFeature(theBaseFeature->getKind()); + std::string aCenterAttributeId; + if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) + aCenterAttributeId = SketchPlugin_Arc::CENTER_ID(); + else if (theBaseFeature->getKind() == SketchPlugin_Circle::ID()) + aCenterAttributeId = SketchPlugin_Circle::CENTER_ID(); + + if (aCenterAttributeId.empty()) + return aFeature; + + aFeature = aSketch->addFeature(SketchPlugin_Arc::ID()); // update fillet arc: make the arc correct for sure, so, it is not needed to process the "attribute updated" // by arc; moreover, it may cause cyclicity in hte mechanism of updater aFeature->data()->blockSendAttributeUpdated(true); aFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue( SketchPlugin_Arc::ARC_TYPE_CENTER_START_END()); + fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()), - theBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID())); + theBaseFeature->attribute(aCenterAttributeId)); fillAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPointAttr); fillAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPointAttr); aFeature->data()->blockSendAttributeUpdated(false); @@ -518,7 +796,7 @@ FeaturePtr SketchPlugin_ConstraintSplit::createArcFeature(const FeaturePtr& theB return aFeature; } -void SketchPlugin_ConstraintSplit::createConstraint(const std::string& theConstraintId, +FeaturePtr SketchPlugin_ConstraintSplit::createConstraint(const std::string& theConstraintId, const AttributePtr& theFirstAttribute, const AttributePtr& theSecondAttribute) { @@ -530,9 +808,11 @@ void SketchPlugin_ConstraintSplit::createConstraint(const std::string& theConstr aRefAttr = std::dynamic_pointer_cast( aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); aRefAttr->setAttr(theSecondAttribute); + + return aConstraint; } -void SketchPlugin_ConstraintSplit::createConstraintForObjects(const std::string& theConstraintId, +FeaturePtr SketchPlugin_ConstraintSplit::createConstraintForObjects(const std::string& theConstraintId, const ObjectPtr& theFirstObject, const ObjectPtr& theSecondObject) { @@ -544,6 +824,8 @@ void SketchPlugin_ConstraintSplit::createConstraintForObjects(const std::string& aRefAttr = std::dynamic_pointer_cast( aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); aRefAttr->setObject(theSecondObject); + + return aConstraint; } std::shared_ptr SketchPlugin_ConstraintSplit::getFeatureResult( @@ -562,3 +844,86 @@ std::shared_ptr SketchPlugin_ConstraintSplit::getFeatureResult( return aResult; } +std::set > SketchPlugin_ConstraintSplit::getEdgeAttributes( + const std::shared_ptr& theFeature) +{ + std::set > anAttributes; + + std::string aFeatureKind = theFeature->getKind(); + if (aFeatureKind == SketchPlugin_Line::ID()) { + anAttributes.insert(theFeature->attribute(SketchPlugin_Line::START_ID())); + anAttributes.insert(theFeature->attribute(SketchPlugin_Line::END_ID())); + } + else if (aFeatureKind == SketchPlugin_Arc::ID()) { + anAttributes.insert(theFeature->attribute(SketchPlugin_Arc::START_ID())); + anAttributes.insert(theFeature->attribute(SketchPlugin_Arc::END_ID())); + } + else if (aFeatureKind == SketchPlugin_Circle::ID()) { + } + + return anAttributes; +} + + +std::string SketchPlugin_ConstraintSplit::getFeatureInfo( + const std::shared_ptr& theFeature, + const bool isUseAttributesInfo) +{ + std::string anInfo; + if (!theFeature.get()) { + return "none"; + } + + //anInfo.append(theFeature->getKind().c_str()); + if (theFeature->data()->isValid()) { + //anInfo.append(", name="); + anInfo.append(theFeature->data()->name().c_str()); + } + if (isUseAttributesInfo) { + std::string aPointsInfo = ModelGeomAlgo_Point2D::getPontAttributesInfo(theFeature, + getEdgeAttributes(theFeature)); + if (!aPointsInfo.empty()) { /// processing of feature with point 2d attributes, like line, arc, circle + anInfo += ": "; + anInfo += "\n"; + anInfo += aPointsInfo; + } + else { /// process constraint coincidence, find points in ref attr attributes + std::list anAttrs = theFeature->data()->attributes( + ModelAPI_AttributeRefAttr::typeId()); + std::list::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end(); + std::string anAttributesInfo; + for(; anIt != aLast; anIt++) { + if (!anAttributesInfo.empty()) { + anAttributesInfo.append(", "); + anAttributesInfo += "\n"; + } + AttributePtr anAttr = *anIt; + std::string aValue = "not defined"; + std::string aType = anAttr->attributeType(); + if (aType == ModelAPI_AttributeRefAttr::typeId()) { + std::shared_ptr aRefAttr = + std::dynamic_pointer_cast(anAttr); + if (aRefAttr.get()) { + if (aRefAttr->isObject()) { + FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object()); + aValue = "" + getFeatureInfo(aFeature, false); + } + else { + AttributePtr anAttribute = aRefAttr->attr(); + if (anAttribute.get()) { + FeaturePtr aFeature = ModelAPI_Feature::feature(anAttribute->owner()); + aValue = "" + ModelGeomAlgo_Point2D::getPointAttributeInfo(anAttribute) + + " [" + getFeatureInfo(aFeature, false) + "]"; + } + } + } + } + anAttributesInfo.append(" " + anAttr->id() + ": " + aValue); + } + if (!anAttributesInfo.empty()) + anInfo = anInfo + "\n" + anAttributesInfo; + } + } + return anInfo; +} + diff --git a/src/SketchPlugin/SketchPlugin_ConstraintSplit.h b/src/SketchPlugin/SketchPlugin_ConstraintSplit.h index 2167a71c3..adbc3c81e 100755 --- a/src/SketchPlugin/SketchPlugin_ConstraintSplit.h +++ b/src/SketchPlugin/SketchPlugin_ConstraintSplit.h @@ -106,31 +106,49 @@ private: std::map, IdToPointPair>& theCoincidenceToFeature, std::map, IdToPointPair>& theCoincidenceToPoint); - /// Obtains those constraints of the feature that should be modified - /// \param theSplitFeature a result split feature - /// \param theBaseFeature a modified base feature - /// \param theAfterFeature an additional created feature if source segement contain three parts - /// \param theFeaturesToDelete [out] constrains that will be deleted after split - /// \param theTangentFeatures [out] tangent feature to be connected to new feature + /// Move coincidence constraint from feature to point if it is found /// \param theCoincidenceToFeature [out] coincidence to feature to be connected to new feature - /// \param theCoincidenceToPoint [out] coincidence to point be connected to new feature - /*void setConstraints(const FeaturePtr& theSplitFeature, - const FeaturePtr& theBaseFeature, - const FeaturePtr& theAfterFeature, - const std::set>& theFeaturesToDelete, - const std::map, IdToPointPair>& theTangentFeatures, - const std::map, IdToPointPair>& theCoincidenceToFeature, - const std::map, IdToPointPair>& theCoincidenceToPoint);*/ + /// \param theFurtherCoincidences a list of points where coincidences will be build + void updateCoincidenceConstraintsToFeature( + const std::map, IdToPointPair>& theCoincidenceToFeature, + const std::set >& theFurtherCoincidences, + const std::set& theFeatureResults); /// Make the base object is splitted by the point attributes /// \param theSplitFeature a result split feature /// \param theBeforeFeature a feature between start point and the 1st point of split feature /// \param theAfterFeature a feature between last point of split feature and the end point /// \param thePoints a list of points where coincidences will be build + /// \param theCreatedFeatures a container of created features + void splitLine(std::shared_ptr& theSplitFeature, + std::shared_ptr& theBeforeFeature, + std::shared_ptr& theAfterFeature, + std::set >& thePoints, + std::set>& theCreatedFeatures); + + /// Make the base object is splitted by the point attributes + /// \param theSplitFeature a result split feature + /// \param theBeforeFeature a feature between start point and the 1st point of split feature + /// \param theAfterFeature a feature between last point of split feature and the end point + /// \param thePoints a list of points where coincidences will be build + /// \param theCreatedFeatures a container of created features void splitArc(std::shared_ptr& theSplitFeature, std::shared_ptr& theBeforeFeature, std::shared_ptr& theAfterFeature, - std::set >& thePoints); + std::set >& thePoints, + std::set>& theCreatedFeatures); + + /// Make the base object is splitted by the point attributes + /// \param theSplitFeature a result split feature + /// \param theBeforeFeature a feature between start point and the 1st point of split feature + /// \param theAfterFeature a feature between last point of split feature and the end point + /// \param thePoints a list of points where coincidences will be build + /// \param theCreatedFeatures a container of created features + void splitCircle(std::shared_ptr& theSplitFeature, + std::shared_ptr& theBeforeFeature, + std::shared_ptr& theAfterFeature, + std::set >& thePoints, + std::set>& theCreatedFeatures); /// Correct the first and the second point to provide condition that the first is closer to /// the start point and the second point - to the last end of current segment. To rearrange @@ -150,6 +168,14 @@ private: void fillAttribute(const AttributePtr& theModifiedAttribute, const AttributePtr& theSourceAttribute); + /// Creates a line feature filled by center of base feature and given points + /// \param theBaseFeature another arc feature + /// \param theFirstAttribute an attribute with coordinates for the start point + /// \param theSecondAttribute an attribute with coordinates for the end point + FeaturePtr createLineFeature(const FeaturePtr& theBaseFeature, + const AttributePtr& theFirstPointAttr, + const AttributePtr& theSecondPointAttr); + /// Creates an arc feature filled by center of base feature and given points /// \param theBaseFeature another arc feature /// \param theFirstAttribute an attribute with coordinates for the start point @@ -162,7 +188,7 @@ private: /// \param theConstraintId a constraint index /// \param theFirstAttribute an attribute of further coincidence /// \param theSecondAttribute an attribute of further coincidence - void createConstraint(const std::string& theConstraintId, + std::shared_ptr createConstraint(const std::string& theConstraintId, const std::shared_ptr& theFirstAttribute, const std::shared_ptr& theSecondAttribute); @@ -170,7 +196,7 @@ private: /// \param theConstraintId a constraint index /// \param theFirstAttribute an attribute of further coincidence /// \param theFirstAttribute an attribute of further coincidence - void createConstraintForObjects(const std::string& theConstraintId, + std::shared_ptr createConstraintForObjects(const std::string& theConstraintId, const std::shared_ptr& theFirstObject, const std::shared_ptr& theSecondObject); @@ -179,6 +205,19 @@ private: /// \return result object std::shared_ptr getFeatureResult( const std::shared_ptr& theFeature); + + /// Returns attributes of the feature, used in edge build, for arc it is end and start points + /// \param theFeature a feature + /// \return container of attributes + std::set > getEdgeAttributes( + const std::shared_ptr& theFeature); + + /// Return feature name, kind, point attribute values united in a string + /// \param theFeature an investigated feature + /// \return string value + std::string getFeatureInfo(const std::shared_ptr& theFeature, + const bool isUseAttributesInfo = true); + private: //std::set myNewPoints; ///< set of new points //std::map myPointFeaturesMap; ///< map of point and features for fillet -- 2.39.2