]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Fillet creation fixes
authordbv <dbv@opencascade.com>
Tue, 3 Nov 2015 11:22:51 +0000 (14:22 +0300)
committerdbv <dbv@opencascade.com>
Tue, 3 Nov 2015 11:22:51 +0000 (14:22 +0300)
src/SketchPlugin/SketchPlugin_ConstraintFillet.cpp
src/SketchPlugin/SketchPlugin_Tools.cpp
src/SketchPlugin/SketchPlugin_Tools.h
src/SketchPlugin/SketchPlugin_Validators.cpp

index 25d2daf2af090750355b50942a450f4bafe543ed..e094b12a76f7028e5fc073bffab02ba9bb149cd6 100644 (file)
@@ -57,9 +57,12 @@ void SketchPlugin_ConstraintFillet::initAttributes()
   data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId());
   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
   data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::typeId());
+  // This attribute used to store base edges
+  data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::typeId());
   data()->addAttribute(PREVIOUS_VALUE, ModelAPI_AttributeDouble::typeId());
   // initialize attribute not applicable for user
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_B());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_C());
   data()->attribute(PREVIOUS_VALUE)->setInitialized();
   std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(data()->attribute(PREVIOUS_VALUE))->setValue(0.0);
 }
@@ -89,62 +92,82 @@ void SketchPlugin_ConstraintFillet::execute()
       aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
   bool needNewObjects = aRefListOfFillet->size() == 0;
 
+  AttributeRefListPtr aRefListOfBaseLines = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+      aData->attribute(SketchPlugin_Constraint::ENTITY_C()));
+
   // Obtain base features
-  AttributePtr anAttrBase = aBaseA->attr();
-  const std::set<AttributePtr>& aRefsList = anAttrBase->owner()->data()->refsToMe();
-  std::set<AttributePtr>::const_iterator aIt;
-  FeaturePtr aCoincident;
-  for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
-    std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
-    FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
-    if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
-      AttributeRefAttrPtr anAttrRefA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-        aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_A()));
-      AttributeRefAttrPtr anAttrRefB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-        aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_B()));
-      if(anAttrRefA.get() && !anAttrRefA->isObject()) {
-        AttributePtr anAttrA = anAttrRefA->attr();
-        if(anAttrBase == anAttrA) {
-          aCoincident = aConstrFeature;
-          break;
+  FeaturePtr anOldFeatureA, anOldFeatureB;
+  if(needNewObjects) {
+    AttributePtr anAttrBase = aBaseA->attr();
+    const std::set<AttributePtr>& aRefsList = anAttrBase->owner()->data()->refsToMe();
+    std::set<AttributePtr>::const_iterator aIt;
+    FeaturePtr aCoincident;
+    for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
+      std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
+      FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
+      if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
+        AttributeRefAttrPtr anAttrRefA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+          aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_A()));
+        AttributeRefAttrPtr anAttrRefB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+          aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_B()));
+        if(anAttrRefA.get() && !anAttrRefA->isObject()) {
+          AttributePtr anAttrA = anAttrRefA->attr();
+          if(anAttrBase == anAttrA) {
+            aCoincident = aConstrFeature;
+            break;
+          }
+        }
+        if(anAttrRefA.get() && !anAttrRefB->isObject()) {
+          AttributePtr anAttrB = anAttrRefB->attr();
+          if(anAttrBase == anAttrB) {
+            aCoincident = aConstrFeature;
+            break;
+          }
         }
       }
-      if(anAttrRefA.get() && !anAttrRefB->isObject()) {
-        AttributePtr anAttrB = anAttrRefB->attr();
-        if(anAttrBase == anAttrB) {
-          aCoincident = aConstrFeature;
-          break;
+    }
+
+    if(!aCoincident.get()) {
+      setError("No coincident edges at selected vertex");
+      return;
+    }
+
+    std::set<FeaturePtr> aCoinsideLines;
+    SketchPlugin_Tools::findCoincidences(aCoincident,
+                                         SketchPlugin_ConstraintCoincidence::ENTITY_A(),
+                                         aCoinsideLines);
+    SketchPlugin_Tools::findCoincidences(aCoincident,
+                                         SketchPlugin_ConstraintCoincidence::ENTITY_B(),
+                                         aCoinsideLines);
+
+    // Remove auxilary lines
+    if(aCoinsideLines.size() > 2) {
+      std::set<FeaturePtr> aNewLines;
+      for(std::set<FeaturePtr>::iterator anIt = aCoinsideLines.begin(); anIt != aCoinsideLines.end(); ++anIt) {
+        if(!(*anIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value()) {
+          aNewLines.insert(*anIt);
         }
       }
+      aCoinsideLines = aNewLines;
     }
-  }
 
-  if(!aCoincident.get()) {
-    setError("No coincident edges at selected vertex");
-    return;
-  }
 
-  std::set<FeaturePtr> aCoinsideLines;
-  SketchPlugin_Tools::findCoincidences(aCoincident,
-                                       SketchPlugin_ConstraintCoincidence::ENTITY_A(),
-                                       aCoinsideLines);
-  SketchPlugin_Tools::findCoincidences(aCoincident,
-                                       SketchPlugin_ConstraintCoincidence::ENTITY_B(),
-                                       aCoinsideLines);
-  if(aCoinsideLines.size() != 2) {
-    setError("At selected vertex should be two coincident lines");
-    return;
-  }
+    if(aCoinsideLines.size() != 2) {
+      setError("At selected vertex should be two coincident lines");
+      return;
+    }
 
-  std::set<FeaturePtr>::iterator aLinesIt = aCoinsideLines.begin();
-  FeaturePtr anOldFeatureA = *aLinesIt;
-  if(!anOldFeatureA) {
-    setError("One of the edges is empty");
-    return;
+    std::set<FeaturePtr>::iterator aLinesIt = aCoinsideLines.begin();
+    anOldFeatureA = *aLinesIt++;
+    anOldFeatureB = *aLinesIt;
+  } else {
+    std::list<ObjectPtr> aNewFeatList = aRefListOfBaseLines->list();
+    std::list<ObjectPtr>::iterator aFeatIt = aNewFeatList.begin();
+    anOldFeatureA = ModelAPI_Feature::feature(*aFeatIt++);
+    anOldFeatureB = ModelAPI_Feature::feature(*aFeatIt++);
   }
-  aLinesIt++;
-  FeaturePtr anOldFeatureB = *aLinesIt;
-  if(!anOldFeatureB) {
+
+  if(!anOldFeatureA.get() || !anOldFeatureB.get()) {
     setError("One of the edges is empty");
     return;
   }
@@ -187,6 +210,7 @@ void SketchPlugin_ConstraintFillet::execute()
       aRefListOfFillet->remove(aNewFeatureA);
       aRefListOfFillet->remove(aNewFeatureB);
       aRefListOfFillet->remove(aNewArc);
+      aRefListOfBaseLines->clear();
       return;
     }
     aFeatAttributes[2*i] = aStartAttr;
@@ -276,6 +300,10 @@ void SketchPlugin_ConstraintFillet::execute()
     aRefListOfFillet->append(aNewFeatureB->lastResult());
     aRefListOfFillet->append(aNewArc->lastResult());
 
+    // attach base lines to the list
+    aRefListOfBaseLines->append(anOldFeatureA);
+    aRefListOfBaseLines->append(anOldFeatureB);
+
     myProducedFeatures.push_back(aNewFeatureA);
     myProducedFeatures.push_back(aNewFeatureB);
     myProducedFeatures.push_back(aNewArc);
index 297649e623deb03cdd26d518dad8e5788fe2fc3c..82c5a3f93986c9c07d3857e797771ec59f7cdc52 100644 (file)
@@ -9,8 +9,9 @@
 #include <GeomDataAPI_Point.h>
 #include <GeomDataAPI_Point2D.h>
 #include <ModelAPI_AttributeDouble.h>
-#include <SketchPlugin_ConstraintCoincidence.h>
 #include <SketcherPrs_Tools.h>
+#include <SketchPlugin_ConstraintCoincidence.h>
+#include <SketchPlugin_SketchEntity.h>
 
 namespace SketchPlugin_Tools {
 
@@ -60,7 +61,7 @@ void clearExpressions(FeaturePtr theFeature)
   }
 }
 
-std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(FeaturePtr theStartCoin)
+std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(const FeaturePtr theStartCoin)
 {
   std::shared_ptr<GeomAPI_Pnt2d> aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), 
                                                                     SketchPlugin_Constraint::ENTITY_A());
@@ -69,26 +70,29 @@ std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(FeaturePtr theStartCoin)
   return aPnt;
 }
 
-void findCoincidences(FeaturePtr theStartCoin,
-                      std::string theAttr,
+void findCoincidences(const FeaturePtr theStartCoin,
+                      const std::string& theAttr,
                       std::set<FeaturePtr>& theList)
 {
   AttributeRefAttrPtr aPnt = theStartCoin->refattr(theAttr);
-  if (!aPnt) return;
+  if(!aPnt) {
+    return;
+  }
   FeaturePtr aObj = ModelAPI_Feature::feature(aPnt->object());
-  if (theList.find(aObj) == theList.end()) {
+  if(theList.find(aObj) == theList.end()) {
     std::shared_ptr<GeomAPI_Pnt2d> aOrig = getCoincidencePoint(theStartCoin);
-    if (aOrig.get() == NULL)
+    if(aOrig.get() == NULL) {
       return;
+    }
     theList.insert(aObj);
     const std::set<AttributePtr>& aRefsList = aObj->data()->refsToMe();
     std::set<AttributePtr>::const_iterator aIt;
-    for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
+    for(aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
       std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
       FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
-      if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { 
+      if(aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
         std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincidencePoint(aConstrFeature);
-        if (aPnt.get() && aOrig->isEqual(aPnt)) {
+        if(aPnt.get() && aOrig->isEqual(aPnt)) {
           findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(), theList);
           findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(), theList);
         }
index 9123cab7a29d450b0cd8550fd411839574f4ef24..9637b5d09929120b118aed70ff96f9b048ae0614 100644 (file)
@@ -18,14 +18,14 @@ void clearExpressions(FeaturePtr theFeature);
 
 /// \return coincidence point
 /// \param[in] theStartCoin coincidence feature
-std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(FeaturePtr theStartCoin);
+std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(const FeaturePtr theStartCoin);
 
 /// Finds lines coincident at point
 /// \param[in] theStartCoin coincidence feature
 /// \param[in] theAttr attribute name
 /// \param[out] theList list of lines
-void findCoincidences(FeaturePtr theStartCoin,
-                      std::string theAttr,
+void findCoincidences(const FeaturePtr theStartCoin,
+                      const std::string& theAttr,
                       std::set<FeaturePtr>& theList);
 
 }; // namespace SketchPlugin_Tools
index 9c8dd5809a2bc112ab80c535cc17ba3365fec1eb..ee7121371bf94d53d0ac811250dfd9527adcd6a1 100755 (executable)
@@ -408,10 +408,18 @@ bool SketchPlugin_FilletVertexValidator::isValid(const AttributePtr& theAttribut
   }
 
   AttributeRefAttrPtr aBase = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
-  if (aBase->isObject()) {
+  if(aBase->isObject()) {
     return false;
   }
 
+  // If we alredy have some result then all ok
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+  AttributePtr aBaseLinesAttribute = aFeature->attribute(SketchPlugin_Constraint::ENTITY_C());
+  AttributeRefListPtr aRefListOfBaseLines = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(aBaseLinesAttribute);
+  if(aRefListOfBaseLines->list().size() == 2) {
+    return true;
+  }
+
   AttributePtr anAttrBase = aBase->attr();
   const std::set<AttributePtr>& aRefsList = anAttrBase->owner()->data()->refsToMe();
   std::set<AttributePtr>::const_iterator aIt;
@@ -452,9 +460,45 @@ bool SketchPlugin_FilletVertexValidator::isValid(const AttributePtr& theAttribut
   SketchPlugin_Tools::findCoincidences(aCoincident,
                                        SketchPlugin_ConstraintCoincidence::ENTITY_B(),
                                        aCoinsideLines);
+  if(aCoinsideLines.size() < 2) {
+    return false;
+  }
+
+  // Remove auxilary lines
+  if(aCoinsideLines.size() > 2) {
+    std::set<FeaturePtr> aNewLines;
+    for(std::set<FeaturePtr>::iterator anIt = aCoinsideLines.begin(); anIt != aCoinsideLines.end(); ++anIt) {
+      if(!(*anIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value()) {
+        aNewLines.insert(*anIt);
+      }
+    }
+    aCoinsideLines = aNewLines;
+  }
+
   if(aCoinsideLines.size() != 2) {
     return false;
   }
 
+  // Check that lines not collinear
+  std::set<FeaturePtr>::iterator anIt = aCoinsideLines.begin();
+  FeaturePtr aFirstFeature = *anIt++;
+  FeaturePtr aSecondFeature = *anIt;
+  if(aFirstFeature->getKind() == SketchPlugin_Line::ID() && aSecondFeature->getKind() == SketchPlugin_Line::ID()) {
+    std::string aStartAttr = SketchPlugin_Line::START_ID();
+    std::string anEndAttr = SketchPlugin_Line::END_ID();
+    std::shared_ptr<GeomAPI_Pnt2d> aFirstStartPnt, aFirstEndPnt, aSecondStartPnt, aSecondEndPnt;
+    aFirstStartPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aFirstFeature->attribute(aStartAttr))->pnt();
+    aFirstEndPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aFirstFeature->attribute(anEndAttr))->pnt();
+    aSecondStartPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aSecondFeature->attribute(aStartAttr))->pnt();
+    aSecondEndPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aSecondFeature->attribute(anEndAttr))->pnt();
+    double aCheck1 = abs((aFirstEndPnt->x() - aFirstStartPnt->x()) * (aSecondStartPnt->y() - aFirstStartPnt->y()) -
+      (aSecondStartPnt->x() - aFirstStartPnt->x()) * (aFirstEndPnt->y() - aFirstStartPnt->y()));
+    double aCheck2 = abs((aFirstEndPnt->x() - aFirstStartPnt->x()) * (aSecondEndPnt->y() - aFirstStartPnt->y()) -
+      (aSecondEndPnt->x() - aFirstStartPnt->x()) * (aFirstEndPnt->y() - aFirstStartPnt->y()));
+    if(aCheck1 < 1.e-7 && aCheck2 < 1.e-7) {
+      return false;
+    }
+  }
+
   return true;
 }