From 37206d029d9dfc191bd7f523ffc7440627516c29 Mon Sep 17 00:00:00 2001 From: azv Date: Fri, 27 Sep 2019 14:15:34 +0300 Subject: [PATCH] Refactoring: Split and Trim features of SketchPlugin. Move similar methods to SketchPlugin_SegmentationTools namespace. --- src/GeomAPI/GeomAPI_Curve.cpp | 20 + src/GeomAPI/GeomAPI_Curve.h | 4 + src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp | 13 +- src/SketchPlugin/SketchPlugin_Split.cpp | 532 +++---------------- src/SketchPlugin/SketchPlugin_Split.h | 68 +-- src/SketchPlugin/SketchPlugin_Tools.cpp | 320 +++++++++++ src/SketchPlugin/SketchPlugin_Tools.h | 75 +++ src/SketchPlugin/SketchPlugin_Trim.cpp | 309 ++--------- src/SketchPlugin/SketchPlugin_Trim.h | 51 +- src/SketchPlugin/SketchPlugin_Validators.cpp | 91 ++-- 10 files changed, 587 insertions(+), 896 deletions(-) diff --git a/src/GeomAPI/GeomAPI_Curve.cpp b/src/GeomAPI/GeomAPI_Curve.cpp index 46635b0a8..dd3c57c27 100644 --- a/src/GeomAPI/GeomAPI_Curve.cpp +++ b/src/GeomAPI/GeomAPI_Curve.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -102,6 +103,25 @@ GeomCurvePtr GeomAPI_Curve::basisCurve() const } // LCOV_EXCL_STOP + +const std::shared_ptr GeomAPI_Curve::project( + const std::shared_ptr& thePoint) const +{ + std::shared_ptr aResult; + if (MY_CURVE.IsNull()) + return aResult; + + const gp_Pnt& aPoint = thePoint->impl(); + + GeomAPI_ProjectPointOnCurve aProj(aPoint, MY_CURVE); + Standard_Integer aNbPoint = aProj.NbPoints(); + if (aNbPoint > 0) { + gp_Pnt aNearest = aProj.NearestPoint(); + aResult = GeomPointPtr(new GeomAPI_Pnt(aNearest.X(), aNearest.Y(), aNearest.Z())); + } + return aResult; +} + // ================================================================================================ bool GeomAPI_Curve::Comparator::operator()(const GeomCurvePtr& theCurve1, diff --git a/src/GeomAPI/GeomAPI_Curve.h b/src/GeomAPI/GeomAPI_Curve.h index 65ba0d5b7..5cdf1db89 100644 --- a/src/GeomAPI/GeomAPI_Curve.h +++ b/src/GeomAPI/GeomAPI_Curve.h @@ -82,6 +82,10 @@ class GeomAPI_Curve : public GeomAPI_Interface GEOMAPI_EXPORT std::shared_ptr getPoint(double theParam); + /// Project point on curve + GEOMAPI_EXPORT const std::shared_ptr project( + const std::shared_ptr& thePoint) const; + public: /// \brief Compare addresses of curves class Comparator diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp index 6eff0ea8b..61adc7cc2 100644 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp @@ -349,15 +349,8 @@ bool ModelGeomAlgo_Point2D::isPointOnEdge(const std::shared_ptr t { bool isInside = false; if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) { - std::shared_ptr anEdge(new GeomAPI_Edge(theBaseShape)); - if (anEdge->isLine()) { - std::shared_ptr aLine = anEdge->line(); - theProjectedPoint = aLine->project(thePoint); - } - else if (anEdge->isCircle() || anEdge->isArc()) { - std::shared_ptr aCircle = anEdge->circle(); - theProjectedPoint = aCircle->project(thePoint); - } + GeomCurvePtr aCurve(new GeomAPI_Curve(theBaseShape->edge())); + theProjectedPoint = aCurve->project(thePoint); if (theProjectedPoint.get()) { std::shared_ptr aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(), theProjectedPoint->y(), theProjectedPoint->z())); @@ -375,7 +368,7 @@ bool ModelGeomAlgo_Point2D::isInnerPointOnEdge(const std::shared_ptr anEdge(new GeomAPI_Edge(theBaseShape)); - if (!anEdge->isCircle()) { + if (!anEdge->isClosed()) { // check the point is not on the boundary GeomVertexPtr aVertex(new GeomAPI_Vertex(theProjectedPoint->x(), theProjectedPoint->y(), theProjectedPoint->z())); diff --git a/src/SketchPlugin/SketchPlugin_Split.cpp b/src/SketchPlugin/SketchPlugin_Split.cpp index ac6a15d6d..8a07349df 100644 --- a/src/SketchPlugin/SketchPlugin_Split.cpp +++ b/src/SketchPlugin/SketchPlugin_Split.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -50,11 +49,12 @@ #include #include #include +#include +#include #include #include #include #include -#include #include #include @@ -88,11 +88,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() @@ -102,26 +97,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())); @@ -142,7 +132,7 @@ 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; @@ -152,7 +142,8 @@ void SketchPlugin_Split::execute() std::map > aBaseRefAttributes; std::list aRefsToFeature; - getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature); + SketchPlugin_SegmentationTools::getRefAttributes( + aBaseFeature, aBaseRefAttributes, aRefsToFeature); std::map aBasePointModifiedAttributes; @@ -256,7 +247,7 @@ void SketchPlugin_Split::execute() aReplacingFeature = splitCircle(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); @@ -315,15 +306,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, aFeaturesToDelete); - updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes); + SketchPlugin_SegmentationTools::updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes); // delete constraints #ifdef DEBUG_SPLIT @@ -347,7 +338,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) { @@ -360,7 +351,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; @@ -387,7 +378,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); @@ -398,7 +389,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; @@ -440,10 +431,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 = @@ -466,7 +457,8 @@ std::string SketchPlugin_Split::processEvent(const std::shared_ptrflush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); - GeomShapePtr aSelectedShape = getSubShape(SELECTED_OBJECT(), SELECTED_POINT()); + GeomShapePtr aSelectedShape = SketchPlugin_SegmentationTools::getSubShape(this, + SELECTED_OBJECT(), SELECTED_POINT(), myCashedShapes, myCashedReferences); if (aSelectedShape.get()) { aFilledAttributeName = SELECTED_OBJECT(); } @@ -493,255 +485,11 @@ std::string SketchPlugin_Split::processEvent(const std::shared_ptr( - 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_SPLIT - std::cout << "SketchPlugin_Split::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); - - if (!aPoints.empty()) - 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; -} - -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 +499,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(); @@ -778,7 +524,7 @@ void SketchPlugin_Split::getConstraints(std::set& theFeaturesToDelet 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 +538,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,52 +571,6 @@ 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, @@ -884,7 +584,8 @@ 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()) @@ -931,7 +632,7 @@ void SketchPlugin_Split::updateCoincidenceConstraintsToFeature( } } 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 @@ -966,40 +667,6 @@ 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, @@ -1019,20 +686,17 @@ FeaturePtr SketchPlugin_Split::splitLine(FeaturePtr& theSplitFeature, 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; @@ -1053,7 +717,7 @@ FeaturePtr SketchPlugin_Split::splitLine(FeaturePtr& theSplitFeature, ModelGeomAlgo_Point2D::getPointAttributeInfo(anEndPointAttrOfBase) << std::endl; #endif - /// create a split feature + // create a split feature theSplitFeature = createLineFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); theCreatedFeatures.insert(theSplitFeature); @@ -1064,15 +728,15 @@ 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 } @@ -1109,7 +773,7 @@ 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 @@ -1132,14 +796,14 @@ FeaturePtr SketchPlugin_Split::splitLine(FeaturePtr& theSplitFeature, // additional constraints between split and base features aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), SketchPlugin_ConstraintParallel::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(theSplitFeature)); + aBaseFeature->lastResult(), + theSplitFeature->lastResult()); theCreatedFeatures.insert(aConstraintFeature); if (theAfterFeature.get()) { aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), SketchPlugin_ConstraintParallel::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(theAfterFeature)); + aBaseFeature->lastResult(), + theAfterFeature->lastResult()); theCreatedFeatures.insert(aConstraintFeature); } #endif @@ -1165,19 +829,16 @@ FeaturePtr SketchPlugin_Split::splitArc(FeaturePtr& theSplitFeature, 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_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; @@ -1197,7 +858,7 @@ FeaturePtr SketchPlugin_Split::splitArc(FeaturePtr& theSplitFeature, ModelGeomAlgo_Point2D::getPointAttributeInfo(anEndPointAttrOfBase) << std::endl; #endif - /// split feature + // split feature theSplitFeature = createArcFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); theCreatedFeatures.insert(theSplitFeature); @@ -1207,15 +868,15 @@ 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 } @@ -1252,7 +913,7 @@ 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 @@ -1275,24 +936,24 @@ FeaturePtr SketchPlugin_Split::splitArc(FeaturePtr& theSplitFeature, #ifdef CREATE_CONSTRAINTS aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), SketchPlugin_ConstraintEqual::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(theSplitFeature)); + aBaseFeature->lastResult(), + theSplitFeature->lastResult()); theCreatedFeatures.insert(aConstraintFeature); aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), SketchPlugin_ConstraintTangent::ID(), - getFeatureResult(theSplitFeature), - getFeatureResult(aBaseFeature)); + theSplitFeature->lastResult(), + aBaseFeature->lastResult()); theCreatedFeatures.insert(aConstraintFeature); if (theAfterFeature.get()) { aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), SketchPlugin_ConstraintEqual::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(theAfterFeature)); + aBaseFeature->lastResult(), + theAfterFeature->lastResult()); theCreatedFeatures.insert(aConstraintFeature); aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), SketchPlugin_ConstraintTangent::ID(), - getFeatureResult(theSplitFeature), - getFeatureResult(theAfterFeature)); + theSplitFeature->lastResult(), + theAfterFeature->lastResult()); theCreatedFeatures.insert(aConstraintFeature); } #endif @@ -1318,25 +979,21 @@ FeaturePtr SketchPlugin_Split::splitCircle(FeaturePtr& theSplitFeature, 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_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 + // split feature theSplitFeature = createArcFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); bool aSplitReversed = std::dynamic_pointer_cast(theSplitFeature)->isReversed(); theCreatedFeatures.insert(theSplitFeature); - /// base feature is a left part of the circle + // base feature is a left part of the circle theBaseFeatureModified = createArcFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit); anNewFeature = theBaseFeatureModified; @@ -1370,8 +1027,8 @@ FeaturePtr SketchPlugin_Split::splitCircle(FeaturePtr& theSplitFeature, #ifdef CREATE_CONSTRAINTS aConstraintFeature = SketchPlugin_Tools::createConstraint(sketch(), SketchPlugin_ConstraintTangent::ID(), - getFeatureResult(theSplitFeature), - getFeatureResult(theBaseFeatureModified)); + theSplitFeature->lastResult(), + theBaseFeatureModified->lastResult()); theCreatedFeatures.insert(aConstraintFeature); #endif return anNewFeature; @@ -1476,8 +1133,8 @@ FeaturePtr SketchPlugin_Split::createLineFeature(const FeaturePtr& theBaseFeatur } FeaturePtr SketchPlugin_Split::createArcFeature(const FeaturePtr& theBaseFeature, - const AttributePtr& theFirstPointAttr, - const AttributePtr& theSecondPointAttr) + const AttributePtr& theFirstPointAttr, + const AttributePtr& theSecondPointAttr) { FeaturePtr aFeature; SketchPlugin_Sketch* aSketch = sketch(); @@ -1507,7 +1164,7 @@ FeaturePtr SketchPlugin_Split::createArcFeature(const FeaturePtr& theBaseFeature 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 + // 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); @@ -1518,44 +1175,6 @@ FeaturePtr SketchPlugin_Split::createArcFeature(const FeaturePtr& theBaseFeature return aFeature; } -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) @@ -1571,6 +1190,10 @@ 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()) { } @@ -1583,7 +1206,8 @@ std::shared_ptr SketchPlugin_Split::getPointAttribute { 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; @@ -1602,7 +1226,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()); @@ -1619,17 +1243,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; } @@ -1654,13 +1278,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(); diff --git a/src/SketchPlugin/SketchPlugin_Split.h b/src/SketchPlugin/SketchPlugin_Split.h index 01d153e76..995b5800a 100644 --- a/src/SketchPlugin/SketchPlugin_Split.h +++ b/src/SketchPlugin/SketchPlugin_Split.h @@ -21,8 +21,9 @@ #define SketchPlugin_Split_H_ #include "SketchPlugin.h" +#include "SketchPlugin_Tools.h" -#include "GeomAPI_IPresentable.h" +#include #include #include @@ -37,13 +38,14 @@ typedef std::pair > IdToPointP * \ingroup Plugins * \brief Feature for creation of a new constraint splitting object. Entities for split: * - Linear segment by point(s) on this line - * - Arc by point(s) on this arc - * - Circle by at least 2 split-points on this circle + * - Circular/elliptic arc by point(s) on this arc + * - Circle/ellipse by at least 2 split-points on it * * The following constraints will be applied after split to keep the divided segments geometry: * - Coincident constraints for both parts of created segments in the point of splitting - * - For linear segments parallel, for circles - tangent constraint, for arc - tangent and equal - * constraints. In case of three segments in result two couple of constraints are created + * - For linear segments parallel, for circles/ellipses - tangent constraint, + * for arc - tangent and equal constraints. In case of three segments in result + * two couple of constraints are created * - parallel and equal constraints: the first is between 1st and middle entity, the second is * between 1st and 3rd. * - tangency constraints: the first between 1st and 2nd, the second between 2nd and 3rd. @@ -57,11 +59,6 @@ typedef std::pair > IdToPointP * start point of arc/line. * - Replication constraint used split feature will be deleted in the same way as it is deleted * by any of entity delete in sketch which is used in this constraint. - * - * This constraint has three attributes: - * SketchPlugin_Constraint::VALUE() contains reference object to be splitted - * SketchPlugin_Constraint::ENTITY_A() and SketchPlugin_Constraint::ENTITY_B() for the points of split; - * */ class SketchPlugin_Split : public SketchPlugin_Feature, public GeomAPI_IPresentable, public ModelAPI_IReentrant @@ -131,23 +128,6 @@ class SketchPlugin_Split : public SketchPlugin_Feature, public GeomAPI_IPresenta virtual std::string processEvent(const std::shared_ptr& theMessage); private: - /// Fulfill an internal container by shapes obtained from the parameter object - /// Shapes are result of split operation by points coincident to shape of the object - /// \param theObject a source object (will be splitted) - /// \param theSketch a sketch object - void fillObjectShapes(const ObjectPtr& theObject, const ObjectPtr& theSketch); - - GeomShapePtr getSubShape(const std::string& theObjectAttributeId, - const std::string& thePointAttributeId); - /// Returns geom point attribute of the feature bounds. It processes line or arc. - /// For circle feature, the result attributes are null - /// \param theFeature a source feature - /// \param theStartPointAttr an out attribute to start point - /// \param theStartPointAttr an out attribute to end point - void getFeaturePoints(const FeaturePtr& theFeature, - std::shared_ptr& theStartPointAttr, - std::shared_ptr& theEndPointAttr); - /// Obtains those constraints of the feature that should be modified. output maps contain /// point of coincidence and attribute id to be modified after split /// \param theFeaturesToDelete [out] constrains that will be deleted after split @@ -159,17 +139,6 @@ private: std::set>& theFeaturesToUpdate, std::map, IdToPointPair>& theCoincidenceToFeature); - /// Obtains references to feature point attributes and to feature, - /// e.g. for feature line: 1st container is - /// <1st line point, list > - /// <2nd line point, list<> > - /// for feature circle 2nd container is - /// \param theFeature an investigated feature - /// \param theRefs a container of list of referenced attributes - void getRefAttributes(const FeaturePtr& theFeature, - std::map >& theRefs, - std::list& theRefsToFeature); - /// Move coincidence constraint from feature to point if it is found /// \param theCoincidenceToFeature coincidence to feature to be connected to new feature /// \param theFurtherCoincidences a list of points where coincidences will be build @@ -191,14 +160,6 @@ private: void updateRefFeatureConstraints(const std::shared_ptr& theFeatureBaseResult, const std::list& theRefsToFeature); - /// Move constraints from attribute of base feature to attribute after modification - /// \param theBaseRefAttributes container of references to the attributes of base feature - /// \param theModifiedAttributes container of attributes placed instead of base attributes - /// at the same place - void updateRefAttConstraints( - const std::map >& theBaseRefAttributes, - const std::set >& theModifiedAttributes); - /// 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 @@ -291,16 +252,6 @@ private: const AttributePtr& theFirstPointAttr, const AttributePtr& theSecondPointAttr); - /// Add feature coincidence constraint between given attributes - /// \param theFeaturesToUpdate a constraint index - void updateFeaturesAfterSplit(const std::set& theFeaturesToUpdate); - - /// Result result of the feature to build constraint with. For arc, circle it is an edge result. - /// \param theFeature a feature - /// \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 @@ -320,11 +271,10 @@ private: const bool isUseAttributesInfo = true); #endif private: - typedef std::map, - std::shared_ptr > PntToAttributesMap; std::map, std::set > myCashedShapes; - std::map, PntToAttributesMap> myCashedReferences; + std::map, + GeomAlgoAPI_ShapeTools::PointToRefsMap> myCashedReferences; }; #endif diff --git a/src/SketchPlugin/SketchPlugin_Tools.cpp b/src/SketchPlugin/SketchPlugin_Tools.cpp index 472078f18..5aa9c1bf1 100644 --- a/src/SketchPlugin/SketchPlugin_Tools.cpp +++ b/src/SketchPlugin/SketchPlugin_Tools.cpp @@ -19,23 +19,35 @@ #include "SketchPlugin_Tools.h" +#include "SketchPlugin_Arc.h" #include "SketchPlugin_ConstraintCoincidence.h" #include "SketchPlugin_ConstraintCoincidenceInternal.h" #include "SketchPlugin_ConstraintLength.h" #include "SketchPlugin_ConstraintTangent.h" #include "SketchPlugin_Ellipse.h" +#include "SketchPlugin_EllipticArc.h" #include "SketchPlugin_Line.h" #include "SketchPlugin_Point.h" +#include "SketchPlugin_Projection.h" #include "SketchPlugin_SketchEntity.h" +#include "SketchPlugin_Split.h" +#include "SketchPlugin_Trim.h" #include #include +#include +#include + #include +#include #include #include +#include +#include + #include #include @@ -525,3 +537,311 @@ GeomPnt2dPtr flyoutPointCoordinates(const ConstraintPtr& theConstraint) } } // namespace SketchPlugin_Tools + + +// ================================================================================================= +// namespace SketchPlugin_SegmentationTools +// ================================================================================================= + +void SketchPlugin_SegmentationTools::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(); + } + else if (aFeatureKind == SketchPlugin_EllipticArc::ID()) { + aStartAttributeName = SketchPlugin_EllipticArc::START_POINT_ID(); + anEndAttributeName = SketchPlugin_EllipticArc::END_POINT_ID(); + } + if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) { + theStartPointAttr = std::dynamic_pointer_cast( + theFeature->attribute(aStartAttributeName)); + theEndPointAttr = std::dynamic_pointer_cast( + theFeature->attribute(anEndAttributeName)); + } +} + + +void SketchPlugin_SegmentationTools::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 = theFeature->lastResult()->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->isMacro() && // <- skip reference from Trim or Split feature + 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); + } + } + } +} + +GeomShapePtr SketchPlugin_SegmentationTools::getSubShape( + SketchPlugin_Feature* theFeature, + const std::string& theObjectAttributeId, + const std::string& thePointAttributeId, + std::map >& theCashedShapes, + std::map& theObjectToPoints) +{ + GeomShapePtr aBaseShape; + + AttributeReferencePtr anObjectAttr = theFeature->reference(theObjectAttributeId); + ObjectPtr aBaseObject = anObjectAttr->value(); + if (!aBaseObject.get()) + return aBaseShape; + + // point on feature + AttributePoint2DPtr aPointAttr = + std::dynamic_pointer_cast(theFeature->attribute(thePointAttributeId)); + std::shared_ptr anAttributePnt2d = aPointAttr->pnt(); + std::shared_ptr anAttributePnt = + theFeature->sketch()->to3D(anAttributePnt2d->x(), anAttributePnt2d->y()); + + if (theCashedShapes.find(aBaseObject) == theCashedShapes.end()) + fillObjectShapes(theFeature, aBaseObject, theCashedShapes, theObjectToPoints); + + std::shared_ptr aStartPoint; + std::shared_ptr aSecondPoint; + const std::set& aShapes = theCashedShapes[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 (theFeature->getKind() == SketchPlugin_Split::ID()) { + // for Split operation collect start and end points of the shape + if (aCurrentShape->shapeType() == GeomAPI_Shape::EDGE) { + std::shared_ptr anEdge(new GeomAPI_Edge(aCurrentShape)); + aStartPoint = anEdge->firstPoint(); + aSecondPoint = anEdge->lastPoint(); + } + } + else + aBaseShape = aCurrentShape; + break; + } + } + + if (!aStartPoint.get() || !aSecondPoint.get()) + return aBaseShape; + + FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObject); + if (anObjectAttr->isInitialized() && aBaseFeature.get() && aPointAttr->isInitialized()) { + ResultPtr aResult = aBaseFeature->lastResult(); + GeomShapePtr aResultShape = aResult->shape(); + std::list > aPoints; + + aPoints.push_back(aStartPoint); + aPoints.push_back(aSecondPoint); + + std::set > aSplitShapes; + GeomAlgoAPI_ShapeTools::splitShape_p(aResultShape, aPoints, aSplitShapes); + aBaseShape = GeomAlgoAPI_ShapeTools::findShape(aPoints, aSplitShapes); + } + return aBaseShape; +} + +void SketchPlugin_SegmentationTools::fillObjectShapes( + SketchPlugin_Feature* theOpFeature, + const ObjectPtr& theObject, + std::map >& theCashedShapes, + std::map& theObjectToPoints) +{ + SketchPlugin_Sketch* aSketch = theOpFeature->sketch(); + + GeomAlgoAPI_ShapeTools::PointToRefsMap aPoints; + std::set aShapes; + + std::set aRefAttributes; + // current feature + FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); + std::set anEdgeShapes; + // edges on feature + ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes); + if (!anEdgeShapes.empty()) { + GeomShapePtr aFeatureShape = (*anEdgeShapes.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 = aSketch->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()))); + + ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(), + aX->dir(), aY, aPoints); + + if (theOpFeature->getKind() == SketchPlugin_Trim::ID()) { + // collect all intersection points with other edges for Trim operation only + std::list aFeatures; + for (int i = 0; i < aSketch->numberOfSubs(); i++) { + FeaturePtr aFeature = aSketch->subFeature(i); + if (aFeature.get() && aFeature->getKind() != SketchPlugin_Projection::ID()) + aFeatures.push_back(aFeature); + } + ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPoints); + } + + if (!aPoints.empty()) + GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPoints, aShapes); + } + theObjectToPoints[theObject] = aPoints; + theCashedShapes[theObject] = aShapes; +} + +void SketchPlugin_SegmentationTools::updateRefAttConstraints( + const std::map >& theBaseRefAttributes, + const std::set >& theModifiedAttributes) +{ +#if defined DEBUG_SPLIT || defined DEBUG_TRIM + std::cout << "updateRefAttConstraints" << std::endl; +#endif + + std::set >::const_iterator + anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end(); + for (; anIt != aLast; anIt++) { + AttributePtr anAttribute = anIt->first; + AttributePtr aNewAttribute = anIt->second; + + // not found in references + if (!aNewAttribute.get() || + theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end()) + continue; + std::list aRefAttributes = theBaseRefAttributes.at(anAttribute); + std::list::const_iterator aRefIt = aRefAttributes.begin(), + aRLast = aRefAttributes.end(); + + 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 + } + } + } +} + +void SketchPlugin_SegmentationTools::updateFeaturesAfterOperation( + 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); + } + } + } +} + +AISObjectPtr SketchPlugin_SegmentationTools::getAISObject( + AISObjectPtr thePrevious, + SketchPlugin_Feature* theOpFeature, + const std::string& thePreviewObjectAttrName, + const std::string& thePreviewPointAttrName, + const std::string& theSelectedObjectAttrName, + const std::string& theSelectedPointAttrName) +{ +#if defined DEBUG_SPLIT || defined DEBUG_TRIM_METHODS + std::cout << "getAISObject: " << theOpFeature->data()->name() << std::endl; +#endif + + AISObjectPtr anAIS = thePrevious; + + std::list > aShapes; + std::map > aCashedShapes; + std::map aObjectToPoints; + GeomShapePtr aPreviewShape = getSubShape(theOpFeature, + thePreviewObjectAttrName, thePreviewPointAttrName, aCashedShapes, aObjectToPoints); + if (aPreviewShape.get()) + aShapes.push_back(aPreviewShape); + GeomShapePtr aSelectedShape = getSubShape(theOpFeature, + theSelectedObjectAttrName, theSelectedPointAttrName, aCashedShapes, aObjectToPoints); + 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; +} diff --git a/src/SketchPlugin/SketchPlugin_Tools.h b/src/SketchPlugin/SketchPlugin_Tools.h index 31162f91d..74193772e 100644 --- a/src/SketchPlugin/SketchPlugin_Tools.h +++ b/src/SketchPlugin/SketchPlugin_Tools.h @@ -25,7 +25,14 @@ #include #include #include +#include #include +#include + +#include +#include + +class GeomAPI_AISObject; class SketchPlugin_Constraint; class SketchPlugin_Feature; @@ -133,4 +140,72 @@ void convertRefAttrToPointOrTangentCurve(const AttributeRefAttrPtr& theRefA GeomPnt2dPtr flyoutPointCoordinates(const std::shared_ptr& theConstraint); }; // namespace SketchPlugin_Tools +namespace SketchPlugin_SegmentationTools +{ + /// Returns geom point attribute of the feature bounds. It processes line or arc. + /// For circle/ellipse feature, the result attributes are null + /// \param theFeature a source feature + /// \param theStartPointAttr an out attribute to start point + /// \param theEndPointAttr an out attribute to end point + void getFeaturePoints(const FeaturePtr& theFeature, + std::shared_ptr& theStartPointAttr, + std::shared_ptr& theEndPointAttr); + + /// Obtains references to feature point attributes and to feature, + /// e.g. for feature line: 1st container is + /// <1st line point, list > + /// <2nd line point, list<> > + /// for feature circle 2nd container is + /// \param theFeature an investigated feature + /// \param theRefs a container of list of referenced attributes + /// \param theRefsToFeature references to the feature result + void getRefAttributes(const FeaturePtr& theFeature, + std::map >& theRefs, + std::list& theRefsToFeature); + + /// Obtains a part of shape selected/highlighted in the viewer for Split/Trim operation + /// \param[in] theFeature Split/Trim feature + /// \param[in] theObjectAttributeId name of attribute containing selected object + /// \param[in] thePointAttributeId name of attribute containing point selected on the object + GeomShapePtr getSubShape( + SketchPlugin_Feature* theFeature, + const std::string& theObjectAttributeId, + const std::string& thePointAttributeId, + std::map >& theCashedShapes, + std::map& theObjectToPoints); + + /// Fulfill an internal containers by shapes obtained from the parameter object + /// Shapes are results of Split/Trim operation by points coincident to shape of the object + /// \param theOpFeture an operation feature (Split/Trim) + /// \param theObject a source object (will be splitted) + void fillObjectShapes( + SketchPlugin_Feature* theOpFeature, + const ObjectPtr& theObject, + std::map >& theCashedShapes, + std::map& theObjectToPoints); + + /// AIS object for selected/highlighted part of splitting/triming feature + /// \param[in] thePrevious previous presentation + /// \param[in] theOpFeture an operation feature (Split/Trim) + std::shared_ptr getAISObject(std::shared_ptr thePrevious, + SketchPlugin_Feature* theOpFeature, + const std::string& thePreviewObjectAttrName, + const std::string& thePreviewPointAttrName, + const std::string& theSelectedObjectAttrName, + const std::string& theSelectedPointAttrName); + + /// Move constraints from attribute of base feature to attribute after modification + /// \param theBaseRefAttributes container of references to the attributes of base feature + /// \param theModifiedAttributes container of attributes placed instead of base attributes + /// at the same place + void updateRefAttConstraints( + const std::map >& theBaseRefAttributes, + const std::set >& theModifiedAttributes); + + /// Updates line length if it exist in the list + /// \param theFeaturesToUpdate a constraint index + void updateFeaturesAfterOperation(const std::set& theFeaturesToUpdate); + +}; // namespace SketchPlugin_SegmentationTools + #endif // SKETCHPLUGIN_TOOLS_H_ \ No newline at end of file diff --git a/src/SketchPlugin/SketchPlugin_Trim.cpp b/src/SketchPlugin/SketchPlugin_Trim.cpp index 66d7157c1..0be8a5a5f 100644 --- a/src/SketchPlugin/SketchPlugin_Trim.cpp +++ b/src/SketchPlugin/SketchPlugin_Trim.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -52,8 +51,6 @@ #include #include #include -#include -#include #include @@ -115,8 +112,10 @@ void SketchPlugin_Trim::findShapePoints(const std::string& theObjectAttributeId, std::shared_ptr anAttributePnt = sketch()->to3D(anAttributePnt2d->x(), anAttributePnt2d->y()); - if (myCashedShapes.find(aBaseObject) == myCashedShapes.end()) - fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints); + if (myCashedShapes.find(aBaseObject) == myCashedShapes.end()) { + SketchPlugin_SegmentationTools::fillObjectShapes( + this, aBaseObject, myCashedShapes, myObjectToPoints); + } const std::set& aShapes = myCashedShapes[aBaseObject]; if (!aShapes.empty()) { @@ -163,12 +162,14 @@ std::shared_ptr SketchPlugin_Trim::convertPoint( AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT())); ObjectPtr aBaseObject = aBaseObjectAttr->value(); - if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end()) - fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints); + if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end()) { + SketchPlugin_SegmentationTools::fillObjectShapes( + this, aBaseObject, myCashedShapes, myObjectToPoints); + } bool aFound = false; - const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject); - for (PointToRefsMap::const_iterator aPointIt = aRefsMap.begin(); + const GeomAlgoAPI_ShapeTools::PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject); + for (GeomAlgoAPI_ShapeTools::PointToRefsMap::const_iterator aPointIt = aRefsMap.begin(); aPointIt != aRefsMap.end() && !aFound; aPointIt++) { if (aPointIt->first->isEqual(thePoint)) { const std::pair, @@ -252,7 +253,8 @@ void SketchPlugin_Trim::execute() // find references(attributes and features) to the base feature std::map > aBaseRefAttributes; std::list aRefsToFeature; - getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature); + SketchPlugin_SegmentationTools::getRefAttributes( + aBaseFeature, aBaseRefAttributes, aRefsToFeature); #ifdef DEBUG_TRIM std::cout << "---- getRefAttributes ----" << std::endl; std::map >::const_iterator @@ -324,11 +326,13 @@ void SketchPlugin_Trim::execute() restoreCurrentFeature(); // constraints to end points of trim feature - if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end()) - fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints); + if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end()) { + SketchPlugin_SegmentationTools::fillObjectShapes( + this, aBaseObject, myCashedShapes, myObjectToPoints); + } // create coincidence to objects, intersected the base object - const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject); + const GeomAlgoAPI_ShapeTools::PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject); for (std::set::const_iterator anIt = aFurtherCoincidences.begin(), aLast = aFurtherCoincidences.end(); anIt != aLast; anIt++) { @@ -356,8 +360,8 @@ void SketchPlugin_Trim::execute() continue; std::pair, std::list > anInfo; - for (PointToRefsMap::const_iterator aRefIt = aRefsMap.begin(); aRefIt != aRefsMap.end(); - aRefIt++) + for (GeomAlgoAPI_ShapeTools::PointToRefsMap::const_iterator aRefIt = aRefsMap.begin(); + aRefIt != aRefsMap.end(); aRefIt++) { if (aRefIt->first->isEqual(aPoint)) { anInfo = aRefIt->second; @@ -406,7 +410,7 @@ void SketchPlugin_Trim::execute() } } - updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete); + SketchPlugin_SegmentationTools::updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes); // Wait all constraints being created, then send update events static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); @@ -429,7 +433,7 @@ void SketchPlugin_Trim::execute() ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete); Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); - updateFeaturesAfterTrim(aFeaturesToUpdate); + SketchPlugin_SegmentationTools::updateFeaturesAfterOperation(aFeaturesToUpdate); // Send events to update the sub-features by the solver. if(isUpdateFlushed) { @@ -501,8 +505,10 @@ std::string SketchPlugin_Trim::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()) { + SketchPlugin_SegmentationTools::fillObjectShapes( + this, anObject, myCashedShapes, myObjectToPoints); + } const std::set& aShapes = myCashedShapes[anObject]; if (aShapes.size() > 1) { std::shared_ptr aRefSelectedAttr = @@ -525,7 +531,8 @@ std::string SketchPlugin_Trim::processEvent(const std::shared_ptrflush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); - GeomShapePtr aSelectedShape = getSubShape(SELECTED_OBJECT(), SELECTED_POINT()); + GeomShapePtr aSelectedShape = SketchPlugin_SegmentationTools::getSubShape(this, + SELECTED_OBJECT(), SELECTED_POINT(), myCashedShapes, myObjectToPoints); #ifdef DEBUG_TRIM_METHODS if (!aSelectedShape.get()) std::cout << "Set empty selected object" << std::endl; @@ -593,7 +600,7 @@ bool SketchPlugin_Trim::moveTangency(const AttributePtr& theAttribute, // get shape of the feature of the attribute FeaturePtr anAttributeFeature = ModelAPI_Feature::feature(aRefAttr->object()); anAttributeFeature->execute(); // the modified value should be applyed to recompute shape - PointToRefsMap aPointToAttributeOrObject; + GeomAlgoAPI_ShapeTools::PointToRefsMap aPointToAttributeOrObject; std::list aFeatures; aFeatures.push_back(anAttributeFeature); ModelGeomAlgo_Point2D::getPointsIntersectedShape(aTangentFeature, aFeatures, @@ -623,102 +630,8 @@ bool SketchPlugin_Trim::moveTangency(const AttributePtr& theAttribute, AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious) { -#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; -} - -GeomShapePtr SketchPlugin_Trim::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()); - - 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; - } - } - return aBaseShape; -} - -void SketchPlugin_Trim::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)); - } + return SketchPlugin_SegmentationTools::getAISObject(thePrevious, + this, PREVIEW_OBJECT(), PREVIEW_POINT(), SELECTED_OBJECT(), SELECTED_POINT()); } void SketchPlugin_Trim::getConstraints(std::set& theFeaturesToDelete, @@ -755,86 +668,6 @@ void SketchPlugin_Trim::getConstraints(std::set& theFeaturesToDelete } } -void SketchPlugin_Trim::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_Trim::updateRefAttConstraints( - const std::map >& theBaseRefAttributes, - const std::set >& theModifiedAttributes, - std::set& theFeaturesToDelete) -{ -#ifdef DEBUG_TRIM - std::cout << "SketchPlugin_Trim::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; - if (aNewAttribute.get()) { - for (; aRefIt != aRLast; aRefIt++) { - AttributeRefAttrPtr aRefAttr = - std::dynamic_pointer_cast(*aRefIt); - if (aRefAttr.get()) { - aRefAttr->setAttr(aNewAttribute); - } - } - } - } -} - void SketchPlugin_Trim::removeReferencesToAttribute(const AttributePtr& theAttribute, std::map >& theBaseRefAttributes) { @@ -870,27 +703,6 @@ void SketchPlugin_Trim::removeReferencesToAttribute(const AttributePtr& theAttri Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); } -void SketchPlugin_Trim::updateFeaturesAfterTrim(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); - } - } - } -} - FeaturePtr SketchPlugin_Trim::trimLine(const std::shared_ptr& theStartShapePoint, const std::shared_ptr& theLastShapePoint, std::map >& theBaseRefAttributes, @@ -907,7 +719,8 @@ FeaturePtr SketchPlugin_Trim::trimLine(const std::shared_ptr& the /// points of trim AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase; - getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); + SketchPlugin_SegmentationTools::getFeaturePoints( + aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); std::shared_ptr aStartFeaturePoint = aStartPointAttrOfBase->pnt(); std::shared_ptr aLastFeaturePoint = anEndPointAttrOfBase->pnt(); @@ -997,7 +810,8 @@ FeaturePtr SketchPlugin_Trim::trimArc(const std::shared_ptr& theS /// points of trim AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase; - getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); + SketchPlugin_SegmentationTools::getFeaturePoints( + aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); std::shared_ptr aStartArcPoint = aStartPointAttrOfBase->pnt(); std::shared_ptr aLastArcPoint = anEndPointAttrOfBase->pnt(); @@ -1305,58 +1119,3 @@ std::shared_ptr SketchPlugin_Trim::getFeatureResult( return aResult; } - -//******************************************************************** -void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject, - const ObjectPtr& theSketch, - std::map >& theCashedShapes, - std::map& theObjectToPoints) -{ - PointToRefsMap aPointsInfo; - - std::set > aShapes; - std::map, - std::list< AttributePoint2DPtr > > aPointToAttributes; - std::map, - std::list< ObjectPtr > > aPointToObjects; - - std::set aRefAttributes; - // current feature - FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); - std::set anEdgeShapes; - // edges on feature - ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes); - if (!anEdgeShapes.empty()) { - GeomShapePtr aFeatureShape = (*anEdgeShapes.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()))); - - ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(), - aX->dir(), aY, aPointsInfo); - - std::list aFeatures; - CompositeFeaturePtr aSketchComposite = - std::dynamic_pointer_cast(theSketch); - for (int i = 0; i < aSketchComposite->numberOfSubs(); i++) { - FeaturePtr aFeature = aSketchComposite->subFeature(i); - if (aFeature.get() && aFeature->getKind() != SketchPlugin_Projection::ID()) - aFeatures.push_back(aFeature); - } - ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPointsInfo); - - GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPointsInfo, aShapes); - } - theObjectToPoints[theObject] = aPointsInfo; - theCashedShapes[theObject] = aShapes; -} diff --git a/src/SketchPlugin/SketchPlugin_Trim.h b/src/SketchPlugin/SketchPlugin_Trim.h index 90bbf7434..91b9405d8 100644 --- a/src/SketchPlugin/SketchPlugin_Trim.h +++ b/src/SketchPlugin/SketchPlugin_Trim.h @@ -21,8 +21,9 @@ #define SketchPlugin_Trim_H_ #include "SketchPlugin.h" +#include -#include "GeomAPI_IPresentable.h" +#include #include #include @@ -105,15 +106,6 @@ class SketchPlugin_Trim : public SketchPlugin_Feature, public GeomAPI_IPresentab /// Apply information of the message to current object. It fills selected point and object virtual std::string processEvent(const std::shared_ptr& theMessage); - typedef std::map, - std::pair >, - std::list > > > PointToRefsMap; - - static void fillObjectShapes(const std::shared_ptr& theObject, - const std::shared_ptr& theSketch, - std::map, std::set >& theCashedShapes, - std::map, PointToRefsMap>& theObjectToPoints); - private: bool setCoincidenceToAttribute(const AttributePtr& theAttribute, const std::set >& theFurtherCoincidences, @@ -123,18 +115,6 @@ private: /// \param theFeature a feature that can be set into the attribute bool moveTangency(const AttributePtr& theAttribute, const FeaturePtr& theFeature); - GeomShapePtr getSubShape(const std::string& theObjectAttributeId, - const std::string& thePointAttributeId); - - /// Returns geom point attribute of the feature bounds. It processes line or arc. - /// For circle feature, the result attributes are null - /// \param theFeature a source feature - /// \param theStartPointAttr an out attribute to start point - /// \param theStartPointAttr an out attribute to end point - void getFeaturePoints(const FeaturePtr& theFeature, - std::shared_ptr& theStartPointAttr, - std::shared_ptr& theEndPointAttr); - /// Obtains those constraints of the feature that should be modified. output maps contain /// point of coincidence and attribute id to be modified after split /// \param theFeaturesToDelete [out] constrains that will be deleted after split @@ -142,36 +122,12 @@ private: void getConstraints(std::set>& theFeaturesToDelete, std::set& theFeaturesToUpdate); - /// Obtains references to feature point attributes and to feature, - /// e.g. for feature line: 1st container is - /// <1st line point, list > - /// <2nd line point, list<> > - /// for feature circle 2nd container is - /// \param theFeature an investigated feature - /// \param theRefs a container of list of referenced attributes - void getRefAttributes(const FeaturePtr& theFeature, - std::map >& theRefs, - std::list& theRefsToFeature); - - /// Move constraints from attribute of base feature to attribute after modification - /// \param theBaseRefAttributes container of references to the attributes of base feature - /// \param theModifiedAttributes container of attributes placed instead of base attributes - /// at the same place - void updateRefAttConstraints( - const std::map >& theBaseRefAttributes, - const std::set >& theModifiedAttributes, - std::set>& theFeaturesToDelete); - /// Remove references constraints from attribute of base feature refer to the given attribute /// \param theAttribute an attribute /// \param theModifiedAttributes modifiable container of attributes void removeReferencesToAttribute(const AttributePtr& theAttribute, std::map >& theBaseRefAttributes); - /// Updates line length if it exist in the list - /// \param theFeaturesToUpdate a constraints container - void updateFeaturesAfterTrim(const std::set& theFeaturesToUpdate); - /// Make the base object is splitted by the point attributes /// \param theBaseRefAttributes container of references to the attributes of base feature /// \param thePoints a list of points where coincidences will be build @@ -270,7 +226,8 @@ private: private: std::map, std::set > myCashedShapes; - std::map, PointToRefsMap> myObjectToPoints; + std::map, + GeomAlgoAPI_ShapeTools::PointToRefsMap> myObjectToPoints; }; #endif diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index b8c9de51f..0ee6f65f3 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -951,49 +951,44 @@ bool SketchPlugin_SplitValidator::isValid(const AttributePtr& theAttribute, if (!anAttrFeature) return aValid; - std::string aKind = anAttrFeature->getKind(); - if (aKind == SketchPlugin_Line::ID() || - aKind == SketchPlugin_Arc::ID() || - aKind == SketchPlugin_Circle::ID()) { - - std::set anEdgeShapes; - ModelGeomAlgo_Shape::shapesOfType(anAttrFeature, GeomAPI_Shape::EDGE, anEdgeShapes); - if (anEdgeShapes.empty() || anEdgeShapes.size() > 1 /*there case has not existed yet*/) - return aValid; - - // coincidences to the feature - std::set > aRefAttributes; - ModelGeomAlgo_Point2D::getPointsOfReference(anAttrFeature, - SketchPlugin_ConstraintCoincidence::ID(), - aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID()); - - GeomShapePtr anAttrShape = (*anEdgeShapes.begin())->shape(); - std::shared_ptr aSFeature = - std::dynamic_pointer_cast(anAttrFeature); - SketchPlugin_Sketch* aSketch = aSFeature->sketch(); - - std::shared_ptr aData = aSketch->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 aDirY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir()))); - - typedef std::map, - std::pair >, - std::list > > > PointToRefsMap; - PointToRefsMap aPointsInfo; - - ModelGeomAlgo_Point2D::getPointsInsideShape(anAttrShape, aRefAttributes, aC->pnt(), - aX->dir(), aDirY, aPointsInfo); - int aCoincidentToFeature = (int)aPointsInfo.size(); - if (aKind == SketchPlugin_Circle::ID()) - aValid = aCoincidentToFeature >= 2; - else - aValid = aCoincidentToFeature >= 1; - } + std::set anEdgeShapes; + ModelGeomAlgo_Shape::shapesOfType(anAttrFeature, GeomAPI_Shape::EDGE, anEdgeShapes); + if (anEdgeShapes.empty() || anEdgeShapes.size() > 1 /*there case has not existed yet*/) + return aValid; + + // coincidences to the feature + std::set > aRefAttributes; + ModelGeomAlgo_Point2D::getPointsOfReference(anAttrFeature, + SketchPlugin_ConstraintCoincidence::ID(), + aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID()); + + GeomShapePtr anAttrShape = (*anEdgeShapes.begin())->shape(); + std::shared_ptr aSFeature = + std::dynamic_pointer_cast(anAttrFeature); + SketchPlugin_Sketch* aSketch = aSFeature->sketch(); + + std::shared_ptr aData = aSketch->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 aDirY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir()))); + + typedef std::map, + std::pair >, + std::list > > > PointToRefsMap; + PointToRefsMap aPointsInfo; + + ModelGeomAlgo_Point2D::getPointsInsideShape(anAttrShape, aRefAttributes, aC->pnt(), + aX->dir(), aDirY, aPointsInfo); + int aCoincidentToFeature = (int)aPointsInfo.size(); + if (anAttrFeature->getKind() == SketchPlugin_Circle::ID() || + anAttrFeature->getKind() == SketchPlugin_Ellipse::ID()) + aValid = aCoincidentToFeature >= 2; + else + aValid = aCoincidentToFeature >= 1; return aValid; } @@ -1031,12 +1026,6 @@ bool SketchPlugin_TrimValidator::isValid(const AttributePtr& theAttribute, if (!aSketchFeature.get() || aSketchFeature->isCopy()) return aValid; - std::string aKind = aBaseFeature->getKind(); - if (aKind != SketchPlugin_Line::ID() && - aKind != SketchPlugin_Arc::ID() && - aKind != SketchPlugin_Circle::ID()) - return aValid; - // point on feature AttributePoint2DPtr aPoint = std::dynamic_pointer_cast( aTrimFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_POINT())); @@ -1051,8 +1040,8 @@ bool SketchPlugin_TrimValidator::isValid(const AttributePtr& theAttribute, std::map, std::pair >, std::list > > > > anObjectToPoints; - SketchPlugin_Trim::fillObjectShapes(aBaseObject, aSketch->data()->owner(), - aCashedShapes, anObjectToPoints); + SketchPlugin_SegmentationTools::fillObjectShapes( + aTrimFeature.get(), aBaseObject, aCashedShapes, anObjectToPoints); const std::set& aShapes = aCashedShapes[aBaseObject]; return aShapes.size() > 1; -- 2.39.2