X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FSketchPlugin%2FSketchPlugin_Trim.cpp;h=46b01dee111b80214a810185788aa4d61d2be937;hb=601d5f7bc5c56f69d114e49a35bf49d126035ba8;hp=d57e409c5ce2fd60cf93d37976278d2421694236;hpb=e8ed54f8e2b9d82191f7040b6255a41c0a59e109;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Trim.cpp b/src/SketchPlugin/SketchPlugin_Trim.cpp index d57e409c5..46b01dee1 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 @@ -64,25 +67,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 +110,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 } @@ -116,10 +141,10 @@ std::shared_ptr SketchPlugin_Trim::convertPoint( std::shared_ptr 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,16 +159,15 @@ 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; } @@ -160,7 +184,7 @@ void SketchPlugin_Trim::execute() // 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; @@ -170,9 +194,20 @@ void SketchPlugin_Trim::execute() 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())); + aPreviewObjectAttr->setValue(ResultPtr()); + /// points of trim std::shared_ptr aStartShapePoint, aLastShapePoint; - findShapePoints(aStartShapePoint, aLastShapePoint); +#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); @@ -183,13 +218,53 @@ void SketchPlugin_Trim::execute() 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; @@ -200,26 +275,43 @@ void SketchPlugin_Trim::execute() 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, + trimLine(aStartShapePoint2d, aLastShapePoint2d, aBaseRefAttributes, aFurtherCoincidences, aModifiedAttributes); } else if (aKind == SketchPlugin_Arc::ID()) { - trimArc(aStartShapePoint2d, aLastShapePoint2d, + 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 +330,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,42 +340,54 @@ 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); @@ -322,6 +403,66 @@ void SketchPlugin_Trim::execute() #endif } +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; @@ -330,60 +471,75 @@ bool SketchPlugin_Trim::isMacro() const AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious) { AISObjectPtr anAIS = thePrevious; - // feature for trim - AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Trim::BASE_OBJECT())); - ObjectPtr aBaseObject = aBaseObjectAttr->value(); + + 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 anAIS; - FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value()); + 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); + 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 aBaseShape = *anIt; + GeomShapePtr aShape = *anIt; std::shared_ptr aProjectedPoint; - if (ModelGeomAlgo_Point2D::isPointOnEdge(aBaseShape, anAttributePnt, aProjectedPoint)) { - if (aBaseShape) { - 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]); - anAIS->setWidth(aWidth); - anAIS->setLineStyle(aLineStyle); - break; - } - } + if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, anAttributePnt, aProjectedPoint)) + aBaseShape = aShape; } } - - return anAIS; + return aBaseShape; } void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature, @@ -414,7 +570,7 @@ void SketchPlugin_Trim::getConstraints(std::set& theFeaturesToDelete // 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); @@ -481,7 +637,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(); @@ -499,23 +655,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, @@ -539,30 +697,62 @@ 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())); -#ifdef DEBUG_TRIM - //FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner()); - //std::cout << " -" << getFeatureInfo(aFeature) << std::endl; -#endif + 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 + // 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::trimLine(const std::shared_ptr& theStartShapePoint, - const std::shared_ptr& theLastShapePoint, - std::set& thePoints, + const std::shared_ptr& theLastShapePoint, + std::map >& theBaseRefAttributes, + std::set& thePoints, std::set>& theModifiedAttributes) { // 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()); @@ -603,15 +793,21 @@ 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); thePoints.insert(std::dynamic_pointer_cast @@ -637,13 +833,14 @@ void SketchPlugin_Trim::trimLine(const std::shared_ptr& theStartS } void SketchPlugin_Trim::trimArc(const std::shared_ptr& theStartShapePoint, - const std::shared_ptr& theLastShapePoint, - std::set& thePoints, + const std::shared_ptr& theLastShapePoint, + std::map >& theBaseRefAttributes, + std::set& thePoints, std::set>& theModifiedAttributes) { // 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()); @@ -661,14 +858,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 @@ -684,9 +881,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))); @@ -710,6 +908,7 @@ void SketchPlugin_Trim::trimArc(const std::shared_ptr& theStartSh (aBaseFeature->attribute(aModifiedAttribute))); // equal Radius constraint for arcs + anArcFeature->execute(); // we need the created arc result to set equal constraint createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), getFeatureResult(aBaseFeature), getFeatureResult(anArcFeature)); @@ -717,6 +916,11 @@ void SketchPlugin_Trim::trimArc(const std::shared_ptr& theStartSh createConstraint(SketchPlugin_ConstraintCoincidence::ID(), aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()), anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID())); + + std::cout << "Created arc on points:" << std::endl; + std::cout << "Start shape point: [" << aStartShapePoint->x() << ", " << + aStartShapePoint->y() << "]" << std::endl; + } } @@ -727,7 +931,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()); @@ -737,6 +941,8 @@ FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr& t /// trim feature FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint); + // arc created by trim of circle is always correct, that means that it is not inversed + anArcFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(false); theModifiedAttributes.insert( std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()), @@ -780,7 +986,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( @@ -816,8 +1022,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 } } @@ -865,6 +1073,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()) @@ -880,10 +1092,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) @@ -902,15 +1117,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); @@ -921,12 +1137,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 aFeature->data()->blockSendAttributeUpdated(aWasBlocked); + #ifdef DEBUG_TRIM + std::cout << "---- createArcFeature:end ---" << std::endl; + #endif + return aFeature; } @@ -1010,13 +1230,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; @@ -1031,7 +1248,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(); @@ -1039,8 +1256,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( @@ -1052,52 +1269,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; }