]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Coincidence to rectangle macro feature: 1. Get point of sub-feature to set coincidenc...
authornds <nds@opencascade.com>
Mon, 29 Feb 2016 15:19:07 +0000 (18:19 +0300)
committernds <nds@opencascade.com>
Mon, 29 Feb 2016 15:19:28 +0000 (18:19 +0300)
src/ModuleBase/ModuleBase_OperationFeature.cpp
src/PartSet/PartSet_Tools.cpp
src/PartSet/PartSet_Tools.h
src/PartSet/PartSet_WidgetPoint2d.cpp

index 6dcda35c2427655c54b216ec5c47338cbc385f31..cee58efb0a8fb83405f8d6148ad3acbb3ba6694d 100755 (executable)
@@ -36,7 +36,7 @@
 
 // the define to check the activated object as a sub-feature by argument of
 // the operation feature. E.g. rectangle feature(operation), line(in argument) to be not activated
-//#define DEBUG_DO_NOT_ACTIVATE_SUB_FEATURE
+#define DEBUG_DO_NOT_ACTIVATE_SUB_FEATURE
 #ifdef DEBUG_DO_NOT_ACTIVATE_SUB_FEATURE
 #include <ModelAPI_AttributeRefList.h>
 #endif
@@ -195,23 +195,27 @@ bool ModuleBase_OperationFeature::hasObject(ObjectPtr theObj) const
         return true;
     }
 #ifdef DEBUG_DO_NOT_ACTIVATE_SUB_FEATURE
-    FeaturePtr anObjectFeature = ModelAPI_Feature::feature(theObj);
-    std::list<AttributePtr> anAttributes = aFeature->data()->attributes(
-                                            ModelAPI_AttributeRefList::typeId());
-    std::list<AttributePtr>::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end();
-    bool aFoundObject = false;
-    for (; anIt != aLast && !aFoundObject; anIt++) {
-      std::shared_ptr<ModelAPI_AttributeRefList> aCurSelList =
-                                       std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIt);
-      for (int i = 0, aNb = aCurSelList->size(); i < aNb && !aFoundObject; i++) {
-        ObjectPtr anObject = aCurSelList->object(i);
-        FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
-        if (aFeature.get()) {
-          aFoundObject = anObjectFeature == aFeature;
+    if (aFeature->isMacro()) {
+      // macro feature may refers to sub-features, which also should be deactivated when the operation
+      // is active, e.g. rectangle'lines.
+      FeaturePtr anObjectFeature = ModelAPI_Feature::feature(theObj);
+      std::list<AttributePtr> anAttributes = aFeature->data()->attributes(
+                                              ModelAPI_AttributeRefList::typeId());
+      std::list<AttributePtr>::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end();
+      bool aFoundObject = false;
+      for (; anIt != aLast && !aFoundObject; anIt++) {
+        std::shared_ptr<ModelAPI_AttributeRefList> aCurSelList =
+                                         std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIt);
+        for (int i = 0, aNb = aCurSelList->size(); i < aNb && !aFoundObject; i++) {
+          ObjectPtr anObject = aCurSelList->object(i);
+          FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
+          if (aFeature.get()) {
+            aFoundObject = anObjectFeature == aFeature;
+          }
         }
       }
+      return aFoundObject;
     }
-    return aFoundObject;
 #endif
   }
   return false;
index a41dc94fdabbd7fc710cdfa7bd27b4b396cf195c..8ee41ea47b8fc070c7f6f46c4b04d8a5dace060e 100755 (executable)
@@ -185,26 +185,6 @@ std::shared_ptr<ModelAPI_Document> PartSet_Tools::document()
   return ModelAPI_Session::get()->moduleDocument();
 }
 
-/*std::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::getFeaturePoint(FeaturePtr theFeature,
-                                                                      double theX, double theY)
-{
-  std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = std::shared_ptr<GeomAPI_Pnt2d>(
-                                                                 new GeomAPI_Pnt2d(theX, theY));
-  std::list<std::shared_ptr<ModelAPI_Attribute> > anAttiributes =
-                                    theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
-  std::list<std::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes.begin(),
-                                                                    aLast = anAttiributes.end();
-  std::shared_ptr<GeomDataAPI_Point2D> aFPoint;
-  for (; anIt != aLast && !aFPoint; anIt++) {
-    std::shared_ptr<GeomDataAPI_Point2D> aCurPoint = std::dynamic_pointer_cast<
-        GeomDataAPI_Point2D>(*anIt);
-    if (aCurPoint && aCurPoint->pnt()->distance(aClickedPoint) < Precision::Confusion())
-      aFPoint = aCurPoint;
-  }
-
-  return aFPoint;
-}*/
-
 void PartSet_Tools::setFeatureValue(FeaturePtr theFeature, double theValue,
                                     const std::string& theAttribute)
 {
@@ -308,14 +288,73 @@ void PartSet_Tools::createConstraint(CompositeFeaturePtr theSketch,
 }*/
 
 
+std::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::findFirstEqualPointInArgumentFeatures(
+                  const FeaturePtr& theFeature, const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+{
+  std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint;
+
+  // may be feature is not updated yet, execute is not performed and references features
+  // are not created. Case: rectangle macro feature
+  ModuleBase_ModelWidget::updateObject(theFeature);
+
+  std::list<AttributePtr> anAttributes = theFeature->data()->attributes(
+                                          ModelAPI_AttributeRefList::typeId());
+  std::list<AttributePtr>::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end();
+  for (; anIt != aLast && !aFeaturePoint.get(); anIt++) {
+    std::shared_ptr<ModelAPI_AttributeRefList> aCurSelList =
+                                      std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIt);
+    for (int i = 0, aNb = aCurSelList->size(); i < aNb && !aFeaturePoint.get(); i++) {
+      ObjectPtr anObject = aCurSelList->object(i);
+      FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
+      if (aFeature.get())
+        aFeaturePoint = PartSet_Tools::findFirstEqualPoint(aFeature, thePoint);
+    }
+  }
+  return aFeaturePoint;
+}
+
+std::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::findFirstEqualPoint(const FeaturePtr& theFeature,
+                                                      const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+{
+  std::shared_ptr<GeomDataAPI_Point2D> aFPoint;
+
+  // find the given point in the feature attributes
+  std::list<std::shared_ptr<ModelAPI_Attribute> > anAttiributes =
+                                    theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
+  std::list<std::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes.begin(),
+      aLast = anAttiributes.end();
+  for (; anIt != aLast && !aFPoint; anIt++) {
+    std::shared_ptr<GeomDataAPI_Point2D> aCurPoint = 
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt);
+    if (aCurPoint && (aCurPoint->pnt()->distance(thePoint) < Precision::Confusion())) {
+      aFPoint = aCurPoint;
+      break;
+    }
+  }
+  return aFPoint;
+}
+
 void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr theFeature,
                                    const std::string& theAttribute, double theClickedX,
                                    double theClickedY)
 {
+  if (!theFeature.get())
+    return;
+
+  std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = std::shared_ptr<GeomAPI_Pnt2d>(
+      new GeomAPI_Pnt2d(theClickedX, theClickedY));
+
   // find a feature point by the selection mode
-  //std::shared_ptr<GeomDataAPI_Point2D> aPoint = featurePoint(theMode);
-  std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint = std::dynamic_pointer_cast<
-      GeomDataAPI_Point2D>(theFeature->data()->attribute(theAttribute));
+  std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint;
+  if (theFeature->isMacro()) {
+    // the macro feature will be removed after the operation is stopped, so we need to build
+    // coicidence to possible sub-features
+    aFeaturePoint = PartSet_Tools::findFirstEqualPointInArgumentFeatures(theFeature, aClickedPoint);
+  }
+  else {
+    aFeaturePoint = std::dynamic_pointer_cast<
+        GeomDataAPI_Point2D>(theFeature->data()->attribute(theAttribute));
+  }
   if (!aFeaturePoint)
     return;
 
@@ -328,25 +367,12 @@ void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr the
   std::list<ObjectPtr> aFeatures = aRefList->list();
   std::list<ObjectPtr>::const_iterator anIt = aFeatures.begin(), aLast = aFeatures.end();
   std::list<std::shared_ptr<ModelAPI_Attribute> > anAttiributes;
-  std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = std::shared_ptr<GeomAPI_Pnt2d>(
-      new GeomAPI_Pnt2d(theClickedX, theClickedY));
   for (; anIt != aLast; anIt++) {
     FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anIt);
     if (!aFeature.get() || theFeature == aFeature)
       continue;
-    // find the given point in the feature attributes
-    anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
-    std::list<std::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes.begin(),
-        aLast = anAttiributes.end();
-    std::shared_ptr<GeomDataAPI_Point2D> aFPoint;
-    for (; anIt != aLast && !aFPoint; anIt++) {
-      std::shared_ptr<GeomDataAPI_Point2D> aCurPoint = 
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt);
-      if (aCurPoint && (aCurPoint->pnt()->distance(aClickedPoint) < Precision::Confusion())) {
-        aFPoint = aCurPoint;
-        break;
-      }
-    }
+    std::shared_ptr<GeomDataAPI_Point2D> aFPoint = PartSet_Tools::findFirstEqualPoint(aFeature,
+                                                                                aClickedPoint);
     if (aFPoint)
       PartSet_Tools::createConstraint(theSketch, aFPoint, aFeaturePoint);
   }
index 1b35d9068e9a39d226a06954cae465c250b7c1b0..752951dbd73c1962238324d13252c084310d4cf1 100755 (executable)
@@ -111,6 +111,20 @@ public:
                                std::shared_ptr<GeomDataAPI_Point2D> thePoint1,
                                std::shared_ptr<GeomDataAPI_Point2D> thePoint2);
 
+  /// Finds in the feature's sub-features first Point2D attribute with the given point coordinates
+  /// \param theFeature a feature with sub-feature attributes
+  /// \param thePoint a point to provided searched coordinates
+  /// \return found point or null
+  static std::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::findFirstEqualPointInArgumentFeatures(
+                  const FeaturePtr& theFeature, const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
+
+  /// Finds in the feature first Point2D attribute with the given point coordinates
+  /// \param theFeature a feature with point attributes
+  /// \param thePoint a point to provided searched coordinates
+  /// \return found point or null
+  static std::shared_ptr<GeomDataAPI_Point2D> findFirstEqualPoint(const FeaturePtr& theFeature,
+                                       const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
+
   /// Creates constrains of the current 
   /// \param theSketch a sketch feature
   /// \param theFeature a source feature
index 50ac3e3eeeaed11c766c01c4c12263aa7b89f56f..03cd49c320831309573364b0a1d39589d9c05808 100644 (file)
@@ -386,16 +386,33 @@ bool PartSet_WidgetPoint2D::getPoint2d(const Handle(V3d_View)& theView,
 
 void PartSet_WidgetPoint2D::setConstraintWith(const ObjectPtr& theObject)
 {
+  std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint;
+  if (feature()->isMacro()) {
+    AttributePtr aThisAttr = feature()->data()->attribute(attributeID());
+    std::shared_ptr<GeomDataAPI_Point2D> anAttrPoint =
+                               std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aThisAttr);
+    if (anAttrPoint.get()) {
+      // the macro feature will be removed after the operation is stopped, so we need to build
+      // coicidence to possible sub-features
+      aFeaturePoint = PartSet_Tools::findFirstEqualPointInArgumentFeatures(feature(),
+                                                                 anAttrPoint->pnt());
+    }
+  }
+  else {
+    AttributePtr aThisAttr = feature()->data()->attribute(attributeID());
+    aFeaturePoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aThisAttr);
+  }
+  if (!aFeaturePoint.get())
+    return;
+
   // Create point-edge coincedence
   FeaturePtr aFeature = mySketch->addFeature(SketchPlugin_ConstraintCoincidence::ID());
   std::shared_ptr<ModelAPI_Data> aData = aFeature->data();
 
   std::shared_ptr<ModelAPI_AttributeRefAttr> aRef1 = std::dynamic_pointer_cast<
       ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
-  AttributePtr aThisAttr = feature()->data()->attribute(attributeID());
-  std::shared_ptr<GeomDataAPI_Point2D> aThisPoint = 
-    std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aThisAttr);
-  aRef1->setAttr(aThisPoint);
+
+  aRef1->setAttr(aFeaturePoint);
 
   std::shared_ptr<ModelAPI_AttributeRefAttr> aRef2 = std::dynamic_pointer_cast<
       ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
@@ -410,8 +427,6 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous
   if (theEvent->button() != Qt::LeftButton)
     return;
 
-  bool isCoincidenceEnabled = MyFeaturesForCoincedence.contains(myFeature->getKind().c_str());
-
   ModuleBase_ISelection* aSelection = myWorkshop->selection();
   Handle(V3d_View) aView = theWnd->v3dView();
   // TODO: This fragment doesn't work because bug in OCC Viewer. It can be used after fixing.
@@ -429,13 +444,11 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous
       aSPFeature = std::dynamic_pointer_cast<SketchPlugin_Feature>(aSelectedFeature);
       if ((!aSPFeature && !aShape.IsNull()) ||
           (aSPFeature.get() && aSPFeature->isExternal())) {
-          ResultPtr aFixedObject;
-          if (isCoincidenceEnabled) {
-          anExternal = true;
-          aFixedObject = PartSet_Tools::findFixedObjectByExternal(aShape, aObject, mySketch);
-          if (!aFixedObject.get())
-            aFixedObject = PartSet_Tools::createFixedObjectByExternal(aShape, aObject, mySketch);
-        }
+        ResultPtr aFixedObject;
+        anExternal = true;
+        aFixedObject = PartSet_Tools::findFixedObjectByExternal(aShape, aObject, mySketch);
+        if (!aFixedObject.get())
+          aFixedObject = PartSet_Tools::createFixedObjectByExternal(aShape, aObject, mySketch);
         double aX, aY;
         if (getPoint2d(aView, aShape, aX, aY) && isFeatureContainsPoint(myFeature, aX, aY)) {
           // do not create a constraint to the point, which already used by the feature
@@ -487,20 +500,19 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous
         bool isAuxiliaryFeature = false;
         if (getPoint2d(aView, aShape, aX, aY)) {
           setPoint(aX, aY);
+          feature()->execute();
           PartSet_Tools::setConstraints(mySketch, feature(), attributeID(), aX, aY);
         }
         else if (aShape.ShapeType() == TopAbs_EDGE) {
-          if (isCoincidenceEnabled) {
-            setConstraintWith(aObject);
-            setValueState(Stored); // in case of edge selection, Apply state should also be updated
-
-            FeaturePtr anObjectFeature = ModelAPI_Feature::feature(aObject);
-            std::string anAuxiliaryAttribute = SketchPlugin_SketchEntity::AUXILIARY_ID();
-            AttributeBooleanPtr anAuxiliaryAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
-                                              anObjectFeature->data()->attribute(anAuxiliaryAttribute));
-            if (anAuxiliaryAttr.get())
-              isAuxiliaryFeature = anAuxiliaryAttr->value();
-          }
+          setConstraintWith(aObject);
+          setValueState(Stored); // in case of edge selection, Apply state should also be updated
+
+          FeaturePtr anObjectFeature = ModelAPI_Feature::feature(aObject);
+          std::string anAuxiliaryAttribute = SketchPlugin_SketchEntity::AUXILIARY_ID();
+          AttributeBooleanPtr anAuxiliaryAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
+                                            anObjectFeature->data()->attribute(anAuxiliaryAttribute));
+          if (anAuxiliaryAttr.get())
+            isAuxiliaryFeature = anAuxiliaryAttr->value();
         }
         // it is important to perform updateObject() in order to the current value is 
         // processed by Sketch Solver. Test case: line is created from a previous point