-// Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+// Copyright (C) 2014-2021 CEA/DEN, EDF R&D
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
#include "Model_Application.h"
#include "Model_Events.h"
#include "Model_Data.h"
+#include "Model_Objects.h"
#include <GeomAPI_Pnt.h>
#include <GeomAPI_Shape.h>
#include <TDF_RelocationTable.hxx>
#include <TDF_DeltaOnAddition.hxx>
#include <TDataStd_UAttribute.hxx>
+#include <TDataStd_ReferenceList.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
/// topology" flag enabled
static const Standard_GUID kIS_GEOMETRICAL_SELECTION("f16987b6-e6c8-435c-99fa-03a7e0b06e83");
+/// GUID for TDataStd_ReferenceList attribute that refers the selection filters feature
+static const Standard_GUID kSELECTION_FILTERS_REF("ea5b1dbf-a740-4a0b-a1b2-3c3c756e691a");
+
+
void Model_AttributeSelectionList::append(
const ObjectPtr& theContext, const std::shared_ptr<GeomAPI_Shape>& theSubShape,
const bool theTemporarily)
}
if (myIsCashed && !theTemporarily) {
- ResultPtr aResContext = std::dynamic_pointer_cast<ModelAPI_Result>(theContext);
- if (aResContext.get())
- myCash[aResContext].push_back(theSubShape);
+ myCash[theContext].push_back(theSubShape);
}
int aNewTag = mySize->Get() + 1;
}
void Model_AttributeSelectionList::append(
- const std::string& theNamingName, const std::string& theType)
+ const std::wstring& theNamingName, const std::string& theType)
{
int aNewTag = mySize->Get() + 1;
TDF_Label aNewLab = mySize->Label().FindChild(aNewTag);
}
void Model_AttributeSelectionList::append(const std::string& theType,
- const std::string& theContextName, const int theIndex)
+ const std::wstring& theContextName, const int theIndex)
{
int aNewTag = mySize->Get() + 1;
TDF_Label aNewLab = mySize->Label().FindChild(aNewTag);
if (!theDestination.FindAttribute(anAttrIter.Value()->ID(), aTargetAttr)) {
// create a new attribute if not yet exists in the destination
aTargetAttr = anAttrIter.Value()->NewEmpty();
+ if (aTargetAttr->ID() != anAttrIter.Value()->ID())
+ aTargetAttr->SetID(anAttrIter.Value()->ID());
theDestination.AddAttribute(aTargetAttr);
}
// for named shape copy exact shapes (in NamedShape Paste method the CopyTool is used)
}
}
+void Model_AttributeSelectionList::copyTo(AttributeSelectionListPtr theTarget) const
+{
+ std::shared_ptr<Model_AttributeSelectionList> aTarget =
+ std::dynamic_pointer_cast<Model_AttributeSelectionList>(theTarget);
+ if (aTarget) {
+ copyAttrs(myLab, aTarget->myLab);
+ aTarget->reinit();
+ }
+}
+
int Model_AttributeSelectionList::size()
{
return mySize->Get();
bool Model_AttributeSelectionList::isInList(const ObjectPtr& theContext,
const std::shared_ptr<GeomAPI_Shape>& theSubShape,
- const bool theTemporarily)
+ const bool /*theTemporarily*/)
{
- ResultPtr aResCont = std::dynamic_pointer_cast<ModelAPI_Result>(theContext);
if (myIsCashed) { // the cashing is active
- if (aResCont.get()) {
- std::map<ResultPtr, std::list<std::shared_ptr<GeomAPI_Shape> > >::iterator aContext =
- myCash.find(aResCont);
+ if (theContext.get()) {
+ std::map<ObjectPtr, std::list<std::shared_ptr<GeomAPI_Shape> > >::iterator aContext =
+ myCash.find(theContext);
if (aContext != myCash.end()) {
// iterate shapes because "isSame" method must be called for each shape
std::list<std::shared_ptr<GeomAPI_Shape> >::iterator aShapes = aContext->second.begin();
for(; aShapes != aContext->second.end(); aShapes++) {
if (!theSubShape.get()) {
- if (!aShapes->get() || (*aShapes)->isSame(aContext->first->shape()))
+ if (!aShapes->get())
+ return true;
+ ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aContext->first);
+ FeaturePtr aFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(aContext->first);
+ if ((aRes.get() && (*aShapes)->isSame(aRes->shape())) || aFeat.get())
return true;
} else {
// we need to call here isSame instead of isEqual to do not check shapes orientation
}
}
// no-cash method
+ bool isFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theContext).get() != NULL;
+ ResultPtr aRes;
+ if (!isFeature)
+ aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theContext);
for(int anIndex = size() - 1; anIndex >= 0; anIndex--) {
AttributeSelectionPtr anAttr = value(anIndex);
if (anAttr.get()) {
- if (anAttr->context() == theContext) { // contexts are equal, so, check that values are also
+ if (isFeature && anAttr->contextFeature() == theContext)
+ return true; // for the feature value should not be compared
+ if (!isFeature && anAttr->context() == theContext) {
+ // contexts are equal, so, check that values are also
std::shared_ptr<GeomAPI_Shape> aValue = anAttr->value();
if (!theSubShape.get()) {
- if (!aValue.get() || (aResCont.get() && aValue->isSame(aResCont->shape()))) {// both null
+ if (!aValue.get() || (aRes.get() && aValue->isSame(aRes->shape())))
return true;
- }
} else {
// we need to call here isSame instead of isEqual to do not check shapes orientation
if (isIn(aValue, theSubShape)) // shapes are equal
}
Model_AttributeSelectionList::Model_AttributeSelectionList(TDF_Label& theLabel)
-: myLab(theLabel)
+: ModelAPI_AttributeSelectionList(), myLab(theLabel)
{
reinit();
}
for(int anIndex = size() - 1; anIndex >= 0; anIndex--) {
AttributeSelectionPtr anAttr = value(anIndex);
if (anAttr.get()) {
- myCash[anAttr->context()].push_back(anAttr->value());
+ myCash[anAttr->contextObject()].push_back(anAttr->value());
}
}
}
myCash.clear(); // empty list as indicator that cash is not used
owner()->data()->sendAttributeUpdated(this);
}
+
+FiltersFeaturePtr Model_AttributeSelectionList::filters() const
+{
+ Handle(TDataStd_ReferenceList) aRef;
+ if (myLab.FindAttribute(kSELECTION_FILTERS_REF, aRef) && !aRef->IsEmpty()) {
+ if (owner().get()) {
+ std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
+ owner()->document());
+ if (aDoc) {
+ const TDF_Label& aRefLab = aRef->First();
+ if (!aRefLab.IsNull()) { // it may happen with old document, issue #285
+ ObjectPtr anObj = aDoc->objects()->object(aRefLab);
+ FiltersFeaturePtr aFeat = std::dynamic_pointer_cast<ModelAPI_FiltersFeature>(anObj);
+ if (aFeat.get()) {
+ aFeat->setAttribute(owner()->data()->attribute(id()));
+ return aFeat;
+ }
+ }
+ }
+ }
+ }
+ return FiltersFeaturePtr(); // null pointer if nothing is defined
+}
+
+void Model_AttributeSelectionList::setFilters(FiltersFeaturePtr theFeature)
+{
+ Handle(TDataStd_ReferenceList) aRef = TDataStd_ReferenceList::Set(myLab, kSELECTION_FILTERS_REF);
+ if (theFeature.get()) {
+ std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theFeature->data());
+ if (aData->isValid()) {
+ TDF_Label anObjLab = aData->label().Father(); // object label
+ if (!aRef->IsEmpty())
+ aRef->Clear();
+ aRef->Append(anObjLab);
+ theFeature->setAttribute(owner()->data()->attribute(id()));
+ return;
+ }
+ }
+ // remove attribute if something is wrong
+ myLab.ForgetAttribute(TDataStd_ReferenceList::GetID());
+}