X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_Split.cpp;h=b0a5658ffef5145a4ee4c13906f34caa50aed772;hb=4ddacde2a835dcba71074928bd8412e8ae9de57f;hp=a7a8f69b224e7250d4ef0b9ad8ab173509c5f3f9;hpb=87b6a30a3afb8fb32e7e43ade8d9c947d9eb1684;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Split.cpp b/src/SketchPlugin/SketchPlugin_Split.cpp index a7a8f69b2..b0a5658ff 100644 --- a/src/SketchPlugin/SketchPlugin_Split.cpp +++ b/src/SketchPlugin/SketchPlugin_Split.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// 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 @@ -12,10 +12,9 @@ // // 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 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "SketchPlugin_Split.h" @@ -28,7 +27,6 @@ #include #include #include -#include #include #include @@ -45,12 +43,15 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#include #include #include #include @@ -64,7 +65,6 @@ //#define CREATE_CONSTRAINTS -//#define DEBUG_SPLIT #ifdef DEBUG_SPLIT #include #endif @@ -89,11 +89,6 @@ void SketchPlugin_Split::initAttributes() ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PREVIEW_POINT()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PREVIEW_OBJECT()); - - // TODO: remove - //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()); } void SketchPlugin_Split::execute() @@ -103,26 +98,21 @@ void SketchPlugin_Split::execute() // Check the base objects are initialized. AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( data()->attribute(SELECTED_OBJECT())); - //ObjectPtr aBaseObject = anObjectAttr->value(); - //AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - // aData->attribute(SketchPlugin_Constraint::VALUE())); if(!aBaseObjectAttr->isInitialized()) { setError("Error: Base object is not initialized."); return; } ObjectPtr aBaseObject = aBaseObjectAttr->value(); AttributePoint2DPtr aFirstPointAttrOfSplit = getPointAttribute(true); - // getPointOfRefAttr(aData->attribute(SketchPlugin_Constraint::ENTITY_A())); AttributePoint2DPtr aSecondPointAttrOfSplit = getPointAttribute(false); - // getPointOfRefAttr(aData->attribute(SketchPlugin_Constraint::ENTITY_B())); if (!aFirstPointAttrOfSplit.get() || !aFirstPointAttrOfSplit->isInitialized() || !aSecondPointAttrOfSplit.get() || !aSecondPointAttrOfSplit->isInitialized()) { setError("Error: Sub-shape is not initialized."); return; } - /// Remove reference of this feature to feature used in preview, it is not necessary anymore - /// as trim will be removed after execute + // Remove reference of this feature to feature used in preview, it is not necessary anymore + // as trim will be removed after execute AttributeReferencePtr aPreviewObjectAttr = std::dynamic_pointer_cast( data()->attribute(PREVIEW_OBJECT())); @@ -143,17 +133,17 @@ void SketchPlugin_Split::execute() // Find feature constraints FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObject); - ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature); + ResultPtr aBaseFeatureResult = aBaseFeature->lastResult(); std::set aFeaturesToDelete, aFeaturesToUpdate; //std::map aTangentFeatures; std::map aCoincidenceToFeature; - getConstraints(aFeaturesToDelete, aFeaturesToUpdate, /*aTangentFeatures, */ - aCoincidenceToFeature); + getConstraints(aFeaturesToDelete, aFeaturesToUpdate, aCoincidenceToFeature); std::map > aBaseRefAttributes; std::list aRefsToFeature; - getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature); + SketchPlugin_SegmentationTools::getRefAttributes( + aBaseFeature, aBaseRefAttributes, aRefsToFeature); std::map aBasePointModifiedAttributes; @@ -235,6 +225,8 @@ void SketchPlugin_Split::execute() std::cout << std::endl; #endif + keepCurrentFeature(); + std::string aFeatureKind = aBaseFeature->getKind(); FeaturePtr aSplitFeature, anAfterFeature; std::set aFurtherCoincidences; @@ -247,15 +239,19 @@ void SketchPlugin_Split::execute() else if (aFeatureKind == SketchPlugin_Arc::ID()) aNewFeature = splitArc(aSplitFeature, aBaseFeature, anAfterFeature, aFurtherCoincidences, aCreatedFeatures, aModifiedAttributes); - if (aFeatureKind == SketchPlugin_Circle::ID()) { - FeaturePtr aCircleFeature = aBaseFeature; - aReplacingFeature = splitCircle(aSplitFeature, aBaseFeature, anAfterFeature, + else if (aFeatureKind == SketchPlugin_EllipticArc::ID()) + aNewFeature = splitEllipticArc(aSplitFeature, aBaseFeature, anAfterFeature, + aFurtherCoincidences, aCreatedFeatures, aModifiedAttributes); + + restoreCurrentFeature(); + + if (aFeatureKind == SketchPlugin_Circle::ID() || aFeatureKind == SketchPlugin_Ellipse::ID()) { + aFeaturesToDelete.insert(aBaseFeature); + aReplacingFeature = splitClosed(aSplitFeature, aBaseFeature, anAfterFeature, aFurtherCoincidences, aCreatedFeatures, aModifiedAttributes); - updateRefFeatureConstraints(getFeatureResult(aBaseFeature), aRefsToFeature); + updateRefFeatureConstraints(aBaseFeature->lastResult(), aRefsToFeature); - AttributePtr aCenterAttr = aCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID()); - aFeaturesToDelete.insert(aCircleFeature); // as circle is removed, temporary fill this attribute*/ aBaseObjectAttr->setObject(ResultPtr()); } @@ -311,15 +307,15 @@ void SketchPlugin_Split::execute() #endif std::set aFeatureResults; - aFeatureResults.insert(getFeatureResult(aBaseFeature)); + aFeatureResults.insert(aBaseFeature->lastResult()); if (anAfterFeature.get() && anAfterFeature != aBaseFeature) - aFeatureResults.insert(getFeatureResult(anAfterFeature)); + aFeatureResults.insert(anAfterFeature->lastResult()); // coincidence to feature updateCoincidenceConstraintsToFeature(aCoincidenceToFeature, aFurtherCoincidences, - aFeatureResults, aSplitFeature); + aFeatureResults, aSplitFeature, aFeaturesToDelete); - updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes); + SketchPlugin_SegmentationTools::updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes); // delete constraints #ifdef DEBUG_SPLIT @@ -343,7 +339,7 @@ void SketchPlugin_Split::execute() std::cout << std::endl; } #endif - updateFeaturesAfterSplit(aFeaturesToUpdate); + SketchPlugin_SegmentationTools::updateFeaturesAfterOperation(aFeaturesToUpdate); // Send events to update the sub-features by the solver. if(isUpdateFlushed) { @@ -356,7 +352,7 @@ void SketchPlugin_Split::execute() ResultPtr aReplacingResult; if (aReplacingFeature.get()) { aReplacingFeature->execute(); // need it to obtain result - aReplacingResult = getFeatureResult(aReplacingFeature); + aReplacingResult = aReplacingFeature->lastResult(); } if (aReplacingResult.get()) { // base object was removed aPreviewObject = aReplacingResult; @@ -371,7 +367,7 @@ void SketchPlugin_Split::execute() //} //aBaseShape = aShape; -#ifdef DEBUG_TRIM_METHODS +#ifdef DEBUG_SPLIT if (!aSelectedShape.get()) std::cout << "Set empty selected object" << std::endl; else @@ -383,7 +379,7 @@ void SketchPlugin_Split::execute() aPreviewObject = ObjectPtr(); aBaseFeature->execute(); // should recompute shapes of result to do not check obsolete one - aBaseObject = getFeatureResult(aBaseFeature); + aBaseObject = aBaseFeature->lastResult(); std::shared_ptr aPreviewPnt = sketch()->to3D(aPreviewPnt2d->x(), aPreviewPnt2d->y()); ResultPtr aBaseResult = std::dynamic_pointer_cast(aBaseObject); @@ -394,7 +390,7 @@ void SketchPlugin_Split::execute() aPreviewObject = aBaseResult; } if (!aPreviewObject.get() && aNewFeature.get()) { - ResultPtr aNewFeatureResult = getFeatureResult(aNewFeature); + ResultPtr aNewFeatureResult = aNewFeature->lastResult(); if (aNewFeatureResult.get()) { GeomShapePtr aShape = aNewFeatureResult->shape(); std::shared_ptr aProjectedPoint; @@ -421,10 +417,11 @@ void SketchPlugin_Split::execute() #endif } +// LCOV_EXCL_START std::string SketchPlugin_Split::processEvent(const std::shared_ptr& theMessage) { -#ifdef DEBUG_TRIM_METHODS - std::cout << "SketchPlugin_Trim::processEvent:" << data()->name() << std::endl; +#ifdef DEBUG_SPLIT + std::cout << "SketchPlugin_Split::processEvent:" << data()->name() << std::endl; #endif std::string aFilledAttributeName; @@ -435,10 +432,10 @@ std::string SketchPlugin_Split::processEvent(const std::shared_ptr aPoint = aMessage->clickedPoint(); if (anObject.get() && aPoint.get()) { - //if (myCashedShapes.find(anObject) == myCashedShapes.end()) - // fillObjectShapes(anObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints); - if (myCashedShapes.find(anObject) == myCashedShapes.end()) - fillObjectShapes(anObject, sketch()->data()->owner()); + if (myCashedShapes.find(anObject) == myCashedShapes.end()) { + SketchPlugin_SegmentationTools::fillObjectShapes( + this, anObject, myCashedShapes, myCashedReferences); + } const std::set& aShapes = myCashedShapes[anObject]; if (aShapes.size() > 1) { std::shared_ptr aRefSelectedAttr = @@ -461,287 +458,39 @@ std::string SketchPlugin_Split::processEvent(const std::shared_ptrflush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); - GeomShapePtr aSelectedShape = getSubShape(SELECTED_OBJECT(), SELECTED_POINT()); - #ifdef DEBUG_TRIM_METHODS + GeomShapePtr aSelectedShape = SketchPlugin_SegmentationTools::getSubShape(this, + SELECTED_OBJECT(), SELECTED_POINT(), myCashedShapes, myCashedReferences); + if (aSelectedShape.get()) { + aFilledAttributeName = SELECTED_OBJECT(); + } + else { + // #2480 - sub shape is not initialized when split sketch + // If restarted operation use some selection on the shape that is split and + // result selectiona can not participate in new split(checked shape above is null), + // reset filled values of selection set in this method above + aRefSelectedAttr->setValue(ResultPtr()); + aRefPreviewAttr->setValue(ResultPtr()); + } + #ifdef DEBUG_SPLIT if (!aSelectedShape.get()) std::cout << "Set empty selected object" << std::endl; else std::cout << "Set shape with ShapeType: " << aSelectedShape->shapeTypeStr() << std::endl; #endif - aFilledAttributeName = SELECTED_OBJECT(); } } } return aFilledAttributeName; } +// LCOV_EXCL_STOP AISObjectPtr SketchPlugin_Split::getAISObject(AISObjectPtr thePrevious) { - /*AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Constraint::VALUE())); - FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); - - AttributePoint2DPtr aFirstPointAttrOfSplit = getPointOfRefAttr( - data()->attribute(SketchPlugin_Constraint::ENTITY_A())); - AttributePoint2DPtr aSecondPointAttrOfSplit = getPointOfRefAttr( - data()->attribute(SketchPlugin_Constraint::ENTITY_B())); - - if (aBaseObjectAttr->isInitialized() && aBaseFeature.get() && - aFirstPointAttrOfSplit->isInitialized() && - aSecondPointAttrOfSplit->isInitialized()) { - - ResultPtr aResult = getFeatureResult(aBaseFeature); - GeomShapePtr aBaseShape = aResult->shape(); - std::list > aPoints; - - std::shared_ptr aStartPnt2d = aFirstPointAttrOfSplit->pnt(); - std::shared_ptr aStartPoint = sketch()->to3D(aStartPnt2d->x(), aStartPnt2d->y()); - aPoints.push_back(aStartPoint); - - std::shared_ptr aSecondPnt2d = aSecondPointAttrOfSplit->pnt(); - std::shared_ptr aSecondPoint = - sketch()->to3D(aSecondPnt2d->x(), aSecondPnt2d->y()); - aPoints.push_back(aSecondPoint); - - std::set > aSplitShapes; - - GeomAlgoAPI_ShapeTools::splitShape_p(aBaseShape, aPoints, aSplitShapes); - std::shared_ptr aShape = - GeomAlgoAPI_ShapeTools::findShape(aPoints, aSplitShapes); - - AISObjectPtr anAIS = thePrevious; - if (aShape) { - if (!anAIS) - anAIS = AISObjectPtr(new GeomAPI_AISObject); - anAIS->createShape(aShape); - std::shared_ptr anAuxiliaryAttr = - aBaseFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID()); - - bool isConstruction = anAuxiliaryAttr.get() != NULL && anAuxiliaryAttr->value(); - - std::vector aColor; - double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH(); - int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE(); - if (isConstruction) { - aColor = Config_PropManager::color("Visualization", "sketch_auxiliary_color"); - aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH_AUXILIARY(); - aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE_AUXILIARY(); - } - else { - aColor = Config_PropManager::color("Visualization", "sketch_entity_color"); - } - anAIS->setColor(aColor[0], aColor[1], aColor[2]); - anAIS->setWidth(aWidth + 1); - anAIS->setLineStyle(aLineStyle); - } - return anAIS; - } - return AISObjectPtr();*/ -#ifdef DEBUG_TRIM_METHODS - std::cout << "SketchPlugin_Trim::getAISObject: " << data()->name() << std::endl; -#endif - - AISObjectPtr anAIS = thePrevious; - - std::list > aShapes; - GeomShapePtr aPreviewShape = getSubShape(PREVIEW_OBJECT(), PREVIEW_POINT()); - if (aPreviewShape.get()) - aShapes.push_back(aPreviewShape); - GeomShapePtr aSelectedShape = getSubShape(SELECTED_OBJECT(), SELECTED_POINT()); - if (aSelectedShape.get()) - aShapes.push_back(aSelectedShape); - - if (aShapes.empty()) - return AISObjectPtr(); - - GeomShapePtr aBaseShape = GeomAlgoAPI_CompoundBuilder::compound(aShapes); - if (!aBaseShape.get()) - return AISObjectPtr(); - - if (aBaseShape.get()) { - if (!anAIS) - anAIS = AISObjectPtr(new GeomAPI_AISObject); - anAIS->createShape(aBaseShape); - - std::vector aColor; - aColor = Config_PropManager::color("Visualization", "operation_remove_feature_color"); - double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH(); - int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE(); - anAIS->setColor(aColor[0], aColor[1], aColor[2]); - // width when there is not base object should be extened in several points - // in order to see this preview over highlight - anAIS->setWidth(aWidth+4); - anAIS->setLineStyle(aLineStyle); - } - else - anAIS = AISObjectPtr(); - return anAIS; + return SketchPlugin_SegmentationTools::getAISObject(thePrevious, + this, PREVIEW_OBJECT(), PREVIEW_POINT(), SELECTED_OBJECT(), SELECTED_POINT()); } //******************************************************************** -void SketchPlugin_Split::fillObjectShapes(const ObjectPtr& theObject, - const ObjectPtr& theSketch) -{ - std::set > aShapes; - std::map, std::shared_ptr > aPointToAttributes; - std::set > aRefAttributes; - // current feature - FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); - // edges on feature - std::set anEdgeResults; - ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeResults); - if (!anEdgeResults.empty()) { - GeomShapePtr aFeatureShape = (*anEdgeResults.begin())->shape(); - - // coincidences to the feature - ModelGeomAlgo_Point2D::getPointsOfReference(aFeature, SketchPlugin_ConstraintCoincidence::ID(), - aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID()); - // layed on feature coincidences to divide it on several shapes - std::shared_ptr aData = theSketch->data(); - std::shared_ptr aC = std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - std::shared_ptr aX = std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Sketch::DIRX_ID())); - std::shared_ptr aNorm = std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Sketch::NORM_ID())); - std::shared_ptr aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir()))); - std::list > aPoints; - ModelGeomAlgo_Point2D::getPointsInsideShape_p(aFeatureShape, aRefAttributes, aC->pnt(), - aX->dir(), aY, aPoints, aPointToAttributes); - - GeomAlgoAPI_ShapeTools::splitShape_p(aFeatureShape, aPoints, aShapes); - } - myCashedShapes[theObject] = aShapes; - myCashedReferences[theObject] = aPointToAttributes; -} - -GeomShapePtr SketchPlugin_Split::getSubShape(const std::string& theObjectAttributeId, - const std::string& thePointAttributeId) -{ - GeomShapePtr aBaseShape; - - AttributeReferencePtr anObjectAttr = std::dynamic_pointer_cast( - data()->attribute(theObjectAttributeId)); - ObjectPtr aBaseObject = anObjectAttr->value(); - if (!aBaseObject.get()) - return aBaseShape; - - // point on feature - AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast( - data()->attribute(thePointAttributeId)); - std::shared_ptr anAttributePnt2d = aPointAttr->pnt(); - std::shared_ptr anAttributePnt = sketch()->to3D(anAttributePnt2d->x(), - anAttributePnt2d->y()); - -#ifdef TRIM_SHAPE - if (myCashedShapes.find(aBaseObject) == myCashedShapes.end()) - fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints); - - const std::set& aShapes = myCashedShapes[aBaseObject]; - if (!aShapes.empty()) { - std::set::const_iterator anIt = aShapes.begin(), aLast = aShapes.end(); - for (; anIt != aLast; anIt++) { - GeomShapePtr aShape = *anIt; - std::shared_ptr aProjectedPoint; - if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, anAttributePnt, aProjectedPoint)) - aBaseShape = aShape; - } - } -#else - if (myCashedShapes.find(aBaseObject) == myCashedShapes.end()) - fillObjectShapes(aBaseObject, sketch()->data()->owner()); - - std::shared_ptr aStartPoint; - std::shared_ptr aSecondPoint; - const std::set& aShapes = myCashedShapes[aBaseObject]; - std::set::const_iterator anIt = aShapes.begin(), aLast = aShapes.end(); - for (; anIt != aLast; anIt++) { - GeomShapePtr aCurrentShape = *anIt; - std::shared_ptr aProjectedPoint; - if (ModelGeomAlgo_Point2D::isPointOnEdge(aCurrentShape, anAttributePnt, aProjectedPoint)) { - if (aCurrentShape->shapeType() == GeomAPI_Shape::EDGE) { - std::shared_ptr anEdge(new GeomAPI_Edge(aCurrentShape)); - aStartPoint = anEdge->firstPoint(); - aSecondPoint = anEdge->lastPoint(); - } - break; - } - } - - if (!aStartPoint.get() || !aSecondPoint.get()) - return aBaseShape; - - //AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - // data()->attribute(SketchPlugin_Constraint::VALUE())); - FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObject/*aBaseObjectAttr->value()*/); - - //AttributePoint2DPtr aFirstPointAttrOfSplit = getPointOfRefAttr( - // data()->attribute(SketchPlugin_Constraint::ENTITY_A())); - //AttributePoint2DPtr aSecondPointAttrOfSplit = getPointOfRefAttr( - // data()->attribute(SketchPlugin_Constraint::ENTITY_B())); - if (anObjectAttr->isInitialized() && aBaseFeature.get() && aPointAttr->isInitialized()) { - //aFirstPointAttrOfSplit->isInitialized() && - //aSecondPointAttrOfSplit->isInitialized()) { - ResultPtr aResult = getFeatureResult(aBaseFeature); - GeomShapePtr aResultShape = aResult->shape(); - std::list > aPoints; - - //std::shared_ptr aStartPnt2d = aFirstPointAttrOfSplit->pnt(); - //std::shared_ptr aStartPoint = sketch()->to3D(aStartPnt2d->x(), aStartPnt2d->y()); - aPoints.push_back(aStartPoint); - - //std::shared_ptr aSecondPnt2d = aSecondPointAttrOfSplit->pnt(); - //std::shared_ptr aSecondPoint = - // sketch()->to3D(aSecondPnt2d->x(), aSecondPnt2d->y()); - aPoints.push_back(aSecondPoint); - - std::set > aSplitShapes; - GeomAlgoAPI_ShapeTools::splitShape_p(aResultShape, aPoints, aSplitShapes); - aBaseShape = GeomAlgoAPI_ShapeTools::findShape(aPoints, aSplitShapes); -#endif - } - return aBaseShape; -} - -std::shared_ptr SketchPlugin_Split::getPointOfRefAttr( - const AttributePtr& theAttribute) -{ - AttributePoint2DPtr aPointAttribute; - - if (theAttribute->attributeType() == ModelAPI_AttributeRefAttr::typeId()) { - AttributeRefAttrPtr aRefAttr = - std::dynamic_pointer_cast(theAttribute); - if (aRefAttr.get() && aRefAttr->isInitialized()) { - AttributePtr anAttribute = aRefAttr->attr(); - if (anAttribute.get() && anAttribute->attributeType() == GeomDataAPI_Point2D::typeId()) - aPointAttribute = std::dynamic_pointer_cast(anAttribute); - } - } - return aPointAttribute; -} - -void SketchPlugin_Split::getFeaturePoints(const FeaturePtr& theFeature, - AttributePoint2DPtr& theStartPointAttr, - AttributePoint2DPtr& theEndPointAttr) -{ - std::string aFeatureKind = theFeature->getKind(); - std::string aStartAttributeName, anEndAttributeName; - if (aFeatureKind == SketchPlugin_Line::ID()) { - aStartAttributeName = SketchPlugin_Line::START_ID(); - anEndAttributeName = SketchPlugin_Line::END_ID(); - } - else if (aFeatureKind == SketchPlugin_Arc::ID()) { - aStartAttributeName = SketchPlugin_Arc::START_ID(); - anEndAttributeName = SketchPlugin_Arc::END_ID(); - } - if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) { - theStartPointAttr = std::dynamic_pointer_cast( - theFeature->attribute(aStartAttributeName)); - theEndPointAttr = std::dynamic_pointer_cast( - theFeature->attribute(anEndAttributeName)); - } -} - void SketchPlugin_Split::getConstraints(std::set& theFeaturesToDelete, std::set& theFeaturesToUpdate, std::map& theCoincidenceToFeature) @@ -751,10 +500,8 @@ void SketchPlugin_Split::getConstraints(std::set& theFeaturesToDelet // Check the base objects are initialized. AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( data()->attribute(SELECTED_OBJECT())); - //AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - // aData->attribute(SketchPlugin_Constraint::VALUE())); FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); - ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature); + ResultPtr aBaseFeatureResult = aBaseFeature->lastResult(); std::set aRefsList = aBaseFeatureResult->data()->refsToMe(); std::set aFRefsList = aBaseFeature->data()->refsToMe(); @@ -772,13 +519,14 @@ void SketchPlugin_Split::getConstraints(std::set& theFeaturesToDelet theFeaturesToDelete.insert(aRefFeature); else if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID()) theFeaturesToUpdate.insert(aRefFeature); - else if (aRefFeatureKind == SketchPlugin_ConstraintCoincidence::ID()) { + else if (aRefFeatureKind == SketchPlugin_ConstraintCoincidence::ID() || + aRefFeatureKind == SketchPlugin_ConstraintCoincidenceInternal::ID()) { std::string anAttributeToBeModified; AttributePoint2DPtr aCoincidentPoint; AttributeRefAttrPtr anAttrA = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A()); AttributeRefAttrPtr anAttrB = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_B()); bool isToFeature = false; - if (anAttrA->isObject() || anAttrB->isObject()) { /// coincidence to base feature + if (anAttrA->isObject() || anAttrB->isObject()) { // coincidence to base feature FeaturePtr aFeature = anAttrA->isObject() ? ModelAPI_Feature::feature(anAttrA->object()) : FeaturePtr(); isToFeature = aFeature.get() && aFeature == aBaseFeature; @@ -792,7 +540,7 @@ void SketchPlugin_Split::getConstraints(std::set& theFeaturesToDelet if (isToFeature) aCoincidentPoint = SketchPlugin_ConstraintCoincidence::getPoint(aRefFeature); } - if (!isToFeature) { /// coincidence to point on base feature + if (!isToFeature) { // coincidence to point on base feature AttributePtr anAttribute; if (!anAttrA->isObject()) { @@ -825,57 +573,12 @@ void SketchPlugin_Split::getConstraints(std::set& theFeaturesToDelet } } -void SketchPlugin_Split::getRefAttributes(const FeaturePtr& theFeature, - std::map >& theRefs, - std::list& theRefsToFeature) -{ - theRefs.clear(); - - std::list aPointAttributes = - theFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); - std::set aPointAttributesSet; - - std::list::const_iterator aPIt = - aPointAttributes.begin(), aPLast = aPointAttributes.end(); - for (; aPIt != aPLast; aPIt++) - aPointAttributesSet.insert(*aPIt); - - std::set aRefsAttributes = getFeatureResult(theFeature)->data()->refsToMe(); - std::set aFRefsList = theFeature->data()->refsToMe(); - aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end()); - - std::set::const_iterator aIt; - for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) { - AttributePtr anAttr = (*aIt); - FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner()); - if (anAttrFeature.get() != this && - anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) { - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(anAttr); - if (!aRefAttr->isObject()) { /// find attributes referenced to feature point attributes - AttributePtr anAttrInRef = aRefAttr->attr(); - if (anAttrInRef.get() && - aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) { - if (theRefs.find(anAttrInRef) != theRefs.end()) - theRefs[anAttrInRef].push_back(aRefAttr); - else { - std::list anAttrList; - anAttrList.push_back(aRefAttr); - theRefs[anAttrInRef] = anAttrList; - } - } - } - else { /// find attributes referenced to feature itself - theRefsToFeature.push_back(anAttr); - } - } - } -} - void SketchPlugin_Split::updateCoincidenceConstraintsToFeature( const std::map, IdToPointPair>& theCoincidenceToFeature, const std::set >& theFurtherCoincidences, const std::set& theFeatureResults, - const FeaturePtr& theSplitFeature) + const FeaturePtr& theSplitFeature, + std::set& theFeaturesToDelete) { if (theCoincidenceToFeature.empty()) return; @@ -883,14 +586,15 @@ void SketchPlugin_Split::updateCoincidenceConstraintsToFeature( // we should build coincidence constraints to end of the split feature std::set > aNewCoincidencesToSplitFeature; AttributePoint2DPtr aStartPointAttr, anEndPointAttr; - getFeaturePoints(theSplitFeature, aStartPointAttr, anEndPointAttr); + SketchPlugin_SegmentationTools::getFeaturePoints( + theSplitFeature, aStartPointAttr, anEndPointAttr); if (theFurtherCoincidences.find(aStartPointAttr) == theFurtherCoincidences.end()) aNewCoincidencesToSplitFeature.insert(aStartPointAttr); if (theFurtherCoincidences.find(anEndPointAttr) == theFurtherCoincidences.end()) aNewCoincidencesToSplitFeature.insert(anEndPointAttr); std::map::const_iterator aCIt = theCoincidenceToFeature.begin(), - aCLast = theCoincidenceToFeature.end(); + aCLast = theCoincidenceToFeature.end(); #ifdef DEBUG_SPLIT std::cout << std::endl; std::cout << "Coincidences to feature(modified):"<< std::endl; @@ -898,6 +602,9 @@ void SketchPlugin_Split::updateCoincidenceConstraintsToFeature( for (; aCIt != aCLast; aCIt++) { FeaturePtr aCoincFeature = aCIt->first; std::string anAttributeId = aCIt->second.first; + std::string aSecondAttribute = anAttributeId == SketchPlugin_Constraint::ENTITY_A() ? + SketchPlugin_Constraint::ENTITY_B() : SketchPlugin_Constraint::ENTITY_A(); + AttributePoint2DPtr aCoincPoint = aCIt->second.second; std::set::const_iterator aFCIt = theFurtherCoincidences.begin(), aFCLast = theFurtherCoincidences.end(); @@ -909,24 +616,25 @@ void SketchPlugin_Split::updateCoincidenceConstraintsToFeature( aFeaturePointAttribute = aFCAttribute; } if (aFeaturePointAttribute.get()) { - aCoincFeature->refattr(anAttributeId)->setObject(ResultPtr()); - aCoincFeature->refattr(anAttributeId)->setAttr(aFeaturePointAttribute); + // create new constraint and remove the current + aCoincFeature = SketchPlugin_Tools::createConstraintAttrAttr(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), + aFeaturePointAttribute, aCoincFeature->refattr(aSecondAttribute)->attr()); + theFeaturesToDelete.insert(aCIt->first); // create new coincidences to split feature points std::set::const_iterator aSFIt = aNewCoincidencesToSplitFeature.begin(), aSFLast = aNewCoincidencesToSplitFeature.end(); for (; aSFIt != aSFLast; aSFIt++) { AttributePoint2DPtr aSFAttribute = *aSFIt; if (aCoincPnt->isEqual(aSFAttribute->pnt())) { - std::string aSecondAttribute = SketchPlugin_Constraint::ENTITY_A(); - if (anAttributeId == SketchPlugin_Constraint::ENTITY_A()) - aSecondAttribute = SketchPlugin_Constraint::ENTITY_B(); - createConstraint(SketchPlugin_ConstraintCoincidence::ID(), + SketchPlugin_Tools::createConstraintAttrAttr(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), aSFAttribute, aCoincFeature->refattr(aSecondAttribute)->attr()); } } } else { - /// find feature by shape intersected the point + // find feature by shape intersected the point ResultPtr aResultForCoincidence = *(theFeatureResults.begin()); if (theFeatureResults.size() > 1) { // try to find point on additional feature @@ -961,45 +669,11 @@ void SketchPlugin_Split::updateRefFeatureConstraints( } } -void SketchPlugin_Split::updateRefAttConstraints( - const std::map >& theBaseRefAttributes, - const std::set >& theModifiedAttributes) -{ -#ifdef DEBUG_SPLIT - std::cout << "SketchPlugin_Split::updateRefAttConstraints" << std::endl; -#endif - - std::set >::const_iterator - anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end(); - for (; anIt != aLast; anIt++) { - AttributePtr anAttribute = anIt->first; - - /// not found in references - if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end()) - continue; - std::list aRefAttributes = theBaseRefAttributes.at(anAttribute); - std::list::const_iterator aRefIt = aRefAttributes.begin(), - aRLast = aRefAttributes.end(); - - AttributePtr aNewAttribute = anIt->second; - for (; aRefIt != aRLast; aRefIt++) { - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(*aRefIt); - if (aRefAttr.get()) { - aRefAttr->setAttr(aNewAttribute); -#ifdef DEBUG_SPLIT - FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner()); - std::cout << " -" << getFeatureInfo(aFeature) << std::endl; -#endif - } - } - } -} - FeaturePtr SketchPlugin_Split::splitLine(FeaturePtr& theSplitFeature, - FeaturePtr& theBaseFeatureModified, - FeaturePtr& theAfterFeature, - std::set& thePoints, - std::set& theCreatedFeatures, + FeaturePtr& theBaseFeatureModified, + FeaturePtr& theAfterFeature, + std::set& thePoints, + std::set& theCreatedFeatures, std::set>& theModifiedAttributes) { FeaturePtr anNewFeature; @@ -1008,26 +682,16 @@ FeaturePtr SketchPlugin_Split::splitLine(FeaturePtr& theSplitFeature, FeaturePtr aConstraintFeature; theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature - SketchPlugin_Sketch* aSketch = sketch(); - if (!aSketch) - return anNewFeature; - AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( data()->attribute(SELECTED_OBJECT())); - //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 anNewFeature; AttributePoint2DPtr aFirstPointAttrOfSplit = getPointAttribute(true); - //getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A())); AttributePoint2DPtr aSecondPointAttrOfSplit = getPointAttribute(false); - //getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B())); AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase; - getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); + SketchPlugin_SegmentationTools::getFeaturePoints( + aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); if (!aStartPointAttrOfBase.get() && !anEndPointAttrOfBase.get()) { setError("Error: Feature has no start and end points."); return anNewFeature; @@ -1048,9 +712,9 @@ FeaturePtr SketchPlugin_Split::splitLine(FeaturePtr& theSplitFeature, ModelGeomAlgo_Point2D::getPointAttributeInfo(anEndPointAttrOfBase) << std::endl; #endif - /// create a split feature - theSplitFeature = - createLineFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); + // create a split feature + theSplitFeature = SketchPlugin_SegmentationTools::createLineFeature( + aBaseFeature, aFirstPointAttrOfSplit->pnt(), aSecondPointAttrOfSplit->pnt()); theCreatedFeatures.insert(theSplitFeature); // before split feature @@ -1059,26 +723,28 @@ FeaturePtr SketchPlugin_Split::splitLine(FeaturePtr& theSplitFeature, theSplitFeature->attribute(SketchPlugin_Line::START_ID()))); } else { - theBaseFeatureModified = aBaseFeature; ///< use base feature to store all constraints here - /// move end arc point to start of split + theBaseFeatureModified = aBaseFeature; // use base feature to store all constraints here + // move end arc point to start of split } // after split feature if (!aSecondPointAttrOfSplit->pnt()->isEqual(anEndPointAttrOfBase->pnt())) { FeaturePtr aFeature; if (!theBaseFeatureModified.get()) { - aFeature = aBaseFeature; ///< use base feature to store all constraints here + aFeature = aBaseFeature; // use base feature to store all constraints here fillAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), aSecondPointAttrOfSplit); aFeature->execute(); // to update result } else { - aFeature = createLineFeature(aBaseFeature, aSecondPointAttrOfSplit, anEndPointAttrOfBase); + aFeature = SketchPlugin_SegmentationTools::createLineFeature( + aBaseFeature, aSecondPointAttrOfSplit->pnt(), anEndPointAttrOfBase->pnt()); theCreatedFeatures.insert(aFeature); theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase, aFeature->attribute(SketchPlugin_Line::END_ID()))); anNewFeature = aFeature; } - aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), + aConstraintFeature = SketchPlugin_Tools::createConstraintAttrAttr(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), theSplitFeature->attribute(SketchPlugin_Line::END_ID()), aFeature->attribute(SketchPlugin_Line::START_ID())); theCreatedFeatures.insert(aConstraintFeature); @@ -1103,11 +769,12 @@ FeaturePtr SketchPlugin_Split::splitLine(FeaturePtr& theSplitFeature, // (after the after feature creation). Otherwise modified value will be used in after feature // before split feature if (!aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) { - /// move end arc point to start of split + // move end arc point to start of split fillAttribute(theBaseFeatureModified->attribute(SketchPlugin_Line::END_ID()), aFirstPointAttrOfSplit); theBaseFeatureModified->execute(); // to update result - aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), + aConstraintFeature = SketchPlugin_Tools::createConstraintAttrAttr(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), theBaseFeatureModified->attribute(SketchPlugin_Line::END_ID()), theSplitFeature->attribute(SketchPlugin_Line::START_ID())); theCreatedFeatures.insert(aConstraintFeature); @@ -1123,14 +790,16 @@ FeaturePtr SketchPlugin_Split::splitLine(FeaturePtr& theSplitFeature, #ifdef CREATE_CONSTRAINTS // additional constraints between split and base features - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintParallel::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(theSplitFeature)); + aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), + SketchPlugin_ConstraintParallel::ID(), + aBaseFeature->lastResult(), + theSplitFeature->lastResult()); theCreatedFeatures.insert(aConstraintFeature); if (theAfterFeature.get()) { - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintParallel::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(theAfterFeature)); + aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), + SketchPlugin_ConstraintParallel::ID(), + aBaseFeature->lastResult(), + theAfterFeature->lastResult()); theCreatedFeatures.insert(aConstraintFeature); } #endif @@ -1138,10 +807,10 @@ FeaturePtr SketchPlugin_Split::splitLine(FeaturePtr& theSplitFeature, } FeaturePtr SketchPlugin_Split::splitArc(FeaturePtr& theSplitFeature, - FeaturePtr& theBaseFeatureModified, - FeaturePtr& theAfterFeature, - std::set& thePoints, - std::set& theCreatedFeatures, + FeaturePtr& theBaseFeatureModified, + FeaturePtr& theAfterFeature, + std::set& thePoints, + std::set& theCreatedFeatures, std::set>& theModifiedAttributes) { FeaturePtr anNewFeature; @@ -1150,25 +819,14 @@ FeaturePtr SketchPlugin_Split::splitArc(FeaturePtr& theSplitFeature, FeaturePtr aConstraintFeature; theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature - SketchPlugin_Sketch* aSketch = sketch(); - if (!aSketch) - return anNewFeature; - - AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SELECTED_OBJECT())); - //AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - // data()->attribute(SketchPlugin_Constraint::VALUE())); + AttributeReferencePtr aBaseObjectAttr = reference(SELECTED_OBJECT()); FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); - std::string aFeatureKind = aBaseFeature->getKind(); - if (aFeatureKind != SketchPlugin_Arc::ID()) - return anNewFeature; AttributePoint2DPtr aFirstPointAttrOfSplit = getPointAttribute(true); - //getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A())); AttributePoint2DPtr aSecondPointAttrOfSplit = getPointAttribute(false); - //getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B())); AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase; - getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); + SketchPlugin_SegmentationTools::getFeaturePoints( + aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); if (!aStartPointAttrOfBase.get() && !anEndPointAttrOfBase.get()) { setError("Error: Feature has no start and end points."); return anNewFeature; @@ -1188,8 +846,9 @@ FeaturePtr SketchPlugin_Split::splitArc(FeaturePtr& theSplitFeature, ModelGeomAlgo_Point2D::getPointAttributeInfo(anEndPointAttrOfBase) << std::endl; #endif - /// split feature - theSplitFeature = createArcFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); + // split feature + theSplitFeature = SketchPlugin_SegmentationTools::createArcFeature( + aBaseFeature, aFirstPointAttrOfSplit->pnt(), aSecondPointAttrOfSplit->pnt()); theCreatedFeatures.insert(theSplitFeature); // before split feature @@ -1198,26 +857,28 @@ FeaturePtr SketchPlugin_Split::splitArc(FeaturePtr& theSplitFeature, theSplitFeature->attribute(SketchPlugin_Arc::START_ID()))); } else { - theBaseFeatureModified = aBaseFeature; ///< use base feature to store all constraints here - /// move end arc point to start of split + theBaseFeatureModified = aBaseFeature; // use base feature to store all constraints here + // move end arc point to start of split } // after split feature if (!aSecondPointAttrOfSplit->pnt()->isEqual(anEndPointAttrOfBase->pnt())) { FeaturePtr aFeature; if (!theBaseFeatureModified.get()) { - aFeature = aBaseFeature; ///< use base feature to store all constraints here + aFeature = aBaseFeature; // use base feature to store all constraints here fillAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), aSecondPointAttrOfSplit); aFeature->execute(); // to update result } else { - aFeature = createArcFeature(aBaseFeature, aSecondPointAttrOfSplit, anEndPointAttrOfBase); + aFeature = SketchPlugin_SegmentationTools::createArcFeature( + aBaseFeature, aSecondPointAttrOfSplit->pnt(), anEndPointAttrOfBase->pnt()); theCreatedFeatures.insert(aFeature); theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase, aFeature->attribute(SketchPlugin_Arc::END_ID()))); anNewFeature = aFeature; } - aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), + aConstraintFeature = SketchPlugin_Tools::createConstraintAttrAttr(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), theSplitFeature->attribute(SketchPlugin_Arc::END_ID()), aFeature->attribute(SketchPlugin_Arc::START_ID())); theCreatedFeatures.insert(aConstraintFeature); @@ -1242,11 +903,12 @@ FeaturePtr SketchPlugin_Split::splitArc(FeaturePtr& theSplitFeature, // (after the after feature creation). Otherwise modified value will be used in after feature // before split feature if (!aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) { - /// move end arc point to start of split + // move end arc point to start of split fillAttribute(theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()), aFirstPointAttrOfSplit); theBaseFeatureModified->execute(); // to update result - aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), + aConstraintFeature = SketchPlugin_Tools::createConstraintAttrAttr(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()), theSplitFeature->attribute(SketchPlugin_Arc::START_ID())); theCreatedFeatures.insert(aConstraintFeature); @@ -1262,29 +924,177 @@ FeaturePtr SketchPlugin_Split::splitArc(FeaturePtr& theSplitFeature, // additional constraints between split and base features #ifdef CREATE_CONSTRAINTS - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(theSplitFeature)); + aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), + SketchPlugin_ConstraintEqual::ID(), + aBaseFeature->lastResult(), + theSplitFeature->lastResult()); + theCreatedFeatures.insert(aConstraintFeature); + aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), + SketchPlugin_ConstraintTangent::ID(), + theSplitFeature->lastResult(), + aBaseFeature->lastResult()); + theCreatedFeatures.insert(aConstraintFeature); + if (theAfterFeature.get()) { + aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), + SketchPlugin_ConstraintEqual::ID(), + aBaseFeature->lastResult(), + theAfterFeature->lastResult()); + theCreatedFeatures.insert(aConstraintFeature); + aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), + SketchPlugin_ConstraintTangent::ID(), + theSplitFeature->lastResult(), + theAfterFeature->lastResult()); + theCreatedFeatures.insert(aConstraintFeature); + } +#endif + return anNewFeature; +} + +FeaturePtr SketchPlugin_Split::splitEllipticArc(FeaturePtr& theSplitFeature, + FeaturePtr& theBaseFeatureModified, + FeaturePtr& theAfterFeature, + std::set& thePoints, + std::set& theCreatedFeatures, + std::set>& theModifiedAttributes) +{ + FeaturePtr anNewFeature; + + std::set aCreatedFeatures; + FeaturePtr aConstraintFeature; + theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature + + AttributeReferencePtr aBaseObjectAttr = reference(SELECTED_OBJECT()); + FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); + + AttributePoint2DPtr aFirstPointAttrOfSplit = getPointAttribute(true); + AttributePoint2DPtr aSecondPointAttrOfSplit = getPointAttribute(false); + AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase; + SketchPlugin_SegmentationTools::getFeaturePoints( + aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); + if (!aStartPointAttrOfBase.get() && !anEndPointAttrOfBase.get()) { + setError("Error: Feature has no start and end points."); + return anNewFeature; + } + + arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase, + aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); +#ifdef DEBUG_SPLIT + std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl; + std::cout << "Start point: " << + ModelGeomAlgo_Point2D::getPointAttributeInfo(aStartPointAttrOfBase) << std::endl; + std::cout << "1st point: " << + ModelGeomAlgo_Point2D::getPointAttributeInfo(aFirstPointAttrOfSplit) << std::endl; + std::cout << "2nd point: " << + ModelGeomAlgo_Point2D::getPointAttributeInfo(aSecondPointAttrOfSplit) << std::endl; + std::cout << "End point: " << + ModelGeomAlgo_Point2D::getPointAttributeInfo(anEndPointAttrOfBase) << std::endl; +#endif + + // split feature + theSplitFeature = SketchPlugin_SegmentationTools::createArcFeature( + aBaseFeature, aFirstPointAttrOfSplit->pnt(), aSecondPointAttrOfSplit->pnt()); + theCreatedFeatures.insert(theSplitFeature); + + // before split feature + if (aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) { + theModifiedAttributes.insert(std::make_pair(aStartPointAttrOfBase, + theSplitFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID()))); + } + else { + theBaseFeatureModified = aBaseFeature; // use base feature to store all constraints here + // move end arc point to start of split + } + + // after split feature + if (!aSecondPointAttrOfSplit->pnt()->isEqual(anEndPointAttrOfBase->pnt())) { + FeaturePtr aFeature; + if (!theBaseFeatureModified.get()) { + aFeature = aBaseFeature; // use base feature to store all constraints here + fillAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), aSecondPointAttrOfSplit); + aFeature->execute(); // to update result + } + else { + aFeature = SketchPlugin_SegmentationTools::createArcFeature( + aBaseFeature, aSecondPointAttrOfSplit->pnt(), anEndPointAttrOfBase->pnt()); + theCreatedFeatures.insert(aFeature); + theModifiedAttributes.insert(std::make_pair( + anEndPointAttrOfBase, aFeature->attribute(SketchPlugin_EllipticArc::END_POINT_ID()))); + anNewFeature = aFeature; + } + aConstraintFeature = SketchPlugin_Tools::createConstraintAttrAttr(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), + theSplitFeature->attribute(SketchPlugin_EllipticArc::END_POINT_ID()), + aFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID())); + theCreatedFeatures.insert(aConstraintFeature); + + thePoints.insert(std::dynamic_pointer_cast + (aFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID()))); + thePoints.insert(std::dynamic_pointer_cast + (aFeature->attribute(SketchPlugin_EllipticArc::END_POINT_ID()))); + + if (!theBaseFeatureModified.get()) + theBaseFeatureModified = aFeature; + else + theAfterFeature = aFeature; + } + else { + thePoints.insert(std::dynamic_pointer_cast( + theSplitFeature->attribute(SketchPlugin_EllipticArc::END_POINT_ID()))); + theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase, + theSplitFeature->attribute(SketchPlugin_EllipticArc::END_POINT_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 (!aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) { + // move end arc point to start of split + fillAttribute(theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::END_POINT_ID()), + aFirstPointAttrOfSplit); + theBaseFeatureModified->execute(); // to update result + aConstraintFeature = SketchPlugin_Tools::createConstraintAttrAttr(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), + theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::END_POINT_ID()), + theSplitFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID())); + theCreatedFeatures.insert(aConstraintFeature); + + thePoints.insert(std::dynamic_pointer_cast( + theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::START_POINT_ID()))); + thePoints.insert(std::dynamic_pointer_cast( + theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::END_POINT_ID()))); + } + else + thePoints.insert(std::dynamic_pointer_cast( + theSplitFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID()))); + + // additional constraints between split and base features +#ifdef CREATE_CONSTRAINTS + aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), + SketchPlugin_ConstraintEqual::ID(), + aBaseFeature->lastResult(), + theSplitFeature->lastResult()); theCreatedFeatures.insert(aConstraintFeature); - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), - getFeatureResult(theSplitFeature), - getFeatureResult(aBaseFeature)); + aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), + SketchPlugin_ConstraintTangent::ID(), + theSplitFeature->lastResult(), + aBaseFeature->lastResult()); theCreatedFeatures.insert(aConstraintFeature); if (theAfterFeature.get()) { - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(theAfterFeature)); + aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), + SketchPlugin_ConstraintEqual::ID(), + aBaseFeature->lastResult(), + theAfterFeature->lastResult()); theCreatedFeatures.insert(aConstraintFeature); - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), - getFeatureResult(theSplitFeature), - getFeatureResult(theAfterFeature)); + aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), + SketchPlugin_ConstraintTangent::ID(), + theSplitFeature->lastResult(), + theAfterFeature->lastResult()); theCreatedFeatures.insert(aConstraintFeature); } #endif return anNewFeature; } -FeaturePtr SketchPlugin_Split::splitCircle(FeaturePtr& theSplitFeature, +FeaturePtr SketchPlugin_Split::splitClosed(FeaturePtr& theSplitFeature, FeaturePtr& theBaseFeatureModified, FeaturePtr& theAfterFeature, std::set& thePoints, @@ -1297,63 +1107,96 @@ FeaturePtr SketchPlugin_Split::splitCircle(FeaturePtr& theSplitFeature, FeaturePtr aConstraintFeature; theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature - SketchPlugin_Sketch* aSketch = sketch(); - if (!aSketch) - return anNewFeature; - - AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SELECTED_OBJECT())); - //AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - // data()->attribute(SketchPlugin_Constraint::VALUE())); + AttributeReferencePtr aBaseObjectAttr = reference(SELECTED_OBJECT()); FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); - std::string aFeatureKind = aBaseFeature->getKind(); - if (aFeatureKind != SketchPlugin_Circle::ID()) - return anNewFeature; AttributePoint2DPtr aFirstPointAttrOfSplit = getPointAttribute(true); - //getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A())); AttributePoint2DPtr aSecondPointAttrOfSplit = getPointAttribute(false); - //getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B())); - /// split feature - theSplitFeature = - createArcFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); - bool aSplitReversed = std::dynamic_pointer_cast(theSplitFeature)->isReversed(); + // split feature + theSplitFeature = SketchPlugin_SegmentationTools::createArcFeature( + aBaseFeature, aFirstPointAttrOfSplit->pnt(), aSecondPointAttrOfSplit->pnt()); + const std::string& aReversedAttrName = theSplitFeature->getKind() == SketchPlugin_Arc::ID() ? + SketchPlugin_Arc::REVERSED_ID() : SketchPlugin_EllipticArc::REVERSED_ID(); + bool aSplitReversed = theSplitFeature->boolean(aReversedAttrName)->value(); theCreatedFeatures.insert(theSplitFeature); - /// base feature is a left part of the circle - theBaseFeatureModified = createArcFeature(aBaseFeature, - aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); + // base feature is a left part of the circle + theBaseFeatureModified = SketchPlugin_SegmentationTools::createArcFeature( + aBaseFeature, aFirstPointAttrOfSplit->pnt(), aSecondPointAttrOfSplit->pnt()); anNewFeature = theBaseFeatureModified; - std::dynamic_pointer_cast( - theBaseFeatureModified)->setReversed(!aSplitReversed); + theBaseFeatureModified->boolean(aReversedAttrName)->setValue(!aSplitReversed); theBaseFeatureModified->execute(); - theModifiedAttributes.insert( - std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()), - theBaseFeatureModified->attribute(SketchPlugin_Arc::CENTER_ID()))); + if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) { + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()), + theBaseFeatureModified->attribute(SketchPlugin_Arc::CENTER_ID()))); + } + else if (aBaseFeature->getKind() == SketchPlugin_Ellipse::ID()) { + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::CENTER_ID()), + theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::CENTER_ID()))); + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::FIRST_FOCUS_ID()), + theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::FIRST_FOCUS_ID()))); + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::SECOND_FOCUS_ID()), + theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::SECOND_FOCUS_ID()))); + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::MAJOR_AXIS_START_ID()), + theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::MAJOR_AXIS_START_ID()))); + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::MAJOR_AXIS_END_ID()), + theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID()))); + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::MINOR_AXIS_START_ID()), + theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::MINOR_AXIS_START_ID()))); + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::MINOR_AXIS_END_ID()), + theBaseFeatureModified->attribute(SketchPlugin_EllipticArc::MINOR_AXIS_END_ID()))); + + // update the PARENT_ID reference for all the features created by the ellipse + const std::set& aRefs = aBaseFeature->data()->refsToMe(); + std::list aRefsToParent; + for (std::set::const_iterator aRef = aRefs.begin(); aRef != aRefs.end(); ++aRef) { + if ((*aRef)->id() == SketchPlugin_SketchEntity::PARENT_ID()) + aRefsToParent.push_back(*aRef); + } + for (std::list::iterator aRef = aRefsToParent.begin(); + aRef != aRefsToParent.end(); ++aRef) + std::dynamic_pointer_cast(*aRef)->setValue(theSplitFeature); + } theCreatedFeatures.insert(theBaseFeatureModified); + const std::string& aStartAttrName = theSplitFeature->getKind() == SketchPlugin_Arc::ID() ? + SketchPlugin_Arc::START_ID() : SketchPlugin_EllipticArc::START_POINT_ID(); + const std::string& aEndAttrName = theSplitFeature->getKind() == SketchPlugin_Arc::ID() ? + SketchPlugin_Arc::END_ID() : SketchPlugin_EllipticArc::END_POINT_ID(); + thePoints.insert(std::dynamic_pointer_cast - (theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID()))); + (theBaseFeatureModified->attribute(aStartAttrName))); thePoints.insert(std::dynamic_pointer_cast - (theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()))); + (theBaseFeatureModified->attribute(aEndAttrName))); // additional constraints between split and base features - aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), - theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()), - theSplitFeature->attribute(SketchPlugin_Arc::END_ID())); + aConstraintFeature = SketchPlugin_Tools::createConstraintAttrAttr(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), + theBaseFeatureModified->attribute(aEndAttrName), + theSplitFeature->attribute(aEndAttrName)); theCreatedFeatures.insert(aConstraintFeature); - aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(), - theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID()), - theSplitFeature->attribute(SketchPlugin_Arc::START_ID())); + aConstraintFeature = SketchPlugin_Tools::createConstraintAttrAttr(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), + theBaseFeatureModified->attribute(aStartAttrName), + theSplitFeature->attribute(aStartAttrName)); theCreatedFeatures.insert(aConstraintFeature); #ifdef CREATE_CONSTRAINTS - aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(), - getFeatureResult(theSplitFeature), - getFeatureResult(theBaseFeatureModified)); + aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), + SketchPlugin_ConstraintTangent::ID(), + theSplitFeature->lastResult(), + theBaseFeatureModified->lastResult()); theCreatedFeatures.insert(aConstraintFeature); #endif return anNewFeature; @@ -1383,9 +1226,14 @@ void SketchPlugin_Split::arrangePointsOnArc( { static const double anAngleTol = 1.e-12; + const std::string& aCenterAttrName = theArc->getKind() == SketchPlugin_Arc::ID() ? + SketchPlugin_Arc::CENTER_ID() : SketchPlugin_EllipticArc::CENTER_ID(); + const std::string& aReversedAttrName = theArc->getKind() == SketchPlugin_Arc::ID() ? + SketchPlugin_Arc::REVERSED_ID() : SketchPlugin_EllipticArc::REVERSED_ID(); + std::shared_ptr aCenter = std::dynamic_pointer_cast( - theArc->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt(); - bool isReversed = theArc->boolean(SketchPlugin_Arc::REVERSED_ID())->value(); + theArc->attribute(aCenterAttrName))->pnt(); + bool isReversed = theArc->boolean(aReversedAttrName)->value(); // collect directions to each point std::shared_ptr aStartDir( @@ -1435,142 +1283,7 @@ void SketchPlugin_Split::fillAttribute(const AttributePtr& theModifiedAttribute, } } -FeaturePtr SketchPlugin_Split::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()); - - fillAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPointAttr); - fillAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPointAttr); - - fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()), - theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID())); - - aFeature->execute(); // to obtain result - - return aFeature; -} - -FeaturePtr SketchPlugin_Split::createArcFeature(const FeaturePtr& theBaseFeature, - const AttributePtr& theFirstPointAttr, - const AttributePtr& theSecondPointAttr) -{ - FeaturePtr aFeature; - SketchPlugin_Sketch* aSketch = sketch(); - if (!aSketch || !theBaseFeature.get()) - return aFeature; - - 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 - bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true); - - fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()), - theBaseFeature->attribute(aCenterAttributeId)); - fillAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPointAttr); - fillAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPointAttr); - - fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()), - theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID())); - - /// fill referersed state of created arc as it is on the base arc - if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) { - bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->value(); - aFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(aReversed); - } - aFeature->data()->blockSendAttributeUpdated(aWasBlocked); - aFeature->execute(); // to obtain result - - return aFeature; -} - -FeaturePtr SketchPlugin_Split::createConstraint(const std::string& theConstraintId, - const AttributePtr& theFirstAttribute, - const AttributePtr& theSecondAttribute) -{ - FeaturePtr aConstraint = sketch()->addFeature(theConstraintId); - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( - aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); - aRefAttr->setAttr(theFirstAttribute); - - aRefAttr = std::dynamic_pointer_cast( - aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); - aRefAttr->setAttr(theSecondAttribute); - - return aConstraint; -} - -FeaturePtr SketchPlugin_Split::createConstraintForObjects( - const std::string& theConstraintId, - const ObjectPtr& theFirstObject, - const ObjectPtr& theSecondObject) -{ - FeaturePtr aConstraint = sketch()->addFeature(theConstraintId); - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( - aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); - aRefAttr->setObject(theFirstObject); - - aRefAttr = std::dynamic_pointer_cast( - aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); - aRefAttr->setObject(theSecondObject); - - return aConstraint; -} - -void SketchPlugin_Split::updateFeaturesAfterSplit( - const std::set& theFeaturesToUpdate) -{ - std::set::const_iterator anIt = theFeaturesToUpdate.begin(), - aLast = theFeaturesToUpdate.end(); - for (; anIt != aLast; anIt++) { - FeaturePtr aRefFeature = std::dynamic_pointer_cast(*anIt); - std::string aRefFeatureKind = aRefFeature->getKind(); - if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID()) { - std::shared_ptr aLenghtFeature = - std::dynamic_pointer_cast(*anIt); - if (aLenghtFeature.get()) { - std::shared_ptr aValueAttr = std::dynamic_pointer_cast< - ModelAPI_AttributeDouble>(aLenghtFeature->attribute(SketchPlugin_Constraint::VALUE())); - double aValue; - if (aLenghtFeature->computeLenghtValue(aValue) && aValueAttr.get()) - aValueAttr->setValue(aValue); - } - } - } -} - -std::shared_ptr SketchPlugin_Split::getFeatureResult( - const std::shared_ptr& theFeature) -{ - std::shared_ptr aResult; - - std::string aFeatureKind = theFeature->getKind(); - if (aFeatureKind == SketchPlugin_Line::ID()) - aResult = theFeature->firstResult(); - else if (aFeatureKind == SketchPlugin_Arc::ID()) - aResult = theFeature->lastResult(); - else if (aFeatureKind == SketchPlugin_Circle::ID()) - aResult = theFeature->lastResult(); - - return aResult; -} - +#ifdef _DEBUG std::set > SketchPlugin_Split::getEdgeAttributes( const std::shared_ptr& theFeature) { @@ -1585,18 +1298,24 @@ std::set > SketchPlugin_Split::getEdgeAttrib anAttributes.insert(theFeature->attribute(SketchPlugin_Arc::START_ID())); anAttributes.insert(theFeature->attribute(SketchPlugin_Arc::END_ID())); } + else if (aFeatureKind == SketchPlugin_EllipticArc::ID()) { + anAttributes.insert(theFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID())); + anAttributes.insert(theFeature->attribute(SketchPlugin_EllipticArc::END_POINT_ID())); + } else if (aFeatureKind == SketchPlugin_Circle::ID()) { } return anAttributes; } +#endif std::shared_ptr SketchPlugin_Split::getPointAttribute (const bool isFirstAttribute) { std::shared_ptr anAttribute; - GeomShapePtr aSelectedShape = getSubShape(SELECTED_OBJECT(), SELECTED_POINT()); + GeomShapePtr aSelectedShape = SketchPlugin_SegmentationTools::getSubShape(this, + SELECTED_OBJECT(), SELECTED_POINT(), myCashedShapes, myCashedReferences); if (!aSelectedShape.get()) return anAttribute; @@ -1615,7 +1334,7 @@ std::shared_ptr SketchPlugin_Split::getPointAttribute std::shared_ptr aLastPnt = anEdge->lastPoint(); std::shared_ptr aFirstPointAttr, aLastPointAttr; - /// find the points in feature attributes + // find the points in feature attributes FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObject); std::list a2DPointAttributes = aBaseFeature->data()->attributes( GeomDataAPI_Point2D::typeId()); @@ -1632,17 +1351,17 @@ std::shared_ptr SketchPlugin_Split::getPointAttribute aLastPointAttr = anAttributePoint; } - /// find the points in coincident features - PntToAttributesMap aRefAttributes = myCashedReferences[aBaseObject]; - PntToAttributesMap::const_iterator + // find the points in coincident features + const GeomAlgoAPI_ShapeTools::PointToRefsMap& aRefAttributes = myCashedReferences.at(aBaseObject); + GeomAlgoAPI_ShapeTools::PointToRefsMap::const_iterator aRIt = aRefAttributes.begin(), aRLast = aRefAttributes.end(); for (; aRIt != aRLast; aRIt++) { - std::shared_ptr anAttribute = aRIt->first; - std::shared_ptr aPoint = aRIt->second; + const std::list& anAttributes = aRIt->second.first; + GeomPointPtr aPoint = aRIt->first; if (!aFirstPointAttr.get() && aFirstPnt->isEqual(aPoint)) - aFirstPointAttr = anAttribute; + aFirstPointAttr = anAttributes.front(); if (!aLastPointAttr.get() && aLastPnt->isEqual(aPoint)) - aLastPointAttr = anAttribute; + aLastPointAttr = anAttributes.front(); if (aFirstPointAttr.get() && aLastPointAttr.get()) break; } @@ -1667,13 +1386,13 @@ std::string SketchPlugin_Split::getFeatureInfo(const std::shared_ptr anAttrs = theFeature->data()->attributes( ModelAPI_AttributeRefAttr::typeId()); std::list::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end();