Salome HOME
Issue #2155 Trim removes multi-rotation constraint, undo leads to wrong DOF
authornds <nds@opencascade.com>
Tue, 16 May 2017 09:29:41 +0000 (12:29 +0300)
committernds <nds@opencascade.com>
Tue, 16 May 2017 09:30:00 +0000 (12:30 +0300)
1. remove multi constraints only if references is to selected objects attribute
2. set tangency constraint to the nearest geometry placed feature.

src/PartSet/PartSet_MenuMgr.cpp
src/PartSet/PartSet_Tools.cpp
src/PartSet/PartSet_Tools.h
src/PartSet/PartSet_Validators.cpp
src/PartSet/PartSet_WidgetPoint2d.cpp
src/SketchPlugin/SketchPlugin_Trim.cpp
src/SketchPlugin/SketchPlugin_Trim.h
src/SketcherPrs/SketcherPrs_SymbolPrs.cpp

index c65d42515b6d585fba3d8e195bed6c497166622f..7dfa911111c0c04da53e19fd774fc084952d629f 100644 (file)
@@ -160,10 +160,13 @@ bool PartSet_MenuMgr::addViewerMenu(const QMap<QString, QAction*>& theStdActions
         if (aCoincident.get() != NULL) {
           QList<FeaturePtr> aCoins;
           mySelectedFeature = aCoincident;
+          QList<bool> anIsAttributes;
           PartSet_Tools::findCoincidences(mySelectedFeature, myCoinsideLines, aCoins,
-                                          SketchPlugin_ConstraintCoincidence::ENTITY_A());
+                                          SketchPlugin_ConstraintCoincidence::ENTITY_A(),
+                                          anIsAttributes);
           PartSet_Tools::findCoincidences(mySelectedFeature, myCoinsideLines, aCoins,
-                                          SketchPlugin_ConstraintCoincidence::ENTITY_B());
+                                          SketchPlugin_ConstraintCoincidence::ENTITY_B(),
+                                          anIsAttributes);
           if (myCoinsideLines.size() > 0) {
             aIsDetach = true;
             QMenu* aSubMenu = new QMenu(tr("Detach"), theParent);
@@ -171,7 +174,12 @@ bool PartSet_MenuMgr::addViewerMenu(const QMap<QString, QAction*>& theStdActions
             QAction* aAction;
             int i = 0;
             foreach (FeaturePtr aCoins, myCoinsideLines) {
-              aAction = aSubMenu->addAction(aCoins->data()->name().c_str());
+              QString anItemText = aCoins->data()->name().c_str();
+#ifdef _DEBUG
+              if (anIsAttributes[i])
+                anItemText += " [attribute]";
+#endif
+              aAction = aSubMenu->addAction(anItemText);
               aAction->setData(QVariant(i));
               i++;
             }
index 6550c77672bd2fea6af3d998fe59e09a844e5a8c..51a24fa71dc95a4f57d2b3c1c74d2aa076551062 100755 (executable)
@@ -749,7 +749,7 @@ FeaturePtr PartSet_Tools::findFirstCoincidence(const FeaturePtr& theFeature,
 
 void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList<FeaturePtr>& theList,
                                      QList<FeaturePtr>& theCoincidencies,
-                                     std::string theAttr)
+                                     std::string theAttr, QList<bool>& theIsAttributes)
 {
   std::shared_ptr<GeomAPI_Pnt2d> aOrig = getCoincedencePoint(theStartCoin);
   if (aOrig.get() == NULL)
@@ -764,6 +764,7 @@ void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList<FeaturePtr>&
     if (!theList.contains(aFeature)) {
       theList.append(aFeature);
       theCoincidencies.append(theStartCoin);
+      theIsAttributes.append(true); // point attribute on a feature
       const std::set<AttributePtr>& aRefsList = aFeature->data()->refsToMe();
       std::set<AttributePtr>::const_iterator aIt;
       for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
@@ -774,9 +775,9 @@ void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList<FeaturePtr>&
             std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincedencePoint(aConstrFeature);
             if (aPnt.get() && aOrig->isEqual(aPnt)) {
               findCoincidences(aConstrFeature, theList, theCoincidencies,
-                SketchPlugin_ConstraintCoincidence::ENTITY_A());
+                SketchPlugin_ConstraintCoincidence::ENTITY_A(), theIsAttributes);
               findCoincidences(aConstrFeature, theList, theCoincidencies,
-                SketchPlugin_ConstraintCoincidence::ENTITY_B());
+                SketchPlugin_ConstraintCoincidence::ENTITY_B(), theIsAttributes);
             }
           }
         }
@@ -790,6 +791,7 @@ void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList<FeaturePtr>&
       if (!theList.contains(aFeature))
         theList.append(aFeature);
       theCoincidencies.append(theStartCoin);
+      theIsAttributes.append(false); // point attribute on a feature
 
       const std::set<AttributePtr>& aRefsList = aResult->data()->refsToMe();
       std::set<AttributePtr>::const_iterator aIt;
@@ -801,9 +803,9 @@ void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList<FeaturePtr>&
             std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincedencePoint(aConstrFeature);
             if (aPnt.get() && aOrig->isEqual(aPnt)) {
               findCoincidences(aConstrFeature, theList, theCoincidencies,
-                SketchPlugin_ConstraintCoincidence::ENTITY_A());
+                SketchPlugin_ConstraintCoincidence::ENTITY_A(), theIsAttributes);
               findCoincidences(aConstrFeature, theList, theCoincidencies,
-                SketchPlugin_ConstraintCoincidence::ENTITY_B());
+                SketchPlugin_ConstraintCoincidence::ENTITY_B(), theIsAttributes);
             }
           }
         }
index 1429f9d29cfdfb853b1e38a93487f8ce2202967e..58c928e29f8d148aa9f47aaca8486cbf8af30dab 100755 (executable)
@@ -247,7 +247,7 @@ public:
   */
   static void findCoincidences(FeaturePtr theStartCoin, QList<FeaturePtr>& theList,
                                QList<FeaturePtr>& theCoincidencies,
-                               std::string theAttr);
+                               std::string theAttr, QList<bool>& theIsAttributes);
 
   /**
   * Returns point of a coincedence
index ec18af32f5c84dc765f22f7302d21032084ab2bb..55e2eee2939b80ab1dc5e9c133460f0227cc35cd 100755 (executable)
@@ -639,10 +639,13 @@ bool PartSet_CoincidentAttr::isValid(const AttributePtr& theAttribute,
         AttributePtr aAR = aRAttr->attr();
         if (aAR->id() != SketchPlugin_Arc::CENTER_ID()) // ignore constraint to center of arc
           aCoinList.insert(aConstrFeature);
+          QList<bool> anIsAttributes;
           PartSet_Tools::findCoincidences(aConstrFeature, aCoinsideLines, aCoins,
-                                          SketchPlugin_ConstraintCoincidence::ENTITY_A());
+                                          SketchPlugin_ConstraintCoincidence::ENTITY_A(),
+                                          anIsAttributes);
           PartSet_Tools::findCoincidences(aConstrFeature, aCoinsideLines, aCoins,
-                                          SketchPlugin_ConstraintCoincidence::ENTITY_B());
+                                          SketchPlugin_ConstraintCoincidence::ENTITY_B(),
+                                          anIsAttributes);
       }
     }
     // if there is no coincidence then it is not valid
index 56b1e9852ff693f9ec2861186092d655f31269db..7ecf8dbf8f089eda8ba06ea47bf643619eb40dda 100644 (file)
@@ -837,10 +837,13 @@ bool PartSet_WidgetPoint2D::isOrphanPoint(const FeaturePtr& theFeature,
       if (aCoincidence.get()) {
         QList<FeaturePtr> aCoinsideLines;
         QList<FeaturePtr> aCoins;
+        QList<bool> anIsAttributes;
         PartSet_Tools::findCoincidences(aCoincidence, aCoinsideLines, aCoins,
-                                        SketchPlugin_ConstraintCoincidence::ENTITY_A());
+                                        SketchPlugin_ConstraintCoincidence::ENTITY_A(),
+                                        anIsAttributes);
         PartSet_Tools::findCoincidences(aCoincidence, aCoinsideLines, aCoins,
-                                        SketchPlugin_ConstraintCoincidence::ENTITY_B());
+                                        SketchPlugin_ConstraintCoincidence::ENTITY_B(),
+                                        anIsAttributes);
         QList<FeaturePtr>::const_iterator anIt = aCoinsideLines.begin(),
                                           aLast = aCoinsideLines.end();
         for (; anIt != aLast && anOrphanPoint; anIt++) {
index 747351bb331bb7d2763ace6181c229729e69776e..53a4ad23c56858b5ed08ec5c3fc13206eefe95ab 100644 (file)
@@ -231,10 +231,10 @@ void SketchPlugin_Trim::execute()
 
   std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint2d = convertPoint(aStartShapePoint);
   std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint2d = convertPoint(aLastShapePoint);
-
+  /// find features that should be deleted (e.g. Middle Point) or updated (e.g. Length)
   std::set<FeaturePtr> aFeaturesToDelete, aFeaturesToUpdate;
   getConstraints(aFeaturesToDelete, aFeaturesToUpdate);
-
+  // find references(attributes and features) to the base feature
   std::map<AttributePtr, std::list<AttributePtr> > aBaseRefAttributes;
   std::list<AttributePtr> aRefsToFeature;
   getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature);
@@ -280,12 +280,6 @@ void SketchPlugin_Trim::execute()
   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<AttributePtr, FeaturePtr> aCoincidencesToBaseFeature;
-  //getCoincidencesToObject(aBaseObject, aCoincidencesToBaseFeature);
-
   std::set<AttributePoint2DPtr> aFurtherCoincidences;
   std::set<std::pair<AttributePtr, AttributePtr>> aModifiedAttributes;
   const std::string& aKind = aBaseFeature->getKind();
@@ -370,12 +364,13 @@ void SketchPlugin_Trim::execute()
       anIt != aLast; anIt++) {
     AttributePtr anAttribute = *anIt;
 
-    //if (replaceCoincidenceAttribute(anAttribute, aModifiedAttributes))
-    //  continue;
-
     if (setCoincidenceToAttribute(anAttribute, aFurtherCoincidences))
       continue;
 
+    // move tangency constraint to the nearest feature if possible
+    if (aNewFeature.get() && moveTangency(anAttribute, aNewFeature))
+      continue;
+
     if (aReplacingResult.get()) {
       AttributeRefAttrPtr aRefAttr =
           std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
@@ -552,34 +547,55 @@ bool SketchPlugin_Trim::setCoincidenceToAttribute(const AttributePtr& theAttribu
   return aFoundPoint;
 }
 
-bool SketchPlugin_Trim::replaceCoincidenceAttribute(const AttributePtr& theCoincidenceAttribute,
-                   const std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
+bool SketchPlugin_Trim::moveTangency(const AttributePtr& theAttribute,
+                                     const FeaturePtr& theFeature)
 {
-  FeaturePtr aCoincidenceFeature = ModelAPI_Feature::feature(theCoincidenceAttribute->owner());
-  if (aCoincidenceFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
+  FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
+  if (aFeature->getKind() != SketchPlugin_ConstraintTangent::ID())
     return false;
 
-  AttributeRefAttrPtr aCAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-                         aCoincidenceFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
-  AttributeRefAttrPtr aCAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-                         aCoincidenceFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
-  AttributePtr aCAttrRefA = aCAttrA->attr();
-  AttributePtr aCAttrRefB = aCAttrB->attr();
-
-  bool isProcessed = false;
-  for (std::set<std::pair<AttributePtr, AttributePtr>>::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;
+  AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+                                                                           theAttribute);
+  if (!aRefAttr.get())
+    return false;
+
+  // get shape of tangent object to the current
+  std::string aTangentAttr = SketchPlugin_Constraint::ENTITY_A();
+  if (aRefAttr->id() == SketchPlugin_Constraint::ENTITY_A())
+    aTangentAttr = SketchPlugin_Constraint::ENTITY_B();
+  AttributeRefAttrPtr aTangentRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+                                                     aFeature->attribute(aTangentAttr));
+  FeaturePtr aTangentFeature = ModelAPI_Feature::feature(aTangentRefAttr->object());
+
+  // get shape of the feature of the attribute
+  FeaturePtr anAttributeFeature = ModelAPI_Feature::feature(aRefAttr->object());
+  anAttributeFeature->execute(); // the modified value should be applyed to recompute shape
+  PointToRefsMap aPointToAttributeOrObject;
+  std::list<FeaturePtr> aFeatures;
+  aFeatures.push_back(anAttributeFeature);
+  ModelGeomAlgo_Point2D::getPointsIntersectedShape(aTangentFeature, aFeatures,
+                                                   aPointToAttributeOrObject);
+  if (!aPointToAttributeOrObject.empty())
+    return true; // the attribute feature has a point of intersection, so we do not replace it
+
+  // get shape of the feature
+  aPointToAttributeOrObject.clear();
+  aFeatures.clear();
+  aFeatures.push_back(theFeature);
+  ModelGeomAlgo_Point2D::getPointsIntersectedShape(aTangentFeature, aFeatures,
+                                                   aPointToAttributeOrObject);
+  if (!aPointToAttributeOrObject.empty()) {
+    std::set<ResultPtr> anEdgeShapes;
+    ModelGeomAlgo_Shape::shapesOfType(theFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
+    if (!anEdgeShapes.empty()) {
+      ResultPtr aResult = *anEdgeShapes.begin();
+      if (aResult.get()) {
+        aRefAttr->setObject(aResult);
+        return true; // the attribute feature has a point of intersection, so we do not replace it
+      }
     }
   }
-  return isProcessed;
+  return false;
 }
 
 AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
@@ -699,12 +715,16 @@ void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete
 
   std::set<AttributePtr>::const_iterator aIt;
   for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
-    std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
-    FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
+    std::shared_ptr<ModelAPI_Attribute> anAttr = (*aIt);
+    FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anAttr->owner());
     std::string aRefFeatureKind = aRefFeature->getKind();
-    if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() ||
-        aRefFeatureKind == SketchPlugin_MultiRotation::ID() ||
-        aRefFeatureKind == SketchPlugin_MultiTranslation::ID() ||
+    std::string anAttributeId = anAttr->id();
+    if ((aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() &&
+         anAttributeId == SketchPlugin_ConstraintMirror::MIRROR_LIST_ID()) ||
+        (aRefFeatureKind == SketchPlugin_MultiRotation::ID() &&
+         anAttributeId == SketchPlugin_MultiRotation::ROTATION_LIST_ID()) ||
+        (aRefFeatureKind == SketchPlugin_MultiTranslation::ID() &&
+         anAttributeId == SketchPlugin_MultiTranslation::TRANSLATION_LIST_ID()) ||
         aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID())
       theFeaturesToDelete.insert(aRefFeature);
     else if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID())
@@ -758,44 +778,6 @@ void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature,
   }
 }
 
-/*void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject,
-                   std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature)
-{
-  const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
-  std::set<AttributePtr>::const_iterator aIt;
-  for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
-    std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
-    FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
-    if (aRefFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
-      continue;
-    AttributePtr anAttribute;
-    AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
-                                  (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
-    if (aRefAttr->isObject() && aRefAttr->object() == theObject)
-    {
-      anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
-    }
-    else {
-      AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
-                                    (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
-      if (aRefAttr->isObject() && aRefAttr->object() == theObject)
-        anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
-    }
-    if (!anAttribute.get())
-      continue;
-
-    aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(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<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
                     const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes,
@@ -1403,7 +1385,6 @@ 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<ModelAPI_Data> aData = theSketch->data();
     std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
         aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
index 6371dad6ca496621c36555a29f2d0a8aa5ceb3e8..b6b6599cf0388fe2b4dc2e981644f4da0d5b252f 100644 (file)
@@ -107,9 +107,10 @@ class SketchPlugin_Trim : public SketchPlugin_Feature, public GeomAPI_IPresentab
 private:
   bool setCoincidenceToAttribute(const AttributePtr& theAttribute,
             const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences);
-
-  bool replaceCoincidenceAttribute(const AttributePtr& theCoincidenceAttribute,
-            const std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
+  /// Move tangency constraint to the feature if it is geometrically closely to it
+  /// \param theAttribute an attribute of a tangent constraint feature
+  /// \param theFeature a feature that can be set into the attribute
+  bool moveTangency(const AttributePtr& theAttribute, const FeaturePtr& theFeature);
 
   GeomShapePtr getSubShape(const std::string& theObjectAttributeId,
                            const std::string& thePointAttributeId);
@@ -141,13 +142,6 @@ private:
                         std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
                         std::list<AttributePtr>& theRefsToFeature);
 
-  /// Obtains coincident features to the given object. It is collected in a container
-  /// by the coincident attribute
-  /// \param theObject an investigated object
-  /// \param theCoincidencesToBaseFeature a container of list of referenced attributes
-  //void getCoincidencesToObject(const std::shared_ptr<ModelAPI_Object>& theObject,
-  //                             std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature);
-
   /// Move constraints from attribute of base feature to attribute after modification
   /// \param theBaseRefAttributes container of references to the attributes of base feature
   /// \param theModifiedAttributes container of attributes placed instead of base attributes
index 005bf4cbc6a6b878c861b22d627f174a54b65842..3a498d8277bb16b959ea1f606df6b8e946505fc2 100644 (file)
@@ -331,7 +331,7 @@ void SketcherPrs_SymbolPrs::drawShape(const std::shared_ptr<GeomAPI_Shape>& theS
                                       Quantity_Color theColor) const
 {
   int aColNam = theColor.Name();
-  cout<<"### SketcherPrs_SymbolPrs::drawShape "<<theColor.Name()<<endl;
+  //cout<<"### SketcherPrs_SymbolPrs::drawShape "<<theColor.Name()<<endl;
   Handle(Graphic3d_AspectLine3d) aLineAspect =
     new Graphic3d_AspectLine3d(theColor, Aspect_TOL_SOLID, 2);