]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #1330
authordbv <dbv@opencascade.com>
Mon, 29 Feb 2016 05:56:11 +0000 (08:56 +0300)
committerdbv <dbv@opencascade.com>
Mon, 29 Feb 2016 05:56:11 +0000 (08:56 +0300)
Fixes for selecting points for fillet with Shift

src/SketchPlugin/SketchPlugin_ConstraintFillet.cpp
src/SketchPlugin/SketchPlugin_ConstraintFillet.h
src/SketchPlugin/SketchPlugin_Validators.cpp

index 70aa19310f3f6d733416e98cd5edc54ad1d37180..b66cbc0c3ba20a40e42cbf15164ad81ac7ba9d57 100644 (file)
@@ -62,7 +62,8 @@ static std::set<FeaturePtr> getCoincides(const FeaturePtr& theConstraintCoincide
 SketchPlugin_ConstraintFillet::SketchPlugin_ConstraintFillet()
 : myListOfPointsChangedInCode(false),
   myRadiusChangedByUser(false),
-  myRadiusChangedInCode(true)
+  myRadiusChangedInCode(false),
+  myRadiusInitialized(false)
 {
 }
 
@@ -88,19 +89,60 @@ void SketchPlugin_ConstraintFillet::execute()
   double aFilletRadius = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
     aData->attribute(SketchPlugin_Constraint::VALUE()))->value();
 
-  // Check the fillet result edges is not initialized yet.
-  bool anIsNeedNewObjects = myResultEdges.size() == 0;
-
   // 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);
 
-  std::list<FeaturePtr>::iterator aResultEdgesIt = myResultEdges.begin();
-  for(int anIndex = 0; anIndex < aPointsRefList->size(); ++anIndex) {
-    std::shared_ptr<GeomDataAPI_Point2D> aFilletPoint2d =
-      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aPointsRefList->attribute(anIndex));
+  // 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) {
+    AttributePtr aPointAttr = *aPointsIter;
+    std::shared_ptr<GeomDataAPI_Point2D> aFilletPoint2d = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aPointAttr);
     if(!aFilletPoint2d.get()) {
       setError("Error: One of the selected points is empty.");
       return;
@@ -108,12 +150,17 @@ void SketchPlugin_ConstraintFillet::execute()
     std::shared_ptr<GeomAPI_Pnt2d> aFilletPnt2d = aFilletPoint2d->pnt();
 
     // Obtain base lines for fillet.
+    bool anIsNeedNewObjects = true;
+    FilletFeatures aFilletFeatures;
+    std::map<AttributePtr, FilletFeatures>::iterator aPrevPointsIter = myPointFeaturesMap.find(aPointAttr);
+    if(aPrevPointsIter != myPointFeaturesMap.end()) {
+      anIsNeedNewObjects = false;
+      aFilletFeatures = aPrevPointsIter->second;
+    }
     FeaturePtr aBaseEdgeA, aBaseEdgeB;
-    if(myBaseEdges.size() > (unsigned int)(anIndex * 2)) {
-      std::list<FeaturePtr>::iterator anIter = myBaseEdges.begin();
-      std::advance(anIter, anIndex * 2);
-      aBaseEdgeA = *anIter++;
-      aBaseEdgeB = *anIter;
+    if(!anIsNeedNewObjects) {
+      aBaseEdgeA = aFilletFeatures.baseEdges.front();
+      aBaseEdgeB = aFilletFeatures.baseEdges.back();
     } else {
       // Obtain constraint coincidence for the fillet point.
       FeaturePtr aConstraintCoincidence;
@@ -158,6 +205,9 @@ void SketchPlugin_ConstraintFillet::execute()
       std::set<FeaturePtr>::iterator aLinesIt = aCoincides.begin();
       aBaseEdgeA = *aLinesIt++;
       aBaseEdgeB = *aLinesIt;
+
+      aFilletFeatures.baseEdges.push_back(aBaseEdgeA);
+      aFilletFeatures.baseEdges.push_back(aBaseEdgeB);
     }
 
     if(!aBaseEdgeA.get() || !aBaseEdgeB.get()) {
@@ -167,16 +217,21 @@ void SketchPlugin_ConstraintFillet::execute()
 
     // Create new edges and arc if needed.
     FeaturePtr aResultEdgeA, aResultEdgeB, aResultArc;
-    if(anIsNeedNewObjects) {
+    if(!anIsNeedNewObjects) {
+      // Obtain features from the list.
+      std::list<FeaturePtr>::iterator aResultEdgesIt = aFilletFeatures.resultEdges.begin();
+      aResultEdgeA = *aResultEdgesIt++;
+      aResultEdgeB = *aResultEdgesIt++;
+      aResultArc = *aResultEdgesIt;
+    } else {
       // Copy edges and create arc.
       aResultEdgeA = SketchPlugin_Sketch::addUniqueNamedCopiedFeature(aBaseEdgeA, sketch());
       aResultEdgeB = SketchPlugin_Sketch::addUniqueNamedCopiedFeature(aBaseEdgeB, sketch());
       aResultArc = sketch()->addFeature(SketchPlugin_Arc::ID());
-    } else {
-      // Obtain features from the list.
-      aResultEdgeA = *aResultEdgesIt++;
-      aResultEdgeB = *aResultEdgesIt++;
-      aResultArc = *aResultEdgesIt++;
+
+      aFilletFeatures.resultEdges.push_back(aResultEdgeA);
+      aFilletFeatures.resultEdges.push_back(aResultEdgeB);
+      aFilletFeatures.resultEdges.push_back(aResultArc);
     }
 
     // Calculate arc attributes
@@ -196,7 +251,6 @@ void SketchPlugin_ConstraintFillet::execute()
         aStartAttr = SketchPlugin_Arc::START_ID();
         aEndAttr = SketchPlugin_Arc::END_ID();
       } else { // wrong argument
-        myResultEdges.clear();
         setError("Error: One of the points has wrong coincide feature");
         return;
       }
@@ -282,15 +336,6 @@ void SketchPlugin_ConstraintFillet::execute()
     aResultArc->execute();
 
     if(anIsNeedNewObjects) {
-      // attach new arc to the list
-      myResultEdges.push_back(aResultEdgeA);
-      myResultEdges.push_back(aResultEdgeB);
-      myResultEdges.push_back(aResultArc);
-
-      myProducedFeatures.push_back(aResultEdgeA);
-      myProducedFeatures.push_back(aResultEdgeB);
-      myProducedFeatures.push_back(aResultArc);
-
       // Create list of additional constraints:
       // 1. Coincidence of boundary points of features (copied lines/arcs) and fillet arc
       // 1.1. coincidence
@@ -305,7 +350,7 @@ void SketchPlugin_ConstraintFillet::execute()
       aRefAttr->setAttr(aResultFeatures[aFeatInd]->attribute(aFeatAttributes[anAttrInd]));
       recalculateAttributes(aResultArc, SketchPlugin_Arc::START_ID(), aResultFeatures[aFeatInd], aFeatAttributes[anAttrInd]);
       aConstraint->execute();
-      myProducedFeatures.push_back(aConstraint);
+      aFilletFeatures.resultConstraints.push_back(aConstraint);
       ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent);
       // 1.2. coincidence
       aConstraint = sketch()->addFeature(SketchPlugin_ConstraintCoincidence::ID());
@@ -319,7 +364,7 @@ void SketchPlugin_ConstraintFillet::execute()
       aRefAttr->setAttr(aResultFeatures[aFeatInd]->attribute(aFeatAttributes[anAttrInd]));
       recalculateAttributes(aResultArc, SketchPlugin_Arc::END_ID(), aResultFeatures[aFeatInd], aFeatAttributes[anAttrInd]);
       aConstraint->execute();
-      myProducedFeatures.push_back(aConstraint);
+      aFilletFeatures.resultConstraints.push_back(aConstraint);
       ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent);
       // 2. Fillet arc radius
       //aConstraint = sketch()->addFeature(SketchPlugin_ConstraintRadius::ID());
@@ -345,7 +390,7 @@ void SketchPlugin_ConstraintFillet::execute()
         bool isArc = aResultFeatures[i]->getKind() == SketchPlugin_Arc::ID();
         aRefAttr->setObject(isArc ? aResultFeatures[i]->lastResult() : aResultFeatures[i]->firstResult());
         aConstraint->execute();
-        myProducedFeatures.push_back(aConstraint);
+        aFilletFeatures.resultConstraints.push_back(aConstraint);
         ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent);
       }
       // 4. Coincidence of free boundaries of base and copied features
@@ -358,7 +403,7 @@ void SketchPlugin_ConstraintFillet::execute()
         aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
             aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
         aRefAttr->setAttr(aResultFeatures[i]->attribute(aFeatAttributes[anAttrInd]));
-        myProducedFeatures.push_back(aConstraint);
+        aFilletFeatures.resultConstraints.push_back(aConstraint);
       }
       // 4.1. Additional tangency constraints when the fillet is based on arcs.
       //      It is used to verify the created arc will be placed on a source.
@@ -373,7 +418,7 @@ void SketchPlugin_ConstraintFillet::execute()
             aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
         aRefAttr->setObject(aResultFeatures[i]->lastResult());
         aConstraint->execute();
-        myProducedFeatures.push_back(aConstraint);
+        aFilletFeatures.resultConstraints.push_back(aConstraint);
         ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent);
       }
       // 5. Tangent points should be placed on the base features
@@ -386,17 +431,18 @@ void SketchPlugin_ConstraintFillet::execute()
         aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
             aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
         aRefAttr->setObject(aBaseFeatures[i]->lastResult());
-        myProducedFeatures.push_back(aConstraint);
+        aFilletFeatures.resultConstraints.push_back(aConstraint);
       }
       // make base features auxiliary
       aBaseEdgeA->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(true);
       aBaseEdgeB->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(true);
 
-      myBaseEdges.push_back(aBaseEdgeA);
-      myBaseEdges.push_back(aBaseEdgeB);
       // exchange the naming IDs of newly created and old line that become auxiliary
       sketch()->exchangeIDs(aBaseEdgeA, aResultEdgeA);
       sketch()->exchangeIDs(aBaseEdgeB, aResultEdgeB);
+
+      // store point and features in the map.
+      myPointFeaturesMap[aPointAttr] = aFilletFeatures;
     } else {
       // Update radius value
       int aNbSubs = sketch()->numberOfSubs();
@@ -433,36 +479,60 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
       return;
     }
 
-    // Clear the list of fillet entities.
-    myResultEdges.clear();
-
-    // Clear the list of base points.
-    myBasePoints.clear();
-
-    // Clear auxiliary flag on initial objects.
-    std::list<FeaturePtr>::const_iterator aFeatureIt;
-    for(aFeatureIt = myBaseEdges.cbegin(); aFeatureIt != myBaseEdges.cend(); ++aFeatureIt) {
-      (*aFeatureIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(false);
-    }
-    myBaseEdges.clear();
-
-    // Remove all produced objects and constraints.
-    DocumentPtr aDoc = sketch()->document();
-    for(aFeatureIt = myProducedFeatures.cbegin(); aFeatureIt != myProducedFeatures.cend(); ++aFeatureIt) {
-      aDoc->removeFeature(*aFeatureIt);
-    }
-    myProducedFeatures.clear();
+    // Clear list of new points.
+    myNewPoints.clear();
 
     // Get list of points for fillets and current radius.
     AttributeRefAttrListPtr aRefListOfFilletPoints = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(
       data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
-    AttributeDoublePtr aRadiusAttribute = real(SketchPlugin_Constraint::VALUE());
+    AttributeDoublePtr aRadiusAttribute = real(VALUE());
+    double aPrevRadius = aRadiusAttribute->value();
     int aListSize = aRefListOfFilletPoints->size();
-    if(aListSize == 0 && !myRadiusChangedByUser) {
-      // If list is empty just reset radius to zero (if it was not changed by user).
-      myRadiusChangedInCode = true;
-      aRadiusAttribute->setValue(0);
-      myRadiusChangedInCode = false;
+    if(aListSize == 0) {
+      // If list is empty reset radius to zero (if it was not changed by user).
+      if(!myRadiusChangedByUser) {
+        myRadiusChangedInCode = true;
+        aRadiusAttribute->setValue(0);
+        myRadiusChangedInCode = false;
+      }
+
+      // Clear auxiliary flag on initial objects.
+      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();
+            ++aFeatureIt) {
+          (*aFeatureIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(false);
+        }
+        ++aPointsIter;
+      }
+
+      // And remove all produced features.
+      DocumentPtr aDoc = sketch()->document();
+      for(std::map<AttributePtr, FilletFeatures>::iterator aPointsIter = myPointFeaturesMap.begin();
+          aPointsIter != myPointFeaturesMap.end();) {
+        // 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++);
+      }
+
       return;
     }
 
@@ -470,18 +540,26 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
     double aMinimumRadius = 0;
     std::list<std::pair<ObjectPtr, AttributePtr>> aSelectedPointsList = aRefListOfFilletPoints->list();
     std::list<std::pair<ObjectPtr, AttributePtr>>::iterator anIter = aSelectedPointsList.begin();
-    std::set<AttributePtr> aBasePoints;
+    std::set<AttributePtr> aPointsToSkeep;
     for(int anIndex = 0; anIndex < aListSize; anIndex++, anIter++) {
       AttributePtr aFilletPointAttr = (*anIter).second;
       std::shared_ptr<GeomDataAPI_Point2D> aFilletPoint2D =
         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aFilletPointAttr);
       if(!aFilletPoint2D.get()) {
+        myNewPoints.clear();
         setError("Error: One of the selected points is invalid.");
         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(aBasePoints.find(aFilletPointAttr) != aBasePoints.end()) {
+      if(aPointsToSkeep.find(aFilletPointAttr) != aPointsToSkeep.end()) {
         myListOfPointsChangedInCode = true;
         aRefListOfFilletPoints->remove(aFilletPointAttr);
         myListOfPointsChangedInCode = false;
@@ -517,6 +595,7 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
       }
 
       if(!aConstraintCoincidence.get()) {
+        myNewPoints.clear();
         setError("Error: No coincident edges at one of the selected points.");
         return;
       }
@@ -542,20 +621,20 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
           std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
             std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr);
           if(aPoint2D.get() && aFilletPnt2d->isEqual(aPoint2D->pnt())) {
-            aBasePoints.insert(anAttr);
+            aPointsToSkeep.insert(anAttr);
           }
         } else if(aFeatureKind == SketchPlugin_Line::ID()) {
           AttributePtr anAttrStart = (*anIt)->attribute(SketchPlugin_Line::START_ID());
           std::shared_ptr<GeomDataAPI_Point2D> aPointStart2D =
             std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttrStart);
           if(aPointStart2D.get() && aFilletPnt2d->isEqual(aPointStart2D->pnt())) {
-            aBasePoints.insert(anAttrStart);
+            aPointsToSkeep.insert(anAttrStart);
           }
           AttributePtr anAttrEnd = (*anIt)->attribute(SketchPlugin_Line::END_ID());
           std::shared_ptr<GeomDataAPI_Point2D> aPointEnd2D =
             std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttrEnd);
           if(aPointEnd2D.get() && aFilletPnt2d->isEqual(aPointEnd2D->pnt())) {
-            aBasePoints.insert(anAttrEnd);
+            aPointsToSkeep.insert(anAttrEnd);
           }
           aNewSetOfCoincides.insert(*anIt);
         } else if(aFeatureKind == SketchPlugin_Arc::ID() ) {
@@ -563,13 +642,13 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
           std::shared_ptr<GeomDataAPI_Point2D> aPointStart2D =
             std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttrStart);
           if(aPointStart2D.get() && aFilletPnt2d->isEqual(aPointStart2D->pnt())) {
-            aBasePoints.insert(anAttrStart);
+            aPointsToSkeep.insert(anAttrStart);
           }
           AttributePtr anAttrEnd = (*anIt)->attribute(SketchPlugin_Arc::END_ID());
           std::shared_ptr<GeomDataAPI_Point2D> aPointEnd2D =
             std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttrEnd);
           if(aPointEnd2D.get() && aFilletPnt2d->isEqual(aPointEnd2D->pnt())) {
-            aBasePoints.insert(anAttrEnd);
+            aPointsToSkeep.insert(anAttrEnd);
           }
           aNewSetOfCoincides.insert(*anIt);
         }
@@ -588,13 +667,14 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
       }
 
       if(aCoincides.size() != 2) {
+        myNewPoints.clear();
         setError("Error: One of the selected points does not have two suitable edges for fillet.");
         return;
       }
 
       // Store base point for fillet.
-      aBasePoints.insert(aFilletPointAttr);
-      myBasePoints.push_back(aFilletPointAttr);
+      aPointsToSkeep.insert(aFilletPointAttr);
+      myNewPoints.insert(aFilletPointAttr);
 
       // Get base lines for fillet.
       FeaturePtr anOldFeatureA, anOldFeatureB;
@@ -626,9 +706,12 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
     }
 
   } else if(theID == SketchPlugin_Constraint::VALUE()) {
-    if(!myRadiusChangedInCode) {
+    if(myRadiusInitialized && !myRadiusChangedInCode) {
       myRadiusChangedByUser = true;
     }
+    if(!myRadiusInitialized) {
+      myRadiusInitialized = true;
+    }
   }
 }
 
index 6a1dfa8f09f14b13914dc1d81c594f5eebaa8573..dd3edf3cc6008bb83bfb2cf90f942130d5eeb930 100644 (file)
 class SketchPlugin_ConstraintFillet : public SketchPlugin_ConstraintBase
 {
  public:
+   struct FilletFeatures {
+    std::list<FeaturePtr> baseEdges; ///< list of objects the fillet is based
+    std::list<FeaturePtr> resultEdges; ///< list of result edges
+    std::list<FeaturePtr> resultConstraints; ///< list of constraints provided by the fillet
+   };
+
   /// Fillet constraint kind
   inline static const std::string& ID()
   {
@@ -58,23 +64,18 @@ class SketchPlugin_ConstraintFillet : public SketchPlugin_ConstraintBase
   /// \brief Use plugin manager for features creation
   SketchPlugin_ConstraintFillet();
 
-  /// \return base points list;
-  SKETCHPLUGIN_EXPORT const std::list<AttributePtr> basePoints() const {return myBasePoints;};
-
-  /// \return base edges list;
-  SKETCHPLUGIN_EXPORT const std::list<FeaturePtr> baseEdges() const {return myBaseEdges;};
-
-  /// \return result edges list;
-  SKETCHPLUGIN_EXPORT const std::list<FeaturePtr> resultEdges() const {return myResultEdges;};
+  /// \return map of base points and features;
+  SKETCHPLUGIN_EXPORT const std::map<AttributePtr, FilletFeatures> pointsFeaturesMap() const {
+    return myPointFeaturesMap;
+  };
 
 private:
-  std::list<AttributePtr> myBasePoints; ///< list of base points
-  std::list<FeaturePtr> myBaseEdges;      ///< list of objects the fillet is based
-  std::list<FeaturePtr> myResultEdges;      ///< list of result edges
-  std::list<FeaturePtr> myProducedFeatures; ///< list of constraints provided by the fillet
+  std::set<AttributePtr> myNewPoints; ///< set of new points
+  std::map<AttributePtr, FilletFeatures> myPointFeaturesMap; ///< map of point and features for fillet
   bool myListOfPointsChangedInCode; ///< flag to track that list of points changed in code
   bool myRadiusChangedByUser; ///< flag to track that radius changed by user
   bool myRadiusChangedInCode; ///< flag to track that radius changed in code
+  bool myRadiusInitialized; /// < flag to track that radius initialized
 };
 
 #endif
index 0da828c4c60c60f716fe48c5abd8cf9f18c9a8d0..431cc0347c0c88618acda48017462a26eb90f91d 100755 (executable)
@@ -468,8 +468,26 @@ bool SketchPlugin_FilletVertexValidator::isValid(const AttributePtr& theAttribut
     return false;
   }
 
-  std::list<AttributePtr> aBasePointsList = aFilletFeature->basePoints();
-  std::list<FeaturePtr> aResultEdgesList = aFilletFeature->resultEdges();
+  std::map<AttributePtr, SketchPlugin_ConstraintFillet::FilletFeatures> aPointsFeaturesMap = aFilletFeature->pointsFeaturesMap();
+  std::set<AttributePtr> aSetOfPointsOnResultEdges;
+  for(std::map<AttributePtr, SketchPlugin_ConstraintFillet::FilletFeatures>::iterator aPointsIter = aPointsFeaturesMap.begin();
+      aPointsIter != aPointsFeaturesMap.end();
+      ++aPointsIter) {
+    const SketchPlugin_ConstraintFillet::FilletFeatures& aFeatures = aPointsIter->second;
+    const std::list<FeaturePtr>& aResultEdges = aFeatures.resultEdges;
+    for(std::list<FeaturePtr>::const_iterator aResultIter = aResultEdges.cbegin();
+        aResultIter != aResultEdges.cend();
+        ++aResultIter) {
+      FeaturePtr aResultFeature = *aResultIter;
+      if(aResultFeature->getKind() == SketchPlugin_Line::ID()) {
+        aSetOfPointsOnResultEdges.insert(aResultFeature->attribute(SketchPlugin_Line::START_ID()));
+        aSetOfPointsOnResultEdges.insert(aResultFeature->attribute(SketchPlugin_Line::END_ID()));
+      } else if(aResultFeature->getKind() == SketchPlugin_Arc::ID()) {
+        aSetOfPointsOnResultEdges.insert(aResultFeature->attribute(SketchPlugin_Arc::START_ID()));
+        aSetOfPointsOnResultEdges.insert(aResultFeature->attribute(SketchPlugin_Arc::END_ID()));
+      }
+    }
+  }
 
   std::list<std::pair<ObjectPtr, AttributePtr>> aPointsList = aPointsRefList->list();
   for(std::list<std::pair<ObjectPtr, AttributePtr>>::const_iterator aPointsIt = aPointsList.cbegin(); aPointsIt != aPointsList.cend(); aPointsIt++) {
@@ -479,29 +497,15 @@ bool SketchPlugin_FilletVertexValidator::isValid(const AttributePtr& theAttribut
 
     // If we alredy have some result then:
     // - if it is the same point all ok, just skip it
-    // - if it is point on the fillet arc then it is not valid
-    if(!aBasePointsList.empty()) {
-      if(std::find(aBasePointsList.begin(), aBasePointsList.end(), aPointAttribute) != aBasePointsList.end()) {
+    // - if it is point on the fillet result edge then it is not valid
+    if(!aPointsFeaturesMap.empty()) {
+      if(aPointsFeaturesMap.find(aPointAttribute) != aPointsFeaturesMap.end()) {
         continue;
       }
 
-      // Check that selected point not on the one of the result fillet arc.
-      std::list<FeaturePtr>::iterator aResultEdgesIt = aResultEdgesList.begin();
-      for(unsigned int anIndex = 0; anIndex < aBasePointsList.size(); anIndex++) {
-        if(aResultEdgesList.size() > 0) {
-          FeaturePtr aResultArc;
-          std::advance(aResultEdgesIt, 2);
-          aResultArc = *aResultEdgesIt++;
-          AttributePtr anArcStart = aResultArc->attribute(SketchPlugin_Arc::START_ID());
-          AttributePtr anArcEnd = aResultArc->attribute(SketchPlugin_Arc::END_ID());
-          std::shared_ptr<GeomAPI_Pnt2d> anArcStartPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anArcStart)->pnt();
-          std::shared_ptr<GeomAPI_Pnt2d> anArcEndPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anArcEnd)->pnt();
-          double aDistSelectedArcStart = aSelectedPnt->distance(anArcStartPnt);
-          double aDistSelectedArcEnd = aSelectedPnt->distance(anArcEndPnt);
-          if(aDistSelectedArcStart < tolerance || aDistSelectedArcEnd < tolerance) {
-            return false;
-          }
-        }
+      // Check that selected point not on the one of the fillet result edge.
+      if(aSetOfPointsOnResultEdges.find(aPointAttribute) != aSetOfPointsOnResultEdges.end()) {
+        return false;
       }
     }