-// Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+// Copyright (C) 2014-2020 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_AttributeTables.h>
#include <Model_Events.h>
#include <Model_Expression.h>
+#include <Model_Tools.h>
+#include <Model_Validator.h>
+
#include <ModelAPI_Feature.h>
#include <ModelAPI_Result.h>
#include <ModelAPI_ResultParameter.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_ResultPart.h>
#include <ModelAPI_Tools.h>
-#include <Model_Validator.h>
#include <GeomDataAPI_Point.h>
#include <GeomDataAPI_Point2D.h>
+#include <GeomDataAPI_Point2DArray.h>
#include <GeomData_Point.h>
#include <GeomData_Point2D.h>
+#include <GeomData_Point2DArray.h>
#include <GeomData_Dir.h>
#include <Events_Loop.h>
#include <Events_InfoMessage.h>
#include <TDataStd_Name.hxx>
#include <TDataStd_AsciiString.hxx>
-#include <TDataStd_IntegerArray.hxx>
#include <TDataStd_UAttribute.hxx>
-#include <TDF_AttributeIterator.hxx>
-#include <TDF_ChildIterator.hxx>
-#include <TDF_RelocationTable.hxx>
-#include <TColStd_HArray1OfByte.hxx>
+#include <TDF_ChildIDIterator.hxx>
#include <string>
static const int kFlagDeleted = 2;
// TDataStd_Integer - 0 if the name of the object is generated automatically,
// otherwise the name is defined by user
-Standard_GUID kUSER_DEFINED_NAME("9c694d18-a83c-4a56-bc9b-8020628a8244");
+static const Standard_GUID kUSER_DEFINED_NAME("9c694d18-a83c-4a56-bc9b-8020628a8244");
// invalid data
const static std::shared_ptr<ModelAPI_Data> kInvalid(new Model_Data());
+static const Standard_GUID kGroupAttributeGroupID("df64ea4c-fc42-4bf8-ad7e-08f7a54bf1b8");
+static const Standard_GUID kGroupAttributeID("ebdcb22a-e045-455b-9a7f-cfd38d68e185");
+
+// id of attribute to store the version of the feature
+static const Standard_GUID kVERSION_ID("61cdb78a-1ba7-4942-976f-63bea7f4a2b1");
+
+
Model_Data::Model_Data() : mySendAttributeUpdated(true), myWasChangedButBlocked(false)
{
}
return shapeLab().IsAttribute(kUSER_DEFINED_NAME);
}
-AttributePtr Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
+std::string Model_Data::version()
+{
+ Handle(TDataStd_Name) aVersionAttr;
+ std::string aVersion;
+ if (shapeLab().FindAttribute(kVERSION_ID, aVersionAttr))
+ aVersion = TCollection_AsciiString(aVersionAttr->Get()).ToCString();
+ return aVersion;
+}
+
+void Model_Data::setVersion(const std::string& theVersion)
+{
+ Handle(TDataStd_Name) aVersionAttr;
+ std::string aVersion;
+ if (!shapeLab().FindAttribute(kVERSION_ID, aVersionAttr))
+ aVersionAttr = TDataStd_Name::Set(shapeLab(), kVERSION_ID, TCollection_ExtendedString());
+ aVersionAttr->Set(theVersion.c_str());
+}
+
+AttributePtr Model_Data::addAttribute(
+ const std::string& theID, const std::string theAttrType, const int theIndex)
{
AttributePtr aResult;
- int anAttrIndex = int(myAttrs.size()) + 1;
+ int anAttrIndex = theIndex == -1 ? int(myAttrs.size()) + 1 : theIndex;
TDF_Label anAttrLab = myLab.FindChild(anAttrIndex);
ModelAPI_Attribute* anAttr = 0;
if (theAttrType == ModelAPI_AttributeDocRef::typeId()) {
}
anAttribute->myIsInitialized = anAllInitialized;
anAttr = anAttribute;
+ } else if (theAttrType == GeomData_Point2DArray::typeId()) {
+ anAttr = new GeomData_Point2DArray(anAttrLab);
}
+
if (anAttr) {
aResult = std::shared_ptr<ModelAPI_Attribute>(anAttr);
myAttrs[theID] = std::pair<AttributePtr, int>(aResult, anAttrIndex);
return aResult;
}
+AttributePtr Model_Data::addFloatingAttribute(
+ const std::string& theID, const std::string theAttrType, const std::string& theGroup)
+{
+ // compute the index of the attribute placement
+ int anIndex;
+ TDF_Label aLab;
+ if (myLab.IsAttribute(TDF_TagSource::GetID())) {
+ // check this is re-init of attributes, so, check attribute with this name already there
+ TDF_ChildIDIterator anIter(myLab, kGroupAttributeID, false);
+ for(; anIter.More(); anIter.Next()) {
+ TCollection_AsciiString aThisName(Handle(TDataStd_Name)::DownCast(anIter.Value())->Get());
+ if (theID == aThisName.ToCString()) {
+ TDF_Label aChildLab = anIter.Value()->Label();
+ Handle(TDataStd_Name) aGName;
+ if (aChildLab.FindAttribute(kGroupAttributeGroupID, aGName)) {
+ TCollection_AsciiString aGroupName(aGName->Get());
+ if (theGroup == aGroupName.ToCString()) {
+ return addAttribute(theGroup + "__" + theID, theAttrType, aChildLab.Tag());
+ }
+ }
+ }
+ }
+ aLab = myLab.NewChild(); // already exists a floating attribute, create the next
+ anIndex = aLab.Tag();
+ } else { // put the first floating attribute, quite far from other standard attributes
+ anIndex = int(myAttrs.size()) + 1000;
+ TDF_TagSource::Set(myLab)->Set(anIndex);
+ aLab = myLab.FindChild(anIndex, true);
+ }
+ // store the group ID and the attribute ID (to restore correctly)
+ TDataStd_Name::Set(aLab, kGroupAttributeGroupID, theGroup.c_str());
+ TDataStd_Name::Set(aLab, kGroupAttributeID, theID.c_str());
+
+ return addAttribute(theGroup + "__" + theID, theAttrType, anIndex);
+}
+
+void Model_Data::allGroups(std::list<std::string>& theGroups)
+{
+ std::set<std::string> alreadyThere;
+ for(TDF_ChildIDIterator aGroup(myLab, kGroupAttributeGroupID); aGroup.More(); aGroup.Next()) {
+ Handle(TDataStd_Name) aGroupAttr = Handle(TDataStd_Name)::DownCast(aGroup.Value());
+ std::string aGroupID = TCollection_AsciiString(aGroupAttr->Get()).ToCString();
+ if (alreadyThere.find(aGroupID) == alreadyThere.end()) {
+ theGroups.push_back(aGroupID);
+ alreadyThere.insert(aGroupID);
+ }
+ }
+}
+
+void Model_Data::attributesOfGroup(const std::string& theGroup,
+ std::list<std::shared_ptr<ModelAPI_Attribute> >& theAttrs)
+{
+ for(TDF_ChildIDIterator aGroup(myLab, kGroupAttributeGroupID); aGroup.More(); aGroup.Next()) {
+ Handle(TDataStd_Name) aGroupID = Handle(TDataStd_Name)::DownCast(aGroup.Value());
+ if (aGroupID->Get().IsEqual(theGroup.c_str())) {
+ Handle(TDataStd_Name) anID;
+ if (aGroup.Value()->Label().FindAttribute(kGroupAttributeID, anID)) {
+ TCollection_AsciiString anAsciiID(aGroupID->Get() + "__" + anID->Get());
+ theAttrs.push_back(attribute(anAsciiID.ToCString()));
+ }
+ }
+ }
+}
+
+void Model_Data::removeAttributes(const std::string& theGroup)
+{
+ TDF_LabelList aLabsToRemove; // collect labels that must be erased after the cycle
+ for(TDF_ChildIDIterator aGroup(myLab, kGroupAttributeGroupID); aGroup.More(); aGroup.Next()) {
+ Handle(TDataStd_Name) aGroupID = Handle(TDataStd_Name)::DownCast(aGroup.Value());
+ if (aGroupID->Get().IsEqual(theGroup.c_str())) {
+ Handle(TDataStd_Name) anID;
+ if (!aGroup.Value()->Label().IsNull() &&
+ aGroup.Value()->Label().FindAttribute(kGroupAttributeID, anID)) {
+ aLabsToRemove.Append(aGroup.Value()->Label());
+ }
+ TCollection_AsciiString anAsciiID(aGroupID->Get() + "__" + anID->Get());
+ myAttrs.erase(anAsciiID.ToCString());
+ }
+ }
+ for(TDF_LabelList::Iterator aLab(aLabsToRemove); aLab.More(); aLab.Next()) {
+ aLab.ChangeValue().ForgetAllAttributes(true);
+ }
+}
+
+void Model_Data::clearAttributes()
+{
+ myAttrs.clear();
+}
+
+
+
// macro for the generic returning of the attribute by the ID
#define GET_ATTRIBUTE_BY_ID(ATTR_TYPE, METHOD_NAME) \
std::shared_ptr<ATTR_TYPE> Model_Data::METHOD_NAME(const std::string& theID) { \
}
} else {
// trim: need to redisplay or set color in the python script
- if (myObject && (theAttr->attributeType() == "Point2D" || theAttr->id() == "Color")) {
+ if (myObject && (theAttr->attributeType() == "Point2D" || theAttr->id() == "Color" ||
+ theAttr->id() == "Transparency" || theAttr->id() == "Deflection" ||
+ theAttr->id() == "Iso_lines" || theAttr->id() == "Show_Iso_lines")) {
static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);
ModelAPI_EventCreator::get()->sendUpdated(myObject, anEvent);
}
if (aRef->isObject()) {
aReferenced.push_back(aRef->object());
} else {
- AttributePtr anAttr = aRef->attr();
- if (anAttr.get())
- aReferenced.push_back(anAttr->owner());
+ AttributePtr aReferredAttr = aRef->attr();
+ if (aReferredAttr.get())
+ aReferenced.push_back(aReferredAttr->owner());
}
} else if (aType == ModelAPI_AttributeRefList::typeId()) { // list of references
aReferenced = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(anAttr)->list();
}
}
-/// makes copy of all attributes on the given label and all sub-labels
-static void copyAttrs(TDF_Label theSource, TDF_Label theDestination) {
- TDF_AttributeIterator anAttrIter(theSource);
- for(; anAttrIter.More(); anAttrIter.Next()) {
- Handle(TDF_Attribute) aTargetAttr;
- if (!theDestination.FindAttribute(anAttrIter.Value()->ID(), aTargetAttr)) {
- // create a new attribute if not yet exists in the destination
- aTargetAttr = anAttrIter.Value()->NewEmpty();
- theDestination.AddAttribute(aTargetAttr);
- }
- // no special relocation, empty map, but self-relocation is on: copy references w/o changes
- Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(Standard_True);
- anAttrIter.Value()->Paste(aTargetAttr, aRelocTable);
- }
- // copy the sub-labels content
- TDF_ChildIterator aSubLabsIter(theSource);
- for(; aSubLabsIter.More(); aSubLabsIter.Next()) {
- copyAttrs(aSubLabsIter.Value(), theDestination.FindChild(aSubLabsIter.Value().Tag()));
- }
-}
-
void Model_Data::copyTo(std::shared_ptr<ModelAPI_Data> theTarget)
{
TDF_Label aTargetRoot = std::dynamic_pointer_cast<Model_Data>(theTarget)->label();
- copyAttrs(myLab, aTargetRoot);
+ Model_Tools::copyAttrs(myLab, aTargetRoot);
// reinitialize Model_Attributes by TDF_Attributes set
std::shared_ptr<Model_Data> aTData = std::dynamic_pointer_cast<Model_Data>(theTarget);
aTData->myAttrs.clear();