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.
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>
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>
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>
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>
#include <ModelAPI_Session.h>
#include <ModelAPI_Document.h>
#include <ModelAPI_ResultPart.h>
+#include <ModelAPI_CompositeFeature.h>
#include <GeomAPI_Shape.h>
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());
+}
+
}
\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
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,
// 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()) {
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;