X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_Trim.cpp;h=aca80577bee77257e880d75981a9536a60b3d3d1;hb=06e7f5859095193fc7f498bd89a7d28009794f53;hp=aedc763322e4c4969e9a362fe366714debcf09d9;hpb=a9e2e7942b9c78aba4e0b6d883b213045a8a10ea;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Trim.cpp b/src/SketchPlugin/SketchPlugin_Trim.cpp index aedc76332..aca80577b 100644 --- a/src/SketchPlugin/SketchPlugin_Trim.cpp +++ b/src/SketchPlugin/SketchPlugin_Trim.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2023 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -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_Trim.h" @@ -26,7 +25,6 @@ #include #include #include -#include #include #include @@ -45,16 +43,16 @@ #include #include #include -//#include #include #include #include #include +#include +#include #include #include #include #include -#include #include @@ -68,9 +66,6 @@ #include -//#define DEBUG_TRIM_METHODS -//#define DEBUG_TRIM - #ifdef DEBUG_TRIM #include #endif @@ -81,9 +76,6 @@ static const double PI = 3.141592653589793238463; -static const std::string OPERATION_HIGHLIGHT_COLOR() { return "128, 0, 0"; } -static const std::string OPERATION_REMOVE_FEATURE_COLOR() { return "255, 174, 201"; } - SketchPlugin_Trim::SketchPlugin_Trim() { } @@ -119,8 +111,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()) { @@ -167,12 +161,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, @@ -243,6 +239,10 @@ void SketchPlugin_Trim::execute() std::cout << " Base Feature: " << aBaseFeature->data()->name() << std::endl; #endif findShapePoints(SELECTED_OBJECT(), SELECTED_POINT(), aStartShapePoint, aLastShapePoint); + if (!aStartShapePoint || !aLastShapePoint) { + setError("Error: Selected point is not placed on any edge"); + return; + } std::shared_ptr aStartShapePoint2d = convertPoint(aStartShapePoint); std::shared_ptr aLastShapePoint2d = convertPoint(aLastShapePoint); @@ -252,7 +252,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 @@ -295,12 +296,16 @@ void SketchPlugin_Trim::execute() std::cout << "[" << aRefsToFeature.size() << "] " << aRefsInfo << std::endl; std::cout << "---- getRefAttributes:end ----" << std::endl; #endif + + keepCurrentFeature(); + std::set aFurtherCoincidences; std::set> aModifiedAttributes; const std::string& aKind = aBaseFeature->getKind(); FeaturePtr aReplacingFeature, aNewFeature; - if (aKind == SketchPlugin_Circle::ID()) { - aReplacingFeature = trimCircle(aStartShapePoint2d, aLastShapePoint2d, + if (aKind == SketchPlugin_Circle::ID() || + aKind == SketchPlugin_Ellipse::ID()) { + aReplacingFeature = trimClosed(aStartShapePoint2d, aLastShapePoint2d, aFurtherCoincidences, aModifiedAttributes); aFeaturesToDelete.insert(aBaseFeature); @@ -317,13 +322,21 @@ void SketchPlugin_Trim::execute() aNewFeature = trimArc(aStartShapePoint2d, aLastShapePoint2d, aBaseRefAttributes, aFurtherCoincidences, aModifiedAttributes); } + else if (aKind == SketchPlugin_EllipticArc::ID()) { + aNewFeature = trimEllipticArc(aStartShapePoint2d, aLastShapePoint2d, aBaseRefAttributes, + aFurtherCoincidences, aModifiedAttributes); + } + + 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++) { @@ -341,29 +354,42 @@ void SketchPlugin_Trim::execute() << "]" << std::endl; #endif - std::shared_ptr aPoint; + std::shared_ptr aExtrPoint; if (aStartShapePoint2d.get() && aPoint2d->isEqual(aStartShapePoint2d)) - aPoint = aStartShapePoint; + aExtrPoint = aStartShapePoint; else if (aLastShapePoint2d.get() && aPoint2d->isEqual(aLastShapePoint2d)) - aPoint = aLastShapePoint; + aExtrPoint = aLastShapePoint; - if (!aPoint.get()) + if (!aExtrPoint.get()) 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)) { + if (aRefIt->first->isEqual(aExtrPoint)) { anInfo = aRefIt->second; - break; + // prefer a segment instead of a point, because further coincidence with a segment + // decreases only 1 DoF (instead of 2 for point) and prevents an overconstraint situation. + bool isEdge = false; + for (std::list::const_iterator anInfoIt = anInfo.second.begin(); + anInfoIt != anInfo.second.end() && !isEdge; ++anInfoIt) { + ResultPtr aResult = std::dynamic_pointer_cast(*anInfoIt); + if (aResult) { + GeomShapePtr aShape = aResult->shape(); + isEdge = aShape && aShape->isEdge(); + } + } + if (isEdge) + break; } } const std::list& anObjects = anInfo.second; for (std::list::const_iterator anObjectIt = anObjects.begin(); anObjectIt != anObjects.end(); anObjectIt++) { - createConstraintToObject(SketchPlugin_ConstraintCoincidence::ID(), aPointAttribute, - *anObjectIt); + SketchPlugin_Tools::createConstraintAttrObject(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), + aPointAttribute, *anObjectIt); } } @@ -372,14 +398,14 @@ void SketchPlugin_Trim::execute() ResultPtr aReplacingResult; if (aReplacingFeature.get()) { aReplacingFeature->execute(); // need it to obtain result - aReplacingResult = getFeatureResult(aReplacingFeature); + aReplacingResult = aReplacingFeature->lastResult(); } for(std::list::const_iterator anIt = aRefsToFeature.begin(), aLast = aRefsToFeature.end(); anIt != aLast; anIt++) { AttributePtr anAttribute = *anIt; - if (setCoincidenceToAttribute(anAttribute, aFurtherCoincidences)) + if (setCoincidenceToAttribute(anAttribute, aFurtherCoincidences, aFeaturesToDelete)) continue; // move tangency constraint to the nearest feature if possible @@ -400,7 +426,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); @@ -423,7 +449,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) { @@ -447,7 +473,7 @@ void SketchPlugin_Trim::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); @@ -458,7 +484,7 @@ void SketchPlugin_Trim::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; @@ -480,6 +506,7 @@ void SketchPlugin_Trim::execute() #endif } +// LCOV_EXCL_START std::string SketchPlugin_Trim::processEvent(const std::shared_ptr& theMessage) { #ifdef DEBUG_TRIM_METHODS @@ -494,8 +521,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 = @@ -518,7 +547,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; @@ -531,9 +561,11 @@ std::string SketchPlugin_Trim::processEvent(const std::shared_ptr& theFurtherCoincidences) + const std::set& theFurtherCoincidences, + std::set>& theFeaturesToDelete) { FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner()); if (aFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID()) @@ -551,12 +583,11 @@ bool SketchPlugin_Trim::setCoincidenceToAttribute(const AttributePtr& theAttribu AttributePoint2DPtr aPointAttribute = (*anIt); std::shared_ptr aPoint2d = aPointAttribute->pnt(); if (aPoint2d->isEqual(aRefPnt2d)) { - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( - theAttribute); - if (aRefAttr.get()) { - aRefAttr->setAttr(aPointAttribute); - aFoundPoint = true; - } + // create new coincidence and then remove the old one + SketchPlugin_Tools::createConstraintAttrAttr(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), + aRefPointAttr, aPointAttribute); + theFeaturesToDelete.insert(aFeature); } } return aFoundPoint; @@ -585,7 +616,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, @@ -615,102 +646,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, @@ -722,7 +659,7 @@ void SketchPlugin_Trim::getConstraints(std::set& theFeaturesToDelete AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Trim::SELECTED_OBJECT())); 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(); @@ -747,86 +684,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) { @@ -862,27 +719,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, @@ -899,7 +735,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(); @@ -950,7 +787,8 @@ FeaturePtr SketchPlugin_Trim::trimLine(const std::shared_ptr& the // result is two lines: start line point - start shape point, // last shape point - last line point // create second line - anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint); + anNewFeature = SketchPlugin_SegmentationTools::createLineFeature( + aBaseFeature, aLastShapePoint, aLastFeaturePoint); thePoints.insert(std::dynamic_pointer_cast (anNewFeature->attribute(SketchPlugin_Line::START_ID()))); @@ -966,10 +804,10 @@ FeaturePtr SketchPlugin_Trim::trimLine(const std::shared_ptr& the (aBaseFeature->attribute(aModifiedAttribute))); // Collinear constraint for lines - createConstraintForObjects(SketchPlugin_ConstraintCollinear::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(anNewFeature)); - + SketchPlugin_Tools::createConstraintObjectObject(sketch(), + SketchPlugin_ConstraintCollinear::ID(), + aBaseFeature->lastResult(), + anNewFeature->lastResult()); } return anNewFeature; } @@ -989,7 +827,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(); @@ -1035,7 +874,8 @@ FeaturePtr SketchPlugin_Trim::trimArc(const std::shared_ptr& theS else { // result is two arcs: start arc point - start shape point, last shape point - last arc point // create second arc - anNewFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint); + anNewFeature = SketchPlugin_SegmentationTools::createArcFeature( + aBaseFeature, aLastShapePoint, aLastArcPoint); thePoints.insert(std::dynamic_pointer_cast (anNewFeature->attribute(SketchPlugin_Arc::START_ID()))); @@ -1051,13 +891,15 @@ FeaturePtr SketchPlugin_Trim::trimArc(const std::shared_ptr& theS (aBaseFeature->attribute(aModifiedAttribute))); // equal Radius constraint for arcs - createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), - getFeatureResult(aBaseFeature), - getFeatureResult(anNewFeature)); + SketchPlugin_Tools::createConstraintObjectObject(sketch(), + SketchPlugin_ConstraintEqual::ID(), + aBaseFeature->lastResult(), + anNewFeature->lastResult()); // coincident centers constraint - createConstraint(SketchPlugin_ConstraintCoincidence::ID(), - aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()), - anNewFeature->attribute(SketchPlugin_Arc::CENTER_ID())); + SketchPlugin_Tools::createConstraintAttrAttr(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), + aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()), + anNewFeature->attribute(SketchPlugin_Arc::CENTER_ID())); #ifdef DEBUG_TRIM std::cout << "Created arc on points:" << std::endl; @@ -1068,40 +910,183 @@ FeaturePtr SketchPlugin_Trim::trimArc(const std::shared_ptr& theS return anNewFeature; } -FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr& theStartShapePoint, - const std::shared_ptr& theLastShapePoint, - std::set& thePoints, +FeaturePtr SketchPlugin_Trim::trimEllipticArc( + const std::shared_ptr& theStartShapePoint, + const std::shared_ptr& theLastShapePoint, + std::map >& theBaseRefAttributes, + std::set& thePoints, std::set>& theModifiedAttributes) { + FeaturePtr anNewFeature; // Check the base objects are initialized. - AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT())); + AttributeReferencePtr aBaseObjectAttr = reference(SELECTED_OBJECT()); ObjectPtr aBaseObject = aBaseObjectAttr->value(); FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); - /// points of trim - //AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase; - //getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); + // points of trim + AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase; + SketchPlugin_SegmentationTools::getFeaturePoints( + aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); + + std::shared_ptr aStartArcPoint = aStartPointAttrOfBase->pnt(); + std::shared_ptr aLastArcPoint = anEndPointAttrOfBase->pnt(); - /// trim feature - FeaturePtr anNewFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint); + std::shared_ptr aStartShapePoint = theStartShapePoint; + std::shared_ptr aLastShapePoint = theLastShapePoint; + arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase, + aStartShapePoint, aLastShapePoint); +#ifdef DEBUG_TRIM + std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl; + if (aStartShapePoint.get()) + std::cout << "Start shape point: [" << aStartShapePoint->x() << ", " << + aStartShapePoint->y() << "]" << std::endl; + std::cout << "Start arc attribute point: [" << aStartArcPoint->x() << ", " << + aStartArcPoint->y() << "]" << std::endl; + if (aLastShapePoint.get()) + std::cout << "Last shape point: [" << aLastShapePoint->x() << ", " << + aLastShapePoint->y() << "]" << std::endl; + std::cout << "Last arc attribute point: [" << aLastArcPoint->x() << ", " << + aLastArcPoint->y() << "]" << std::endl; +#endif + + bool isStartPoint = !aStartShapePoint.get() || aStartArcPoint->isEqual(aStartShapePoint); + bool isLastPoint = !aLastShapePoint.get() || aLastArcPoint->isEqual(aLastShapePoint); + if (isStartPoint || isLastPoint) { + // result is one arc: changed existing arc + std::string aModifiedAttribute = isStartPoint ? SketchPlugin_EllipticArc::START_POINT_ID() + : SketchPlugin_EllipticArc::END_POINT_ID(); + std::shared_ptr aPoint; + if (aStartShapePoint.get() && aLastShapePoint.get()) + aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint; + else + aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint; + + removeReferencesToAttribute(aBaseFeature->attribute(aModifiedAttribute), + theBaseRefAttributes); + + fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint); + + thePoints.insert(std::dynamic_pointer_cast + (aBaseFeature->attribute(aModifiedAttribute))); + } + else { + // result is two arcs: start arc point - start shape point, last shape point - last arc point + // create second arc + anNewFeature = SketchPlugin_SegmentationTools::createArcFeature( + aBaseFeature, aLastShapePoint, aLastArcPoint); + thePoints.insert(std::dynamic_pointer_cast( + anNewFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID()))); + + std::string aModifiedAttribute = SketchPlugin_EllipticArc::END_POINT_ID(); + theModifiedAttributes.insert( + std::make_pair(aBaseFeature->attribute(aModifiedAttribute), + anNewFeature->attribute(SketchPlugin_EllipticArc::END_POINT_ID()))); + + // modify base arc + fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint); + + thePoints.insert(std::dynamic_pointer_cast + (aBaseFeature->attribute(aModifiedAttribute))); + + // make elliptic arcs equal + SketchPlugin_Tools::createConstraintObjectObject(sketch(), + SketchPlugin_ConstraintEqual::ID(), + aBaseFeature->lastResult(), + anNewFeature->lastResult()); + // coincident centers constraint + SketchPlugin_Tools::createConstraintAttrAttr(sketch(), + SketchPlugin_ConstraintCoincidence::ID(), + aBaseFeature->attribute(SketchPlugin_EllipticArc::CENTER_ID()), + anNewFeature->attribute(SketchPlugin_EllipticArc::CENTER_ID())); + +#ifdef DEBUG_TRIM + std::cout << "Created arc on points:" << std::endl; + std::cout << "Start shape point: [" << aStartShapePoint->x() << ", " << + aStartShapePoint->y() << "]" << std::endl; +#endif + } + return anNewFeature; +} + +FeaturePtr SketchPlugin_Trim::trimClosed(const std::shared_ptr& theStartShapePoint, + const std::shared_ptr& theLastShapePoint, + std::set& thePoints, + std::set>& theModifiedAttributes) +{ + // Check the base objects are initialized. + AttributeReferencePtr aBaseObjectAttr = reference(SELECTED_OBJECT()); + ObjectPtr aBaseObject = aBaseObjectAttr->value(); + FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); + + // trim feature + FeaturePtr anNewFeature = SketchPlugin_SegmentationTools::createArcFeature( + aBaseFeature, theStartShapePoint, theLastShapePoint); // arc created by trim of circle is always correct, that means that it is not inversed - anNewFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(false); + const std::string& aReversedAttrName = anNewFeature->getKind() == SketchPlugin_Arc::ID() ? + SketchPlugin_Arc::REVERSED_ID() : SketchPlugin_EllipticArc::REVERSED_ID(); + anNewFeature->boolean(aReversedAttrName)->setValue(false); - theModifiedAttributes.insert( - std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()), - anNewFeature->attribute(SketchPlugin_Arc::CENTER_ID()))); + if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) { + theModifiedAttributes.insert( + std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()), + anNewFeature->attribute(SketchPlugin_Arc::CENTER_ID()))); + } + else if (aBaseFeature->getKind() == SketchPlugin_Ellipse::ID()) { + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::CENTER_ID()), + anNewFeature->attribute(SketchPlugin_EllipticArc::CENTER_ID()))); + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::FIRST_FOCUS_ID()), + anNewFeature->attribute(SketchPlugin_EllipticArc::FIRST_FOCUS_ID()))); + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::SECOND_FOCUS_ID()), + anNewFeature->attribute(SketchPlugin_EllipticArc::SECOND_FOCUS_ID()))); + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::MAJOR_AXIS_START_ID()), + anNewFeature->attribute(SketchPlugin_EllipticArc::MAJOR_AXIS_START_ID()))); + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::MAJOR_AXIS_END_ID()), + anNewFeature->attribute(SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID()))); + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::MINOR_AXIS_START_ID()), + anNewFeature->attribute(SketchPlugin_EllipticArc::MINOR_AXIS_START_ID()))); + theModifiedAttributes.insert(std::make_pair( + aBaseFeature->attribute(SketchPlugin_Ellipse::MINOR_AXIS_END_ID()), + anNewFeature->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(anNewFeature); + + FeaturePtr anOwner = ModelAPI_Feature::feature((*aRef)->owner()); + SketchPlugin_Tools::replaceInName(anOwner, aBaseFeature->name(), anNewFeature->name()); + SketchPlugin_Tools::replaceInName(anOwner->lastResult(), + aBaseFeature->name(), anNewFeature->name()); + } + } + + const std::string& aStartAttrName = anNewFeature->getKind() == SketchPlugin_Arc::ID() ? + SketchPlugin_Arc::START_ID() : SketchPlugin_EllipticArc::START_POINT_ID(); + const std::string& aEndAttrName = anNewFeature->getKind() == SketchPlugin_Arc::ID() ? + SketchPlugin_Arc::END_ID() : SketchPlugin_EllipticArc::END_POINT_ID(); thePoints.insert(std::dynamic_pointer_cast - (anNewFeature->attribute(SketchPlugin_Arc::START_ID()))); + (anNewFeature->attribute(aStartAttrName))); thePoints.insert(std::dynamic_pointer_cast - (anNewFeature->attribute(SketchPlugin_Arc::END_ID()))); + (anNewFeature->attribute(aEndAttrName))); return anNewFeature; } void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartPointAttr, - const AttributePoint2DPtr& theEndPointAttr, + const AttributePoint2DPtr& /*theEndPointAttr*/, std::shared_ptr& theFirstPoint, std::shared_ptr& theLastPoint) const { @@ -1119,7 +1104,7 @@ void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartP void SketchPlugin_Trim::arrangePointsOnArc(const FeaturePtr& theArc, const AttributePoint2DPtr& theStartPointAttr, - const AttributePoint2DPtr& theEndPointAttr, + const AttributePoint2DPtr& /*theEndPointAttr*/, std::shared_ptr& theFirstPoint, std::shared_ptr& theSecondPoint) const { @@ -1128,9 +1113,14 @@ void SketchPlugin_Trim::arrangePointsOnArc(const FeaturePtr& theArc, 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( @@ -1174,7 +1164,6 @@ void SketchPlugin_Trim::fillPointAttribute(const AttributePtr& theModifiedAttrib } } - void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute, const AttributePtr& theSourceAttribute) { @@ -1197,233 +1186,4 @@ void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute, if (aModifiedAttribute.get() && aSourceAttribute.get()) aModifiedAttribute->setValue(aSourceAttribute->value()); } - else if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) { - AttributeRefAttrPtr aRefAttributeToFill = std::dynamic_pointer_cast( - theModifiedAttribute); - AttributeRefAttrPtr aSourceRefAttr = std::dynamic_pointer_cast( - theSourceAttribute); - if (!aSourceRefAttr.get()) - aRefAttributeToFill->setAttr(theSourceAttribute); - else { - if (aSourceRefAttr->isObject()) - aRefAttributeToFill->setObject(aSourceRefAttr->object()); - else - aRefAttributeToFill->setAttr(aSourceRefAttr->attr()); - } - } -} - -FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature, - const std::shared_ptr& theFirstPoint, - const std::shared_ptr& theSecondPoint) -{ -#ifdef DEBUG_TRIM - std::cout << "---- createLineFeature ---" << std::endl; -#endif - - FeaturePtr aFeature; - SketchPlugin_Sketch* aSketch = sketch(); - if (!aSketch || !theBaseFeature.get()) - return aFeature; - - aFeature = aSketch->addFeature(SketchPlugin_Line::ID()); - - fillPointAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPoint); - fillPointAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPoint); - - fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()), - theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID())); - - aFeature->execute(); // to obtain result - -#ifdef DEBUG_TRIM - std::cout << "---- createLineFeature:end ---" << std::endl; -#endif - - return aFeature; -} - -FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature, - const std::shared_ptr& theFirstPoint, - const std::shared_ptr& theSecondPoint) -{ - 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; - -#ifdef DEBUG_TRIM - std::cout << "---- createArcFeature ---" << std::endl; -#endif - - 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)); - fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPoint); - fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPoint); - - 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->execute(); // to obtain result (need to calculate arc parameters before sending Update) - aFeature->data()->blockSendAttributeUpdated(aWasBlocked); - - #ifdef DEBUG_TRIM - std::cout << "---- createArcFeature:end ---" << std::endl; - #endif - - return aFeature; -} - -FeaturePtr SketchPlugin_Trim::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); - -#ifdef DEBUG_TRIM - std::cout << " :" - << "first attribute - " << theFirstAttribute->id() - << "second attribute - " << theSecondAttribute->id() - << std::endl; -#endif - - return aConstraint; -} - -FeaturePtr SketchPlugin_Trim::createConstraintToObject(const std::string& theConstraintId, - const AttributePtr& theFirstAttribute, - const ObjectPtr& theSecondObject) -{ - 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->setObject(theSecondObject); - -#ifdef DEBUG_TRIM - std::cout << " :" - << "first attribute - " << theFirstAttribute->id() - << "second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind() - << std::endl; -#endif - - return aConstraint; -} - -FeaturePtr SketchPlugin_Trim::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; -} - -std::shared_ptr SketchPlugin_Trim::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; -} - -//******************************************************************** -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; }