X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_Trim.cpp;h=9ad6f0db9ecb71e6b63ee53c4f49d71abd29d794;hb=59f84b781e13321cf09c21606b195297fc4c47e5;hp=d989afb3115b8666262fca9687f10512fef8c7f3;hpb=409ad39d4655a87a91986bf9927e47bfc08b5341;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Trim.cpp b/src/SketchPlugin/SketchPlugin_Trim.cpp index d989afb31..9ad6f0db9 100644 --- a/src/SketchPlugin/SketchPlugin_Trim.cpp +++ b/src/SketchPlugin/SketchPlugin_Trim.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -23,6 +24,8 @@ #include #include +#include + #include #include #include @@ -38,6 +41,8 @@ #include #include +#include + #include #include #include @@ -48,11 +53,17 @@ #include -#define DEBUG_TRIM +//#define DEBUG_TRIM_METHODS +//#define DEBUG_TRIM + #ifdef DEBUG_TRIM #include #endif +#ifdef DEBUG_TRIM_METHODS +#include +#endif + static const double PI = 3.141592653589793238463; static const std::string OPERATION_HIGHLIGHT_COLOR() { return "128, 0, 0"; } @@ -64,25 +75,38 @@ SketchPlugin_Trim::SketchPlugin_Trim() void SketchPlugin_Trim::initAttributes() { - data()->addAttribute(SketchPlugin_Trim::BASE_OBJECT(), ModelAPI_AttributeReference::typeId()); - data()->addAttribute(ENTITY_POINT(), GeomDataAPI_Point2D::typeId()); + data()->addAttribute(SketchPlugin_Trim::SELECTED_OBJECT(), + ModelAPI_AttributeReference::typeId()); + data()->addAttribute(SELECTED_POINT(), GeomDataAPI_Point2D::typeId()); + + data()->addAttribute(PREVIEW_POINT(), GeomDataAPI_Point2D::typeId()); + data()->addAttribute(PREVIEW_OBJECT(), ModelAPI_AttributeReference::typeId()); + + data()->attribute(PREVIEW_POINT())->setIsArgument(false); + data()->attribute(SELECTED_POINT())->setIsArgument(false); + data()->attribute(PREVIEW_OBJECT())->setIsArgument(false); + + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PREVIEW_POINT()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PREVIEW_OBJECT()); } -void SketchPlugin_Trim::findShapePoints(std::shared_ptr& aStartPoint, +void SketchPlugin_Trim::findShapePoints(const std::string& theObjectAttributeId, + const std::string& thePointAttributeId, + std::shared_ptr& aStartPoint, std::shared_ptr& aLastPoint) { AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Trim::BASE_OBJECT())); + data()->attribute(theObjectAttributeId)); ObjectPtr aBaseObject = aBaseObjectAttr->value(); AttributePoint2DPtr aPoint = std::dynamic_pointer_cast( - data()->attribute(ENTITY_POINT())); + data()->attribute(thePointAttributeId)); std::shared_ptr anAttributePnt2d = aPoint->pnt(); std::shared_ptr anAttributePnt = sketch()->to3D(anAttributePnt2d->x(), anAttributePnt2d->y()); if (myCashedShapes.find(aBaseObject) == myCashedShapes.end()) - fillObjectShapes(aBaseObject); + fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints); const std::set& aShapes = myCashedShapes[aBaseObject]; if (!aShapes.empty()) { @@ -94,19 +118,28 @@ void SketchPlugin_Trim::findShapePoints(std::shared_ptr& aStartPoin if (aBaseShape->shapeType() == GeomAPI_Shape::EDGE) { std::shared_ptr anEdge(new GeomAPI_Edge(aBaseShape)); - aStartPoint = anEdge->lastPoint(); - aLastPoint = anEdge->firstPoint(); + //GeomAPI_Shape::Orientation anOrientation = anEdge->orientation(); + //if (anOrientation == GeomAPI_Shape::REVERSED) { + aStartPoint = anEdge->lastPoint(); + aLastPoint = anEdge->firstPoint(); + //} + //else { + //aStartPoint = anEdge->firstPoint(); + //aLastPoint = anEdge->lastPoint(); + //} } } } } #ifdef DEBUG_TRIM std::cout << " => " - << "Start Point: [" - << aStartPoint->x() << ", " << aStartPoint->y() << ", " << aStartPoint->z() << "]" - << "Last Point: [" - << aLastPoint->x() << ", " << aLastPoint->y() << ", " << aLastPoint->z() << "]" - << std::endl; + << std::endl << "Attribute point: " + << anAttributePnt->x() << ", " << anAttributePnt->y() << ", " << anAttributePnt->z() << "]" + << std::endl << "Start Point: [" + << aStartPoint->x() << ", " << aStartPoint->y() << ", " << aStartPoint->z() << "]" + << std::endl << "Last Point: [" + << aLastPoint->x() << ", " << aLastPoint->y() << ", " << aLastPoint->z() << "]" + << std::endl; #endif } @@ -114,12 +147,14 @@ std::shared_ptr SketchPlugin_Trim::convertPoint( const std::shared_ptr& thePoint) { std::shared_ptr aPoint; + if (!thePoint.get()) + return aPoint; AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Trim::BASE_OBJECT())); + data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT())); ObjectPtr aBaseObject = aBaseObjectAttr->value(); if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end()) - return aPoint; + fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints); bool aFound = false; const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject); @@ -134,92 +169,170 @@ std::shared_ptr SketchPlugin_Trim::convertPoint( aFound = true; } else { - std::shared_ptr aPlane = sketch()->plane(); - aPoint = thePoint->to2D(aPlane); + aPoint = sketch()->to2D(thePoint); aFound = true; } } } if (!aFound) { - // returns an end of the shape to define direction of split if feature's attribute participates - std::shared_ptr aPlane = sketch()->plane(); - aPoint = thePoint->to2D(aPlane); + // returns an end of the shape to define direction of split if feature's attribute + // participates + aPoint = sketch()->to2D(thePoint); } return aPoint; } void SketchPlugin_Trim::execute() { -#ifdef DEBUG_TRIM - std::cout << "SketchPlugin_Trim::execute" << std::endl; +#ifdef DEBUG_TRIM_METHODS + std::cout << "SketchPlugin_Trim::execute: " << data()->name() << std::endl; #endif SketchPlugin_Sketch* aSketch = sketch(); - if (!aSketch) + if (!aSketch) { + setError("Error: Sketch object is empty."); return; + } // Check the base objects are initialized. AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Trim::BASE_OBJECT())); + data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT())); if(!aBaseObjectAttr->isInitialized()) { setError("Error: Base object is not initialized."); return; } ObjectPtr aBaseObject = aBaseObjectAttr->value(); - if (!aBaseObject.get()) + if (!aBaseObject.get()) { + setError("Error: Base object is not initialized."); return; + } FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); + /// 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(SketchPlugin_Trim::PREVIEW_OBJECT())); + + ObjectPtr aPreviewObject = aPreviewObjectAttr->value(); + AttributePoint2DPtr aPoint = std::dynamic_pointer_cast( + data()->attribute(PREVIEW_POINT())); + std::shared_ptr aPreviewPnt2d = aPoint->pnt(); + // nullify pointer of preview attribute + aPreviewObjectAttr->setValue(ResultPtr()); + + bool anIsEqualPreviewAndSelected = aPreviewObject == aBaseObject; + /// points of trim std::shared_ptr aStartShapePoint, aLastShapePoint; - findShapePoints(aStartShapePoint, aLastShapePoint); - std::shared_ptr aStartShapePoint2d = convertPoint(aStartShapePoint); +#ifdef DEBUG_TRIM + std::cout << " Base Feature: " << aBaseFeature->data()->name() << std::endl; +#endif + findShapePoints(SELECTED_OBJECT(), SELECTED_POINT(), aStartShapePoint, aLastShapePoint); + std::shared_ptr aStartShapePoint2d = convertPoint(aStartShapePoint); std::shared_ptr aLastShapePoint2d = convertPoint(aLastShapePoint); - std::set aFeaturesToDelete; - getConstraints(aFeaturesToDelete); + std::set aFeaturesToDelete, aFeaturesToUpdate; + getConstraints(aFeaturesToDelete, aFeaturesToUpdate); std::map > aBaseRefAttributes; std::list aRefsToFeature; getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature); - - +#ifdef DEBUG_TRIM + std::cout << "---- getRefAttributes ----" << std::endl; + std::map >::const_iterator + aRefIt = aBaseRefAttributes.begin(), aRefLast = aBaseRefAttributes.end(); + std::cout << std::endl << "References to attributes of base feature [" << + aBaseRefAttributes.size() << "]" << std::endl; + for (; aRefIt != aRefLast; aRefIt++) { + AttributePtr aBaseAttr = aRefIt->first; + std::list aRefAttributes = aRefIt->second; + std::string aRefsInfo; + std::list::const_iterator aRefAttrIt = aRefAttributes.begin(), + aRefAttrLast = aRefAttributes.end(); + for (; aRefAttrIt != aRefAttrLast; aRefAttrIt++) { + if (!aRefsInfo.empty()) + aRefsInfo.append(","); + AttributePtr aRAttr = *aRefAttrIt; + aRefsInfo.append(aRAttr->id()); + FeaturePtr aRFeature = ModelAPI_Feature::feature(aRAttr->owner()); + aRefsInfo.append("(" + aRFeature->name() + ") "); + } + std::shared_ptr aPointAttr = + std::dynamic_pointer_cast(aBaseAttr); + std::cout << aPointAttr->id().c_str() << + ": " << "[" << aRefAttributes.size() << "] " << aRefsInfo << std::endl; + } + std::cout << std::endl; + std::cout << std::endl << "References to base feature [" << + aRefsToFeature.size() << "]" << std::endl; + std::list::const_iterator aRefAttrIt = aRefsToFeature.begin(), + aRefAttrLast = aRefsToFeature.end(); + std::string aRefsInfo; + for (; aRefAttrIt != aRefAttrLast; aRefAttrIt++) { + if (!aRefsInfo.empty()) + aRefsInfo.append(","); + AttributePtr aRAttr = *aRefAttrIt; + aRefsInfo.append(aRAttr->id()); + FeaturePtr aRFeature = ModelAPI_Feature::feature(aRAttr->owner()); + aRefsInfo.append("(" + aRFeature->name() + ") "); + } + std::cout << "[" << aRefsToFeature.size() << "] " << aRefsInfo << std::endl; + std::cout << "---- getRefAttributes:end ----" << std::endl; +#endif // coincidence to result points // find coincidences to the base object, it should be used when attribute is found // in myObjectToPoints - std::map aCoincidencesToBaseFeature; - getCoincidencesToObject(aBaseObject, aCoincidencesToBaseFeature); + //std::map aCoincidencesToBaseFeature; + //getCoincidencesToObject(aBaseObject, aCoincidencesToBaseFeature); std::set aFurtherCoincidences; std::set> aModifiedAttributes; const std::string& aKind = aBaseFeature->getKind(); - FeaturePtr aReplacingFeature; + FeaturePtr aReplacingFeature, aNewFeature; if (aKind == SketchPlugin_Circle::ID()) { aReplacingFeature = trimCircle(aStartShapePoint2d, aLastShapePoint2d, aFurtherCoincidences, aModifiedAttributes); aFeaturesToDelete.insert(aBaseFeature); - // as circle is removed, temporary fill this attribute + // as circle is removed, erase it from dependencies(arguments) of this feature + // otherwise Trim feature will be removed with the circle before + // this operation is finished aBaseObjectAttr->setObject(ResultPtr()); } else if (aKind == SketchPlugin_Line::ID()) { - trimLine(aStartShapePoint2d, aLastShapePoint2d, - aFurtherCoincidences, aModifiedAttributes); + aNewFeature = trimLine(aStartShapePoint2d, aLastShapePoint2d, aBaseRefAttributes, + aFurtherCoincidences, aModifiedAttributes); } else if (aKind == SketchPlugin_Arc::ID()) { - trimArc(aStartShapePoint2d, aLastShapePoint2d, - aFurtherCoincidences, aModifiedAttributes); + aNewFeature = trimArc(aStartShapePoint2d, aLastShapePoint2d, aBaseRefAttributes, + aFurtherCoincidences, aModifiedAttributes); } - // + // constraints to end points of trim feature + if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end()) + fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints); + + // create coincidence to objects, intersected the base object const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject); - std::set::const_iterator anIt = aFurtherCoincidences.begin(), - aLast = aFurtherCoincidences.end(); - for (; anIt != aLast; anIt++) { + for (std::set::const_iterator anIt = aFurtherCoincidences.begin(), + aLast = aFurtherCoincidences.end(); + anIt != aLast; anIt++) { AttributePoint2DPtr aPointAttribute = (*anIt); std::shared_ptr aPoint2d = aPointAttribute->pnt(); +#ifdef DEBUG_TRIM + std::cout << " => " << std::endl + << "aPoint2d: [" << aPoint2d->x() << ", " << aPoint2d->y() << "]" << std::endl; + if (aStartShapePoint2d.get()) + std::cout << "Start Point: [" << aStartShapePoint2d->x() << ", " << aStartShapePoint2d->y() + << "]" << std::endl; + if (aLastShapePoint2d.get()) + std::cout << "Last Point: [" << aLastShapePoint2d->x() << ", " << aLastShapePoint2d->y() + << "]" << std::endl; +#endif + std::shared_ptr aPoint; if (aStartShapePoint2d.get() && aPoint2d->isEqual(aStartShapePoint2d)) aPoint = aStartShapePoint; @@ -238,29 +351,6 @@ void SketchPlugin_Trim::execute() break; } } - const std::list& anAttributes = anInfo.first; - for (std::list::const_iterator anAttrIt = anAttributes.begin(); - anAttrIt != anAttributes.end(); anAttrIt++) { - AttributePtr anAttribute = *anAttrIt; - if (aCoincidencesToBaseFeature.find(anAttribute) != aCoincidencesToBaseFeature.end()) - { - FeaturePtr anAttrFeature = aCoincidencesToBaseFeature.at(anAttribute); - AttributePtr anOtherAttribute; - if (std::dynamic_pointer_cast - (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()))->attr() == anAttribute) - anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()); - else if (std::dynamic_pointer_cast - (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()))->attr() == anAttribute) - anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()); - else - continue; - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast - (anOtherAttribute); - if (aRefAttr.get()) - aRefAttr->setAttr(aPointAttribute); - } - } - const std::list& anObjects = anInfo.second; for (std::list::const_iterator anObjectIt = anObjects.begin(); anObjectIt != anObjects.end(); anObjectIt++) { @@ -271,57 +361,239 @@ void SketchPlugin_Trim::execute() // move constraints from base feature to replacing feature: ignore coincidences to feature // if attributes of coincidence participated in split + ResultPtr aReplacingResult; if (aReplacingFeature.get()) { - ResultPtr aReplacingResult = getFeatureResult(aReplacingFeature); - std::list::const_iterator anIt = aRefsToFeature.begin(), - aLast = aRefsToFeature.end(); - for (; anIt != aLast; anIt++) { - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(*anIt); - if (!aRefAttr.get()) - continue; - FeaturePtr anAttrFeature = ModelAPI_Feature::feature(aRefAttr->owner()); - if (anAttrFeature.get() && - anAttrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) - { - if (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()) == aRefAttr || - anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()) == aRefAttr) - continue; + aReplacingFeature->execute(); // need it to obtain result + aReplacingResult = getFeatureResult(aReplacingFeature); + } + for(std::list::const_iterator anIt = aRefsToFeature.begin(), + aLast = aRefsToFeature.end(); + anIt != aLast; anIt++) { + AttributePtr anAttribute = *anIt; + + //if (replaceCoincidenceAttribute(anAttribute, aModifiedAttributes)) + // continue; + + if (setCoincidenceToAttribute(anAttribute, aFurtherCoincidences)) + continue; + + if (aReplacingResult.get()) { + AttributeRefAttrPtr aRefAttr = + std::dynamic_pointer_cast(anAttribute); + if (aRefAttr.get()) + aRefAttr->setObject(aReplacingResult); + else { + AttributeReferencePtr aReferenceAttr = + std::dynamic_pointer_cast(anAttribute); + if (aReferenceAttr.get()) + aReferenceAttr->setObject(aReplacingResult); } - aRefAttr->setObject(aReplacingResult); } } + updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete); + // Wait all constraints being created, then send update events static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent); if (isUpdateFlushed) Events_Loop::loop()->setFlushed(anUpdateEvent, false); - updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete); - // delete constraints #ifdef DEBUG_TRIM - std::cout << "remove features and references:" << std::endl; - std::set::const_iterator aDIt = aFeaturesToDelete.begin(), - aDLast = aFeaturesToDelete.end(); - for (; aDIt != aDLast; aDIt++) { - //std::cout << getFeatureInfo(*aDIt, false) << std::endl; - //std::cout << std::endl; + if (aFeaturesToDelete.size() > 0) { + std::cout << "after SPlit: removeFeaturesAndReferences: " << std::endl; + std::string aValue; + for (std::set::const_iterator anIt = aFeaturesToDelete.begin(); + anIt != aFeaturesToDelete.end(); anIt++) { + FeaturePtr aFeature = *anIt; + std::cout << aFeature->data()->name() << std::endl; + } } #endif ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete); Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); + updateFeaturesAfterTrim(aFeaturesToUpdate); + // Send events to update the sub-features by the solver. if(isUpdateFlushed) { Events_Loop::loop()->setFlushed(anUpdateEvent, true); } + if (anIsEqualPreviewAndSelected) { + // equal preview and selected objects + // nothing to do if the preview and selected objects are different + if (aReplacingResult.get()) { // base object was removed + aPreviewObject = aReplacingResult; + //aMessage->setSelectedObject(aReplacingResult); + + GeomShapePtr aSelectedShape = aReplacingResult->shape(); + std::shared_ptr aPreviewPnt = sketch()->to3D(aPreviewPnt2d->x(), + aPreviewPnt2d->y()); + std::shared_ptr aProjectedPoint; + if (ModelGeomAlgo_Point2D::isPointOnEdge(aSelectedShape, aPreviewPnt, aProjectedPoint)) { + bool aValue = true; + } + //aBaseShape = aShape; + +#ifdef DEBUG_TRIM_METHODS + if (!aSelectedShape.get()) + std::cout << "Set empty selected object" << std::endl; + else + std::cout << "Set shape with ShapeType: " << aSelectedShape->shapeTypeStr() << std::endl; +#endif + bool aValue = true; + } + else { + aPreviewObject = ObjectPtr(); + + aBaseFeature->execute(); // should recompute shapes of result to do not check obsolete one + aBaseObject = getFeatureResult(aBaseFeature); + std::shared_ptr aPreviewPnt = sketch()->to3D(aPreviewPnt2d->x(), + aPreviewPnt2d->y()); + ResultPtr aBaseResult = std::dynamic_pointer_cast(aBaseObject); + if (aBaseResult) { + GeomShapePtr aShape = aBaseResult->shape(); + std::shared_ptr aProjectedPoint; + if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, aPreviewPnt, aProjectedPoint)) + aPreviewObject = aBaseResult; + } + if (!aPreviewObject.get() && aNewFeature.get()) { + ResultPtr aNewFeatureResult = getFeatureResult(aNewFeature); + if (aNewFeatureResult.get()) { + GeomShapePtr aShape = aNewFeatureResult->shape(); + std::shared_ptr aProjectedPoint; + if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, aPreviewPnt, aProjectedPoint)) + aPreviewObject = aNewFeatureResult; + } + } + } + } + if (aPreviewObject.get()) { + std::shared_ptr aMessage = std::shared_ptr + (new ModelAPI_EventReentrantMessage( + ModelAPI_EventReentrantMessage::eventId(), this)); + aMessage->setSelectedObject(aPreviewObject); + Events_Loop::loop()->send(aMessage); + } #ifdef DEBUG_TRIM std::cout << "SketchPlugin_Trim::done" << std::endl; #endif } +std::string SketchPlugin_Trim::processEvent(const std::shared_ptr& theMessage) +{ +#ifdef DEBUG_TRIM_METHODS + std::cout << "SketchPlugin_Trim::processEvent:" << data()->name() << std::endl; +#endif + std::string aFilledAttributeName; + + std::shared_ptr aMessage = + std::dynamic_pointer_cast(theMessage); + if (aMessage.get()) { + ObjectPtr anObject = aMessage->selectedObject(); + std::shared_ptr aPoint = aMessage->clickedPoint(); + + if (anObject.get() && aPoint.get()) { + if (myCashedShapes.find(anObject) == myCashedShapes.end()) + fillObjectShapes(anObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints); + const std::set& aShapes = myCashedShapes[anObject]; + if (aShapes.size() > 1) { + std::shared_ptr aRefSelectedAttr = + std::dynamic_pointer_cast( + data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT())); + std::shared_ptr aRefPreviewAttr = + std::dynamic_pointer_cast( + data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT())); + aRefSelectedAttr->setValue(anObject); + aRefPreviewAttr->setValue(anObject); + + std::shared_ptr aPointSelectedAttr = + std::dynamic_pointer_cast( + data()->attribute(SketchPlugin_Trim::SELECTED_POINT())); + std::shared_ptr aPointPreviewAttr = + std::dynamic_pointer_cast( + data()->attribute(SketchPlugin_Trim::PREVIEW_POINT())); + aPointSelectedAttr->setValue(aPoint); + aPointPreviewAttr->setValue(aPoint); + + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); + + GeomShapePtr aSelectedShape = getSubShape(SELECTED_OBJECT(), SELECTED_POINT()); + #ifdef DEBUG_TRIM_METHODS + if (!aSelectedShape.get()) + std::cout << "Set empty selected object" << std::endl; + else + std::cout << "Set shape with ShapeType: " << aSelectedShape->shapeTypeStr() << std::endl; + #endif + aFilledAttributeName = SketchPlugin_Trim::SELECTED_OBJECT(); + } + } + } + return aFilledAttributeName; +} + +bool SketchPlugin_Trim::setCoincidenceToAttribute(const AttributePtr& theAttribute, + const std::set& theFurtherCoincidences) +{ + FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner()); + if (aFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID()) + return false; + + AttributePoint2DPtr aRefPointAttr = SketchPlugin_ConstraintCoincidence::getPoint(aFeature); + if (!aRefPointAttr.get()) + return false; + std::shared_ptr aRefPnt2d = aRefPointAttr->pnt(); + + std::set::const_iterator anIt = theFurtherCoincidences.begin(), + aLast = theFurtherCoincidences.end(); + bool aFoundPoint = false; + for (; anIt != aLast && !aFoundPoint; anIt++) { + 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; + } + } + } + return aFoundPoint; +} + +bool SketchPlugin_Trim::replaceCoincidenceAttribute(const AttributePtr& theCoincidenceAttribute, + const std::set>& theModifiedAttributes) +{ + FeaturePtr aCoincidenceFeature = ModelAPI_Feature::feature(theCoincidenceAttribute->owner()); + if (aCoincidenceFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID()) + return false; + + AttributeRefAttrPtr aCAttrA = std::dynamic_pointer_cast( + aCoincidenceFeature->attribute(SketchPlugin_Constraint::ENTITY_A())); + AttributeRefAttrPtr aCAttrB = std::dynamic_pointer_cast( + aCoincidenceFeature->attribute(SketchPlugin_Constraint::ENTITY_B())); + AttributePtr aCAttrRefA = aCAttrA->attr(); + AttributePtr aCAttrRefB = aCAttrB->attr(); + + bool isProcessed = false; + for (std::set>::const_iterator + anIt = theModifiedAttributes.begin(); anIt != theModifiedAttributes.end(); anIt++) { + AttributePtr anAttributeBefore = anIt->first; + if (anAttributeBefore == aCAttrRefA) { + aCAttrA->setAttr(anIt->second); + isProcessed = true; + } + if (anAttributeBefore == aCAttrRefB) { + aCAttrB->setAttr(anIt->second); + isProcessed = true; + } + } + return isProcessed; +} + bool SketchPlugin_Trim::isMacro() const { return true; @@ -329,26 +601,68 @@ bool SketchPlugin_Trim::isMacro() const AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious) { +#ifdef DEBUG_TRIM_METHODS + std::cout << "SketchPlugin_Trim::getAISObject: " << data()->name() << std::endl; +#endif + AISObjectPtr anAIS = thePrevious; - // feature for trim - AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Trim::BASE_OBJECT())); - ObjectPtr aBaseObject = aBaseObjectAttr->value(); - if (!aBaseObject.get()) + + 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(); - FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); + + 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 aPoint = std::dynamic_pointer_cast( - data()->attribute(ENTITY_POINT())); + data()->attribute(thePointAttributeId)); std::shared_ptr anAttributePnt2d = aPoint->pnt(); std::shared_ptr anAttributePnt = sketch()->to3D(anAttributePnt2d->x(), anAttributePnt2d->y()); if (myCashedShapes.find(aBaseObject) == myCashedShapes.end()) - fillObjectShapes(aBaseObject); - - GeomShapePtr aBaseShape; + fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints); const std::set& aShapes = myCashedShapes[aBaseObject]; if (!aShapes.empty()) { @@ -360,34 +674,7 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious) aBaseShape = aShape; } } - - if (aBaseShape.get()) { - if (!anAIS) - anAIS = AISObjectPtr(new GeomAPI_AISObject); - anAIS->createShape(aBaseShape); - - std::shared_ptr anAuxiliaryAttr = - aBaseFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID()); - - bool isConstruction = anAuxiliaryAttr.get() != NULL && anAuxiliaryAttr->value(); - std::vector aColor; - aColor = Config_PropManager::color("Visualization", "operation_remove_feature_color", - OPERATION_REMOVE_FEATURE_COLOR()); - double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH(); - int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE(); - if (isConstruction) { - aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH_AUXILIARY(); - aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE_AUXILIARY(); - } - anAIS->setColor(aColor[0], aColor[1], aColor[2]); - // width is extened in several points in order to see this preview over highlight - anAIS->setWidth(aWidth + 2); - anAIS->setLineStyle(aLineStyle); - } - else - anAIS = AISObjectPtr(); - - return anAIS; + return aBaseShape; } void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature, @@ -412,13 +699,14 @@ void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature, } } -void SketchPlugin_Trim::getConstraints(std::set& theFeaturesToDelete) +void SketchPlugin_Trim::getConstraints(std::set& theFeaturesToDelete, + std::set& theFeaturesToUpdate) { std::shared_ptr aData = data(); // Check the base objects are initialized. AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Trim::BASE_OBJECT())); + aData->attribute(SketchPlugin_Trim::SELECTED_OBJECT())); FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature); @@ -436,6 +724,8 @@ void SketchPlugin_Trim::getConstraints(std::set& theFeaturesToDelete aRefFeatureKind == SketchPlugin_MultiTranslation::ID() || aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID()) theFeaturesToDelete.insert(aRefFeature); + else if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID()) + theFeaturesToUpdate.insert(aRefFeature); } } @@ -485,7 +775,7 @@ void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature, } } -void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject, +/*void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject, std::map& theCoincidencesToBaseFeature) { const std::set& aRefsList = theObject->data()->refsToMe(); @@ -503,23 +793,25 @@ void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject, anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B()); } else { - aRefAttr = std::dynamic_pointer_cast + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B())); if (aRefAttr->isObject() && aRefAttr->object() == theObject) - { anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A()); - } - if (anAttribute.get()) - { - aRefAttr = std::dynamic_pointer_cast - (anAttribute); - anAttribute = aRefAttr->attr(); - if (anAttribute.get()) - theCoincidencesToBaseFeature[anAttribute] = aRefFeature; - } + } + if (!anAttribute.get()) + continue; + + aRefAttr = std::dynamic_pointer_cast(anAttribute); + if (aRefAttr->isObject()) + continue; // one of attributes of coincidence contains link to an attribute + + anAttribute = aRefAttr->attr(); + if (anAttribute.get()) + { + theCoincidencesToBaseFeature[anAttribute] = aRefFeature; } } -} +}*/ void SketchPlugin_Trim::updateRefAttConstraints( const std::map >& theBaseRefAttributes, @@ -543,30 +835,85 @@ void SketchPlugin_Trim::updateRefAttConstraints( aRLast = aRefAttributes.end(); AttributePtr aNewAttribute = anIt->second; - for (; aRefIt != aRLast; aRefIt++) { - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(*aRefIt); - if (aRefAttr.get()) { - if (aNewAttribute.get()) - aRefAttr->setAttr(aNewAttribute); - else - theFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner())); + 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) +{ + /// not found in references + if (theBaseRefAttributes.find(theAttribute) == theBaseRefAttributes.end()) + return; + + std::list aRefAttributes = theBaseRefAttributes.at(theAttribute); + std::list::const_iterator aRefIt = aRefAttributes.begin(), + aRLast = aRefAttributes.end(); + + std::set aFeaturesToDelete; + for (; aRefIt != aRLast; aRefIt++) { + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(*aRefIt); + if (aRefAttr.get()) { + aFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner())); + } + } + #ifdef DEBUG_TRIM - //FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner()); - //std::cout << " -" << getFeatureInfo(aFeature) << std::endl; + // delete constraints + if (aFeaturesToDelete.size() > 0) { + std::cout << "removeReferencesToAttribute: " << std::endl; + std::string aValue; + for (std::set::const_iterator anIt = aFeaturesToDelete.begin(); + anIt != aFeaturesToDelete.end(); anIt++) { + FeaturePtr aFeature = *anIt; + std::cout << aFeature->data()->name() << std::endl; + } + } #endif + ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete); + 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); } } } } -void SketchPlugin_Trim::trimLine(const std::shared_ptr& theStartShapePoint, - const std::shared_ptr& theLastShapePoint, - std::set& thePoints, +FeaturePtr SketchPlugin_Trim::trimLine(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::BASE_OBJECT())); + data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT())); ObjectPtr aBaseObject = aBaseObjectAttr->value(); FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); @@ -607,17 +954,23 @@ void SketchPlugin_Trim::trimLine(const std::shared_ptr& theStartS else aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint; + // it is important to delete references before the feature modification because + // if deletion will be after the feature modification, solver returns the feature back + removeReferencesToAttribute(aBaseFeature->attribute(aModifiedAttribute), + theBaseRefAttributes); + fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint); - theModifiedAttributes.insert( - std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr())); + //theModifiedAttributes.insert( + // std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr())); thePoints.insert(std::dynamic_pointer_cast (aBaseFeature->attribute(aModifiedAttribute))); } else { - // result is two lines: start line point - start shape point, last shape point - last line point + // result is two lines: start line point - start shape point, + // last shape point - last line point // create second line - FeaturePtr anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint); + anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint); thePoints.insert(std::dynamic_pointer_cast (anNewFeature->attribute(SketchPlugin_Line::START_ID()))); @@ -638,16 +991,19 @@ void SketchPlugin_Trim::trimLine(const std::shared_ptr& theStartS getFeatureResult(anNewFeature)); } + return anNewFeature; } -void SketchPlugin_Trim::trimArc(const std::shared_ptr& theStartShapePoint, - const std::shared_ptr& theLastShapePoint, - std::set& thePoints, +FeaturePtr SketchPlugin_Trim::trimArc(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::BASE_OBJECT())); + data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT())); ObjectPtr aBaseObject = aBaseObjectAttr->value(); FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); @@ -665,14 +1021,14 @@ void SketchPlugin_Trim::trimArc(const std::shared_ptr& theStartSh #ifdef DEBUG_TRIM std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl; if (aStartShapePoint.get()) - std::cout << "Start point: [" << aStartShapePoint->x() << ", " << + std::cout << "Start shape point: [" << aStartShapePoint->x() << ", " << aStartShapePoint->y() << "]" << std::endl; - std::cout << "1st point: [" << aStartArcPoint->x() << ", " << + std::cout << "Start arc attribute point: [" << aStartArcPoint->x() << ", " << aStartArcPoint->y() << "]" << std::endl; if (aLastShapePoint.get()) - std::cout << "2st point: [" << aLastShapePoint->x() << ", " << + std::cout << "Last shape point: [" << aLastShapePoint->x() << ", " << aLastShapePoint->y() << "]" << std::endl; - std::cout << "End point: [" << aLastArcPoint->x() << ", " << + std::cout << "Last arc attribute point: [" << aLastArcPoint->x() << ", " << aLastArcPoint->y() << "]" << std::endl; #endif @@ -688,9 +1044,10 @@ void SketchPlugin_Trim::trimArc(const std::shared_ptr& theStartSh else aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint; + removeReferencesToAttribute(aBaseFeature->attribute(aModifiedAttribute), + theBaseRefAttributes); + fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint); - theModifiedAttributes.insert( - std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr())); thePoints.insert(std::dynamic_pointer_cast (aBaseFeature->attribute(aModifiedAttribute))); @@ -698,14 +1055,14 @@ void SketchPlugin_Trim::trimArc(const std::shared_ptr& theStartSh else { // result is two arcs: start arc point - start shape point, last shape point - last arc point // create second arc - FeaturePtr anArcFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint); + anNewFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint); thePoints.insert(std::dynamic_pointer_cast - (anArcFeature->attribute(SketchPlugin_Arc::START_ID()))); + (anNewFeature->attribute(SketchPlugin_Arc::START_ID()))); std::string aModifiedAttribute = SketchPlugin_Arc::END_ID(); theModifiedAttributes.insert( std::make_pair(aBaseFeature->attribute(aModifiedAttribute), - anArcFeature->attribute(SketchPlugin_Arc::END_ID()))); + anNewFeature->attribute(SketchPlugin_Arc::END_ID()))); // modify base arc fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint); @@ -716,12 +1073,19 @@ void SketchPlugin_Trim::trimArc(const std::shared_ptr& theStartSh // equal Radius constraint for arcs createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), getFeatureResult(aBaseFeature), - getFeatureResult(anArcFeature)); + getFeatureResult(anNewFeature)); // coincident centers constraint createConstraint(SketchPlugin_ConstraintCoincidence::ID(), aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()), - anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID())); + anNewFeature->attribute(SketchPlugin_Arc::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::trimCircle(const std::shared_ptr& theStartShapePoint, @@ -731,7 +1095,7 @@ FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr& t { // Check the base objects are initialized. AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Trim::BASE_OBJECT())); + data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT())); ObjectPtr aBaseObject = aBaseObjectAttr->value(); FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); @@ -740,18 +1104,20 @@ FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr& t //getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase); /// trim feature - FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint); + FeaturePtr anNewFeature = 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); theModifiedAttributes.insert( std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()), - anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()))); + anNewFeature->attribute(SketchPlugin_Arc::CENTER_ID()))); thePoints.insert(std::dynamic_pointer_cast - (anArcFeature->attribute(SketchPlugin_Arc::START_ID()))); + (anNewFeature->attribute(SketchPlugin_Arc::START_ID()))); thePoints.insert(std::dynamic_pointer_cast - (anArcFeature->attribute(SketchPlugin_Arc::END_ID()))); + (anNewFeature->attribute(SketchPlugin_Arc::END_ID()))); - return anArcFeature; + return anNewFeature; } void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartPointAttr, @@ -784,7 +1150,7 @@ void SketchPlugin_Trim::arrangePointsOnArc(const FeaturePtr& theArc, std::shared_ptr aCenter = std::dynamic_pointer_cast( theArc->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt(); - bool isReversed = theArc->boolean(SketchPlugin_Arc::INVERSED_ID())->value(); + bool isReversed = theArc->boolean(SketchPlugin_Arc::REVERSED_ID())->value(); // collect directions to each point std::shared_ptr aStartDir( @@ -820,8 +1186,10 @@ void SketchPlugin_Trim::fillPointAttribute(const AttributePtr& theModifiedAttrib aModifiedAttribute->setValue(thePoint); #ifdef DEBUG_TRIM - std::cout << " => Pnt2d - [" << thePoint->x() << ", " - << thePoint->y() << "]" << std::endl; + FeaturePtr aFeature = ModelAPI_Feature::feature(theModifiedAttribute->owner()); + std::cout << "data()->name() << ": " << + theModifiedAttribute->id() << + "]> => Pnt2d - [" << thePoint->x() << ", " << thePoint->y() << "]" << std::endl; #endif } } @@ -869,6 +1237,10 @@ 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()) @@ -884,10 +1256,13 @@ FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature 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) @@ -906,15 +1281,16 @@ FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature, 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); - aFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue( - SketchPlugin_Arc::ARC_TYPE_CENTER_START_END()); - fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()), theBaseFeature->attribute(aCenterAttributeId)); fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPoint); @@ -925,12 +1301,16 @@ FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature, /// 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::INVERSED_ID())->value(); - aFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->setValue(aReversed); + bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->value(); + aFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(aReversed); } - aFeature->execute(); // to obtain result + 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; } @@ -1014,13 +1394,10 @@ std::shared_ptr SketchPlugin_Trim::getFeatureResult( } //******************************************************************** -bool SketchPlugin_Trim::useGraphicIntersection() const -{ - return true; -} - -//******************************************************************** -void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject) +void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject, + const ObjectPtr& theSketch, + std::map >& theCashedShapes, + std::map& theObjectToPoints) { PointToRefsMap aPointsInfo; @@ -1035,7 +1412,7 @@ void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject) FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); std::set anEdgeShapes; // edges on feature - ModelAPI_Tools::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes); + ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes); if (!anEdgeShapes.empty()) { GeomShapePtr aFeatureShape = (*anEdgeShapes.begin())->shape(); @@ -1043,8 +1420,8 @@ void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject) 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 - SketchPlugin_Sketch* aSketch = sketch(); - std::shared_ptr aData = aSketch->data(); + //SketchPlugin_Sketch* aSketch = sketch(); + 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( @@ -1056,52 +1433,18 @@ void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject) ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(), aX->dir(), aY, aPointsInfo); - // intersection points - if (useGraphicIntersection()) { - std::list aFeatures; - for (int i = 0; i < aSketch->numberOfSubs(); i++) { - FeaturePtr aFeature = aSketch->subFeature(i); - if (aFeature.get()) - aFeatures.push_back(aFeature); - } - ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, 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()) + aFeatures.push_back(aFeature); } - GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPointsInfo, aShapes); - } - myObjectToPoints[theObject] = aPointsInfo; - myCashedShapes[theObject] = aShapes; -} + ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPointsInfo); -//******************************************************************** -void SketchPlugin_Trim::attributeChanged(const std::string& theID) -{ - //data()->addAttribute(SketchPlugin_Trim::BASE_OBJECT(), ModelAPI_AttributeReference::typeId()); - if (theID == SketchPlugin_Trim::BASE_OBJECT()) { - bool isValidAttribute = false; - // feature for trim - AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Trim::BASE_OBJECT())); - ObjectPtr aBaseObject = aBaseObjectAttr->value(); - if (aBaseObject.get()) { - FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); - // point on feature - AttributePoint2DPtr aPoint = std::dynamic_pointer_cast( - data()->attribute(ENTITY_POINT())); - std::shared_ptr anAttributePnt2d = aPoint->pnt(); - std::shared_ptr anAttributePnt = sketch()->to3D(anAttributePnt2d->x(), - anAttributePnt2d->y()); - - if (myCashedShapes.find(aBaseObject) == myCashedShapes.end()) - fillObjectShapes(aBaseObject); - - const std::set& aShapes = myCashedShapes[aBaseObject]; - isValidAttribute = !aShapes.empty(); - - if (!isValidAttribute) { - bool aWasBlocked = data()->blockSendAttributeUpdated(true); - aBaseObjectAttr->setValue(ObjectPtr()); - data()->blockSendAttributeUpdated(aWasBlocked); - } - } + GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPointsInfo, aShapes); } + theObjectToPoints[theObject] = aPointsInfo; + theCashedShapes[theObject] = aShapes; }