From f3420899628d626dcd7f9eba90f11cd75a5dd1a2 Mon Sep 17 00:00:00 2001 From: nds Date: Fri, 10 Jul 2015 12:01:04 +0300 Subject: [PATCH] Issue #711 - Fatal error when Create extrusion cut The problem is ExtrusionCut deletion by moving over external edge. This is not a fix, but a pleminary code correction. --- src/XGUI/XGUI_Workshop.cpp | 141 +++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 67 deletions(-) diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 3f044f918..f70dcb903 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -1087,86 +1087,92 @@ void XGUI_Workshop::moveObjects() } //************************************************************** -std::set refFeatures(const ObjectPtr& theObject, - bool checkAllDocuments = true, - bool useRecursion = false) +void refsToFeatureInFeatureDocument(const ObjectPtr& theObject, std::set& 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& theRefFeatures) { - std::set aRefFeatures; FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); if (!aFeature.get()) - return aRefFeatures; + return; - DocumentPtr aFeatureDoc = aFeature->document(); // 1. find references in the current document - aFeatureDoc->refsToFeature(aFeature, aRefFeatures, false); + 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 - if (checkAllDocuments) { - 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 aObjects; - aObjects.push_back(aFeature); - typedef std::list > 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. + 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 aObjects; + aObjects.push_back(aFeature); + typedef std::list > 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 anOpenedDocs = aMgr->allOpenedDocuments(); - std::list::const_iterator anIt = anOpenedDocs.begin(), - aLast = anOpenedDocs.end(); - std::list > > 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(anObject); - if (!aFeature.get()) - continue; - - aRefs.clear(); - aFeature->data()->referencesToObjects(aRefs); - std::list > >::iterator aRef = aRefs.begin(); - bool aHasReferenceToObjetc = false; - for(; aRef != aRefs.end() && !aHasReferenceToObjetc; aRef++) { - std::list::iterator aRefObj = aRef->second.begin(); - for(; aRefObj != aRef->second.end() && !aHasReferenceToObjetc; aRefObj++) { - std::list::const_iterator aObjIt = aObjects.begin(); - for(; aObjIt != aObjects.end() && !aHasReferenceToObjetc; aObjIt++) { - aHasReferenceToObjetc = *aObjIt == *aRefObj; - } + std::list anOpenedDocs = aMgr->allOpenedDocuments(); + std::list::const_iterator anIt = anOpenedDocs.begin(), + aLast = anOpenedDocs.end(); + std::list > > 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(anObject); + if (!aFeature.get()) + continue; + + aRefs.clear(); + aFeature->data()->referencesToObjects(aRefs); + std::list > >::iterator aRef = aRefs.begin(); + bool aHasReferenceToObjetc = false; + for(; aRef != aRefs.end() && !aHasReferenceToObjetc; aRef++) { + std::list::iterator aRefObj = aRef->second.begin(); + for(; aRefObj != aRef->second.end() && !aHasReferenceToObjetc; aRefObj++) { + std::list::const_iterator aObjIt = aObjects.begin(); + for(; aObjIt != aObjects.end() && !aHasReferenceToObjetc; aObjIt++) { + aHasReferenceToObjetc = *aObjIt == *aRefObj; } } - if (aHasReferenceToObjetc) - aRefFeatures.insert(aFeature); } + if (aHasReferenceToObjetc) + theRefFeatures.insert(aFeature); } } } - // Run recursion - if (useRecursion) { - std::set::const_iterator aFeatureIt = aRefFeatures.begin(); - for (; aFeatureIt != aRefFeatures.end(); ++aFeatureIt) { - std::set aRecursiveRefFeatures = refFeatures(*aFeatureIt, checkAllDocuments, useRecursion); - aRefFeatures.insert(aRecursiveRefFeatures.begin(), aRecursiveRefFeatures.end()); - } - } - - return aRefFeatures; + // 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 aRecursiveRefFeatures; + std::set::const_iterator aFeatureIt = theRefFeatures.begin(); + for (; aFeatureIt != theRefFeatures.end(); ++aFeatureIt) { + refsToFeatureInAllDocuments(*aFeatureIt, aRecursiveRefFeatures); + } + theRefFeatures.insert(aRecursiveRefFeatures.begin(), aRecursiveRefFeatures.end()); } //************************************************************** @@ -1188,8 +1194,7 @@ bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theList, // 1. find all referenced features std::set aRefFeatures; foreach (ObjectPtr aDeletedObj, theList) { - std::set aFeatures = refFeatures(aDeletedObj, true, true); - aRefFeatures.insert(aFeatures.begin(), aFeatures.end()); + refsToFeatureInAllDocuments(aDeletedObj, aRefFeatures); } // 2. warn about the references remove, break the delete operation if the user chose it if (theAskAboutDeleteReferences && !aRefFeatures.empty()) { @@ -1318,7 +1323,9 @@ bool XGUI_Workshop::canMoveFeature() return false; std::set aPlacedFeatures(aFeaturesBetween.begin(), aFeaturesBetween.end()); // 2. Get all reference features to the selected object in the document - std::set aRefFeatures = refFeatures(aObject, false); + std::set aRefFeatures; + refsToFeatureInFeatureDocument(aObject, aRefFeatures); + if (aRefFeatures.empty()) continue; // 3. Find any placed features in all reference features -- 2.39.2