Salome HOME
Issue #711 Fatal error when Create extrusion cut
authornds <natalia.donis@opencascade.com>
Fri, 10 Jul 2015 14:52:10 +0000 (17:52 +0300)
committernds <natalia.donis@opencascade.com>
Fri, 10 Jul 2015 14:57:22 +0000 (17:57 +0300)
Chash by mpv: in sketch of Extrusion cut try to move over external edge, result is crash. It is caused by recursive delete of referenced features to the external edge. The extrusion cut was in the list of deleted features.

src/FeaturesPlugin/FeaturesPlugin_ExtrusionBoolean.cpp [changed mode: 0644->0755]
src/FeaturesPlugin/extrusioncut_widget.xml
src/FeaturesPlugin/extrusionfuse_widget.xml
src/FeaturesPlugin/revolutioncut_widget.xml
src/FeaturesPlugin/revolutionfuse_widget.xml
src/XGUI/XGUI_Tools.cpp
src/XGUI/XGUI_Tools.h
src/XGUI/XGUI_Workshop.cpp

index 0b9f14a6e459e432e4934c1aca8857c203b44056..9d749ae27d0329efa2cd611d73b87026d34c8723 100755 (executable)
@@ -73,4 +73,5 @@
     type_choice="Solids"
     concealment="true">
   </multi_selector>
+  <validator id="GeomValidators_ZeroOffset" parameters="CreationMethod,BySizes,to_size,from_size,to_object,to_offset,from_object,from_offset"/>
 </source>
index 70579aa19ea833942b602962dec4ddc360dc8d92..380dd7692a35aa43fc0aabad40df141e0409c4af 100644 (file)
@@ -73,4 +73,5 @@
     type_choice="Solids"
     concealment="true">
   </multi_selector>
+  <validator id="GeomValidators_ZeroOffset" parameters="CreationMethod,BySizes,to_size,from_size,to_object,to_offset,from_object,from_offset"/>
 </source>
index 93bfdcf066e594ee38aff01e1d410c94d7eb9c17..32218ce9c9757b12965975d85a4226d880f8b8b2 100644 (file)
@@ -81,4 +81,5 @@
     type_choice="Solids"
     concealment="true">
   </multi_selector>
+  <validator id="GeomValidators_ZeroOffset" parameters="CreationMethod,ByAngles,to_angle,from_angle,to_object,to_offset,from_object,from_offset"/>
 </source>
index 6bbcd32705ae9d68389279e4eed432a9b83506ea..599058cb40cd6f5e3d3833c495c40b7c40bb881c 100644 (file)
@@ -81,4 +81,5 @@
     type_choice="Solids"
     concealment="true">
   </multi_selector>
+  <validator id="GeomValidators_ZeroOffset" parameters="CreationMethod,ByAngles,to_angle,from_angle,to_object,to_offset,from_object,from_offset"/>
 </source>
index 47de402703e2f0cc611ff9659b1ac3bca33a5a01..b835629a7e37dbbb877aef8592f488b87741f4e0 100644 (file)
@@ -10,6 +10,7 @@
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Document.h>
 #include <ModelAPI_ResultPart.h>
+#include <ModelAPI_CompositeFeature.h>
 
 #include <GeomAPI_Shape.h>
 
@@ -123,4 +124,119 @@ bool allDocumentsActivated(QString& theNotActivatedNames)
   return anAllPartActivated;
 }
 
+//**************************************************************
+void refsToFeatureInFeatureDocument(const ObjectPtr& theObject, std::set<FeaturePtr>& theRefFeatures)
+{
+  FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+  if (aFeature.get()) {
+    DocumentPtr aFeatureDoc = aFeature->document();
+    // 1. find references in the current document
+    aFeatureDoc->refsToFeature(aFeature, theRefFeatures, false);
+  }
+}
+
+//**************************************************************
+bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
+{
+  bool isSub = false;
+  CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
+  if (aComposite.get()) {
+    isSub = aComposite->isSub(theObject);
+    // the recursive is possible, the parameters are sketch circle and extrusion cut. They are
+    // separated by composite sketch feature
+    if (!isSub) {
+      int aNbSubs = aComposite->numberOfSubs();
+      for (int aSub = 0; aSub < aNbSubs && !isSub; aSub++) {
+        isSub = isSubOfComposite(theObject, aComposite->subFeature(aSub));
+      }
+    }
+  }
+  return isSub;
+}
+
+//**************************************************************
+void refsToFeatureInAllDocuments(const ObjectPtr& theSourceObject, const ObjectPtr& theObject,
+                                 std::set<FeaturePtr>& theRefFeatures)
+{
+  FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+  if (!aFeature.get())
+    return;
+
+  // 1. find references in the current document
+  std::set<FeaturePtr> aRefFeatures;
+  refsToFeatureInFeatureDocument(theObject, aRefFeatures);
+  std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
+                                       aLast = aRefFeatures.end();
+  for (; anIt != aLast; anIt++) {
+    if (!isSubOfComposite(theSourceObject, *anIt))
+      theRefFeatures.insert(*anIt);
+  }
+
+  // 2. find references in all documents if the document of the feature is
+  // "PartSet". Features of this document can be used in all other documents
+  DocumentPtr aFeatureDoc = aFeature->document();
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+  DocumentPtr aModuleDoc = aMgr->moduleDocument();
+  if (aFeatureDoc == aModuleDoc) {
+    // the feature and results of the feature should be found in references
+    std::list<ObjectPtr> aObjects;
+    aObjects.push_back(aFeature);
+    typedef std::list<std::shared_ptr<ModelAPI_Result> > ResultsList;
+    const ResultsList& aResults = aFeature->results();
+    ResultsList::const_iterator aRIter = aResults.begin();
+    for (; aRIter != aResults.cend(); aRIter++) {
+      ResultPtr aRes = *aRIter;
+      if (aRes.get())
+        aObjects.push_back(aRes);
+    }
+    // get all opened documents; found features in the documents;
+    // get a list of objects where a feature refers;
+    // search in these objects the deleted objects.
+    SessionPtr aMgr = ModelAPI_Session::get();
+    std::list<DocumentPtr> anOpenedDocs = aMgr->allOpenedDocuments();
+    std::list<DocumentPtr>::const_iterator anIt = anOpenedDocs.begin(),
+                                            aLast = anOpenedDocs.end();
+    std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
+    for (; anIt != aLast; anIt++) {
+      DocumentPtr aDocument = *anIt;
+      if (aDocument == aFeatureDoc)
+        continue; // this document has been already processed in 1.1
+
+      int aFeaturesCount = aDocument->size(ModelAPI_Feature::group());
+      for (int aId = 0; aId < aFeaturesCount; aId++) {
+        ObjectPtr anObject = aDocument->object(ModelAPI_Feature::group(), aId);
+        FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
+        if (!aFeature.get())
+          continue;
+
+        aRefs.clear();
+        aFeature->data()->referencesToObjects(aRefs);
+        std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRef = aRefs.begin();
+        bool aHasReferenceToObject = false;
+        for(; aRef != aRefs.end() && !aHasReferenceToObject; aRef++) {
+          std::list<ObjectPtr>::iterator aRefObj = aRef->second.begin();
+          for(; aRefObj != aRef->second.end() && !aHasReferenceToObject; aRefObj++) {
+            std::list<ObjectPtr>::const_iterator aObjIt = aObjects.begin();
+            for(; aObjIt != aObjects.end() && !aHasReferenceToObject; aObjIt++) {
+              aHasReferenceToObject = *aObjIt == *aRefObj;
+            }
+          }
+        }
+        if (aHasReferenceToObject && !isSubOfComposite(theSourceObject, aFeature))
+          theRefFeatures.insert(aFeature);
+      }
+    }
+  }
+
+  // Run recursion. It is possible recusive dependency, like the folowing: plane, extrusion uses plane,
+  // axis is built on extrusion. Delete of a plane should check the dependency from the axis also.
+  std::set<FeaturePtr> aRecursiveRefFeatures;
+  std::set<FeaturePtr>::const_iterator aFeatureIt = theRefFeatures.begin();
+  for (; aFeatureIt != theRefFeatures.end(); ++aFeatureIt) {
+    refsToFeatureInAllDocuments(theSourceObject, *aFeatureIt, aRecursiveRefFeatures);
+  } 
+  theRefFeatures.insert(aRecursiveRefFeatures.begin(), aRecursiveRefFeatures.end());
+}
+
 }
index a3fba88c90fdebba52e6216ab9ef44de3cab117c..4869f30377a394826de75d9436a6837e7592972f 100644 (file)
@@ -83,6 +83,38 @@ bool XGUI_EXPORT canRemoveOrRename(QWidget* theParent, const QObjectPtrList& aLi
  \return a boolean value
  */
 bool XGUI_EXPORT allDocumentsActivated(QString& theNotActivatedNames);
+
+/*!
+  Returns a container of referenced feature to the current object in the object document.
+  \param theObject an object, which will be casted to a feature type
+  \param theRefFeatures an output container
+ */
+void XGUI_EXPORT refsToFeatureInFeatureDocument(const ObjectPtr& theObject,
+                                                std::set<FeaturePtr>& theRefFeatures);
+
+/*!
+ Returns true if the object if a sub child of the feature. The feature is casted to the
+ composite one. If it is possible, the sub object check happens. The method is applyed
+ recursively to the feature subs.
+ \param theObject a candidate to be a sub object
+ \param theFeature a candidate to be a composite feature
+ \return a boolean value
+ */
+bool XGUI_EXPORT isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature);
+
+/*!
+ Returns a container of references feature to the source object. The search happens in the object
+ document and in other Part documents if the object belongs to the PartSet. The search is recursive,
+ in other words it is applyed to set of the found objects until it is possible.
+ It do not returns the referenced features to the object if this references is a composite feature
+ which has the object as a sub object.
+ \param theSourceObject an object, which references are searched
+ \param theObject an intermediate recursive object, should be set in the source object
+ \return a boolean value
+ */
+void XGUI_EXPORT refsToFeatureInAllDocuments(const ObjectPtr& theSourceObject,
+                                             const ObjectPtr& theObject,
+                                             std::set<FeaturePtr>& theRefFeatures);
 };
 
 #endif
index f70dcb90399556bfcf6bd02a0097d365e246d0f3..755f4b732eca881ab4ddadceaa0cebbfd64a73b8 100644 (file)
@@ -1086,95 +1086,6 @@ void XGUI_Workshop::moveObjects()
   aMgr->finishOperation();
 }
 
-//**************************************************************
-void refsToFeatureInFeatureDocument(const ObjectPtr& theObject, std::set<FeaturePtr>& theRefFeatures)
-{
-  FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
-  if (aFeature.get()) {
-    DocumentPtr aFeatureDoc = aFeature->document();
-    // 1. find references in the current document
-    aFeatureDoc->refsToFeature(aFeature, theRefFeatures, false);
-  }
-}
-
-//**************************************************************
-void refsToFeatureInAllDocuments(const ObjectPtr& theObject, std::set<FeaturePtr>& theRefFeatures)
-{
-  FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
-  if (!aFeature.get())
-    return;
-
-  // 1. find references in the current document
-  refsToFeatureInFeatureDocument(theObject, theRefFeatures);
-
-
-  // 2. find references in all documents if the document of the feature is
-  // "PartSet". Features of this document can be used in all other documents
-  DocumentPtr aFeatureDoc = aFeature->document();
-
-  SessionPtr aMgr = ModelAPI_Session::get();
-  DocumentPtr aModuleDoc = aMgr->moduleDocument();
-  if (aFeatureDoc == aModuleDoc) {
-    // the feature and results of the feature should be found in references
-    std::list<ObjectPtr> aObjects;
-    aObjects.push_back(aFeature);
-    typedef std::list<std::shared_ptr<ModelAPI_Result> > ResultsList;
-    const ResultsList& aResults = aFeature->results();
-    ResultsList::const_iterator aRIter = aResults.begin();
-    for (; aRIter != aResults.cend(); aRIter++) {
-      ResultPtr aRes = *aRIter;
-      if (aRes.get())
-        aObjects.push_back(aRes);
-    }
-    // get all opened documents; found features in the documents;
-    // get a list of objects where a feature refers;
-    // search in these objects the deleted objects.
-    SessionPtr aMgr = ModelAPI_Session::get();
-    std::list<DocumentPtr> anOpenedDocs = aMgr->allOpenedDocuments();
-    std::list<DocumentPtr>::const_iterator anIt = anOpenedDocs.begin(),
-                                            aLast = anOpenedDocs.end();
-    std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
-    for (; anIt != aLast; anIt++) {
-      DocumentPtr aDocument = *anIt;
-      if (aDocument == aFeatureDoc)
-        continue; // this document has been already processed in 1.1
-
-      int aFeaturesCount = aDocument->size(ModelAPI_Feature::group());
-      for (int aId = 0; aId < aFeaturesCount; aId++) {
-        ObjectPtr anObject = aDocument->object(ModelAPI_Feature::group(), aId);
-        FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
-        if (!aFeature.get())
-          continue;
-
-        aRefs.clear();
-        aFeature->data()->referencesToObjects(aRefs);
-        std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRef = aRefs.begin();
-        bool aHasReferenceToObjetc = false;
-        for(; aRef != aRefs.end() && !aHasReferenceToObjetc; aRef++) {
-          std::list<ObjectPtr>::iterator aRefObj = aRef->second.begin();
-          for(; aRefObj != aRef->second.end() && !aHasReferenceToObjetc; aRefObj++) {
-            std::list<ObjectPtr>::const_iterator aObjIt = aObjects.begin();
-            for(; aObjIt != aObjects.end() && !aHasReferenceToObjetc; aObjIt++) {
-              aHasReferenceToObjetc = *aObjIt == *aRefObj;
-            }
-          }
-        }
-        if (aHasReferenceToObjetc)
-          theRefFeatures.insert(aFeature);
-      }
-    }
-  }
-
-  // Run recursion. It is possible recusive dependency, like the folowing: plane, extrusion uses plane,
-  // axis is built on extrusion. Delete of a plane should check the dependency from the axis also.
-  std::set<FeaturePtr> aRecursiveRefFeatures;
-  std::set<FeaturePtr>::const_iterator aFeatureIt = theRefFeatures.begin();
-  for (; aFeatureIt != theRefFeatures.end(); ++aFeatureIt) {
-    refsToFeatureInAllDocuments(*aFeatureIt, aRecursiveRefFeatures);
-  } 
-  theRefFeatures.insert(aRecursiveRefFeatures.begin(), aRecursiveRefFeatures.end());
-}
-
 //**************************************************************
 bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theList,
                                    const std::set<FeaturePtr>& theIgnoredFeatures,
@@ -1194,7 +1105,7 @@ bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theList,
   // 1. find all referenced features
   std::set<FeaturePtr> aRefFeatures;
   foreach (ObjectPtr aDeletedObj, theList) {
-    refsToFeatureInAllDocuments(aDeletedObj, aRefFeatures);
+    XGUI_Tools::refsToFeatureInAllDocuments(aDeletedObj, aDeletedObj, aRefFeatures);
   }
   // 2. warn about the references remove, break the delete operation if the user chose it
   if (theAskAboutDeleteReferences && !aRefFeatures.empty()) {
@@ -1324,7 +1235,7 @@ bool XGUI_Workshop::canMoveFeature()
     std::set<FeaturePtr> aPlacedFeatures(aFeaturesBetween.begin(), aFeaturesBetween.end());
     // 2. Get all reference features to the selected object in the document 
     std::set<FeaturePtr> aRefFeatures;
-    refsToFeatureInFeatureDocument(aObject, aRefFeatures);
+    XGUI_Tools::refsToFeatureInFeatureDocument(aObject, aRefFeatures);
 
     if (aRefFeatures.empty())
       continue;