Salome HOME
Issue #1664 In the Sketcher, add the function Split a segment - correction for arc...
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_ConstraintFillet.cpp
index 0576e0654bf3ce3ec316b9a4219bcb4d0eae4dc5..0481c4a14a0f48e193f4ac149edd4563b978d87f 100644 (file)
@@ -13,7 +13,6 @@
 #include <GeomAPI_XY.h>
 #include <GeomDataAPI_Point2D.h>
 #include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_AttributeRefAttrList.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Events.h>
@@ -95,49 +94,6 @@ void SketchPlugin_ConstraintFillet::execute()
   if (isUpdateFlushed)
     Events_Loop::loop()->setFlushed(anUpdateEvent, false);
 
-  // Remove unused items.
-  for(std::map<AttributePtr, FilletFeatures>::iterator aPointsIter = myPointFeaturesMap.begin();
-      aPointsIter != myPointFeaturesMap.end();) {
-    if(myNewPoints.find(aPointsIter->first) == myNewPoints.end()) {
-      // Clear auxiliary flag on initial objects.
-      const FilletFeatures& aFilletFeatures = aPointsIter->second;
-      std::list<FeaturePtr>::const_iterator aFeatureIt;
-      for(aFeatureIt = aFilletFeatures.baseEdges.cbegin();
-          aFeatureIt != aFilletFeatures.baseEdges.cend();
-          ++aFeatureIt) {
-        (*aFeatureIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(false);
-      }
-    }
-    ++aPointsIter;
-  }
-
-  DocumentPtr aDoc = sketch()->document();
-  for(std::map<AttributePtr, FilletFeatures>::iterator aPointsIter = myPointFeaturesMap.begin();
-      aPointsIter != myPointFeaturesMap.end();) {
-    if(myNewPoints.find(aPointsIter->first) != myNewPoints.end()) {
-      ++aPointsIter; // keep this point and result features.
-    } else {
-      // Remove all produced constraints.
-      const FilletFeatures& aFilletFeatures = aPointsIter->second;
-      std::list<FeaturePtr>::const_iterator aFeatureIt;
-      for(aFeatureIt = aFilletFeatures.resultConstraints.cbegin();
-          aFeatureIt != aFilletFeatures.resultConstraints.cend();
-          ++aFeatureIt) {
-        aDoc->removeFeature(*aFeatureIt);
-      }
-
-      // Remove all result edges.
-      for(aFeatureIt = aFilletFeatures.resultEdges.cbegin();
-          aFeatureIt != aFilletFeatures.resultEdges.cend();
-          ++aFeatureIt) {
-        aDoc->removeFeature(*aFeatureIt);
-      }
-
-      // Remove point from map.
-      myPointFeaturesMap.erase(aPointsIter++);
-    }
-  }
-
   for(std::set<AttributePtr>::iterator aPointsIter = myNewPoints.begin();
       aPointsIter != myNewPoints.end();
       ++aPointsIter) {
@@ -159,8 +115,8 @@ void SketchPlugin_ConstraintFillet::execute()
     }
     FeaturePtr aBaseEdgeA, aBaseEdgeB;
     if(!anIsNeedNewObjects) {
-      aBaseEdgeA = aFilletFeatures.baseEdges.front();
-      aBaseEdgeB = aFilletFeatures.baseEdges.back();
+      aBaseEdgeA = aFilletFeatures.baseEdgesState.front().first;
+      aBaseEdgeB = aFilletFeatures.baseEdgesState.back().first;
     } else {
       // Obtain constraint coincidence for the fillet point.
       FeaturePtr aConstraintCoincidence;
@@ -206,8 +162,10 @@ void SketchPlugin_ConstraintFillet::execute()
       aBaseEdgeA = *aLinesIt++;
       aBaseEdgeB = *aLinesIt;
 
-      aFilletFeatures.baseEdges.push_back(aBaseEdgeA);
-      aFilletFeatures.baseEdges.push_back(aBaseEdgeB);
+      std::pair<FeaturePtr, bool> aBasePairA = std::make_pair(aBaseEdgeA, aBaseEdgeA->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value());
+      std::pair<FeaturePtr, bool> aBasePairB = std::make_pair(aBaseEdgeB, aBaseEdgeB->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value());
+      aFilletFeatures.baseEdgesState.push_back(aBasePairA);
+      aFilletFeatures.baseEdgesState.push_back(aBasePairB);
     }
 
     if(!aBaseEdgeA.get() || !aBaseEdgeB.get()) {
@@ -226,7 +184,9 @@ void SketchPlugin_ConstraintFillet::execute()
     } else {
       // Copy edges and create arc.
       aResultEdgeA = SketchPlugin_Sketch::addUniqueNamedCopiedFeature(aBaseEdgeA, sketch());
+      aResultEdgeA->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(false);
       aResultEdgeB = SketchPlugin_Sketch::addUniqueNamedCopiedFeature(aBaseEdgeB, sketch());
+      aResultEdgeB->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(false);
       aResultArc = sketch()->addFeature(SketchPlugin_Arc::ID());
 
       aFilletFeatures.resultEdges.push_back(aResultEdgeA);
@@ -313,7 +273,7 @@ void SketchPlugin_ConstraintFillet::execute()
     aResultEdgeB->execute();
     // 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
-    //aResultArc->data()->blockSendAttributeUpdated(true);
+    aResultArc->data()->blockSendAttributeUpdated(true);
     std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       aResultArc->attribute(SketchPlugin_Arc::CENTER_ID()))->setValue(aCenter->x(), aCenter->y());
     if(isReversed) {
@@ -332,7 +292,7 @@ void SketchPlugin_ConstraintFillet::execute()
     }
     aStartPoint->setValue(aTangentPntA->x(), aTangentPntA->y());
     aEndPoint->setValue(aTangentPntB->x(), aTangentPntB->y());
-    //aResultArc->data()->blockSendAttributeUpdated(false);
+    aResultArc->data()->blockSendAttributeUpdated(false);
     aResultArc->execute();
 
     if(anIsNeedNewObjects) {
@@ -479,6 +439,9 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
       return;
     }
 
+    // Clear results.
+    clearResults();
+
     // Clear list of new points.
     myNewPoints.clear();
 
@@ -486,18 +449,12 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
     AttributeRefAttrListPtr aRefListOfFilletPoints = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(
       data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
     AttributeDoublePtr aRadiusAttribute = real(VALUE());
-    double aPrevRadius = aRadiusAttribute->value();
     int aListSize = aRefListOfFilletPoints->size();
-    if(aListSize == 0) {
+    if(aListSize == 0 && !myRadiusChangedByUser) {
       // If list is empty reset radius to zero (if it was not changed by user).
-      if(!myRadiusChangedByUser) {
-        myRadiusChangedInCode = true;
-        aRadiusAttribute->setValue(0);
-        myRadiusChangedInCode = false;
-      }
-
-      clearResults();
-
+      myRadiusChangedInCode = true;
+      aRadiusAttribute->setValue(0);
+      myRadiusChangedInCode = false;
       return;
     }
 
@@ -516,13 +473,6 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
         return;
       }
 
-      // If point was previously selected, skip it.
-      if(myPointFeaturesMap.find(aFilletPointAttr) != myPointFeaturesMap.end()) {
-        myNewPoints.insert(aFilletPointAttr);
-        aMinimumRadius = aPrevRadius;
-        continue;
-      }
-
       // If point or coincident point is already in list remove it from attribute.
       if(aPointsToSkeep.find(aFilletPointAttr) != aPointsToSkeep.end()) {
         myListOfPointsChangedInCode = true;
@@ -603,6 +553,13 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
           }
           aNewSetOfCoincides.insert(*anIt);
         } else if(aFeatureKind == SketchPlugin_Arc::ID() ) {
+          AttributePtr anAttrCenter = (*anIt)->attribute(SketchPlugin_Arc::CENTER_ID());
+          std::shared_ptr<GeomDataAPI_Point2D> aPointCenter2D =
+            std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttrCenter);
+          if(aPointCenter2D.get() && aFilletPnt2d->isEqual(aPointCenter2D->pnt())) {
+            aPointsToSkeep.insert(anAttrCenter);
+            continue;
+          }
           AttributePtr anAttrStart = (*anIt)->attribute(SketchPlugin_Arc::START_ID());
           std::shared_ptr<GeomDataAPI_Point2D> aPointStart2D =
             std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttrStart);
@@ -663,10 +620,6 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
       }
     }
 
-    if(abs(aPrevRadius - aMinimumRadius) > tolerance) {
-      clearResults(); // if radius changed clear all results;
-    }
-
     // Set new default radius if it was not changed by user.
     if(!myRadiusChangedByUser) {
       myRadiusChangedInCode = true;
@@ -705,11 +658,11 @@ void SketchPlugin_ConstraintFillet::clearResults()
   for(std::map<AttributePtr, FilletFeatures>::iterator aPointsIter = myPointFeaturesMap.begin();
       aPointsIter != myPointFeaturesMap.end();) {
     const FilletFeatures& aFilletFeatures = aPointsIter->second;
-    std::list<FeaturePtr>::const_iterator aFeatureIt;
-    for(aFeatureIt = aFilletFeatures.baseEdges.cbegin();
-        aFeatureIt != aFilletFeatures.baseEdges.cend();
+    std::list<std::pair<FeaturePtr, bool>>::const_iterator aFeatureIt;
+    for(aFeatureIt = aFilletFeatures.baseEdgesState.cbegin();
+        aFeatureIt != aFilletFeatures.baseEdgesState.cend();
         ++aFeatureIt) {
-      (*aFeatureIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(false);
+      aFeatureIt->first->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(aFeatureIt->second);
     }
     ++aPointsIter;
   }
@@ -1085,6 +1038,8 @@ std::set<FeaturePtr> getCoincides(const FeaturePtr& theConstraintCoincidence)
 {
   std::set<FeaturePtr> aCoincides;
 
+  std::shared_ptr<GeomAPI_Pnt2d> aFilletPnt = SketchPlugin_Tools::getCoincidencePoint(theConstraintCoincidence);
+
   SketchPlugin_Tools::findCoincidences(theConstraintCoincidence,
                                        SketchPlugin_ConstraintCoincidence::ENTITY_A(),
                                        aCoincides);
@@ -1095,8 +1050,15 @@ std::set<FeaturePtr> getCoincides(const FeaturePtr& theConstraintCoincidence)
   // Remove points from set of coincides.
   std::set<FeaturePtr> aNewSetOfCoincides;
   for(std::set<FeaturePtr>::iterator anIt = aCoincides.begin(); anIt != aCoincides.end(); ++anIt) {
-    if((*anIt)->getKind() == SketchPlugin_Line::ID() ||
-        (*anIt)->getKind() == SketchPlugin_Arc::ID() ) {
+    if((*anIt)->getKind() == SketchPlugin_Line::ID()) {
+      aNewSetOfCoincides.insert(*anIt);
+    } else if((*anIt)->getKind() == SketchPlugin_Arc::ID()) {
+      AttributePtr anAttrCenter = (*anIt)->attribute(SketchPlugin_Arc::CENTER_ID());
+      std::shared_ptr<GeomDataAPI_Point2D> aPointCenter2D =
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttrCenter);
+      if(aPointCenter2D.get() && aFilletPnt->isEqual(aPointCenter2D->pnt())) {
+        continue;
+      }
       aNewSetOfCoincides.insert(*anIt);
     }
   }