1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: Model_AttributeTables.cpp
4 // Created: 14 Nov 2016
5 // Author: Mikhail Ponikarov
7 #include "Model_AttributeTables.h"
9 #include <ModelAPI_Data.h>
10 #include <ModelAPI_Object.h>
12 #include <TColStd_ListIteratorOfListOfInteger.hxx>
13 #include <TDataStd_RealArray.hxx>
14 #include <TDataStd_BooleanArray.hxx>
15 #include <TDataStd_IntegerArray.hxx>
16 #include <TDataStd_ExtStringArray.hxx>
18 #include <TColStd_HArray1OfReal.hxx>
19 #include <TColStd_HArray1OfByte.hxx>
20 #include <TColStd_HArray1OfInteger.hxx>
21 #include <TColStd_HArray1OfExtendedString.hxx>
25 // returns the array attribute GUID for the given type
26 #define MY_ARRAY_ID(type) \
27 ((type) == ModelAPI_AttributeTables::DOUBLE ? TDataStd_RealArray::GetID(): \
28 ((type) == ModelAPI_AttributeTables::BOOLEAN ? TDataStd_BooleanArray::GetID(): \
29 ((type) == ModelAPI_AttributeTables::INTEGER? TDataStd_IntegerArray::GetID(): \
30 TDataStd_ExtStringArray::GetID())))
32 int Model_AttributeTables::rows()
37 int Model_AttributeTables::columns()
42 int Model_AttributeTables::tables()
47 void Model_AttributeTables::setSize(const int theRows, const int theColumns, const int theTables)
49 if (theRows != myRows || theColumns != myCols || theTables != myTables) {
50 owner()->data()->sendAttributeUpdated(this);
51 int aSize = myRows * myCols * myTables;
52 int aNewSize = theRows * theColumns * theTables;
53 if (aSize == 0 && aNewSize == 0) {
55 } else if (aNewSize == 0) {
57 myLab.ForgetAttribute(MY_ARRAY_ID(myType));
60 Handle(TColStd_HArray1OfReal) anOldDouble, aNewDouble =
61 (myType == ModelAPI_AttributeTables::DOUBLE) ?
62 new TColStd_HArray1OfReal(0, aNewSize - 1) : Handle(TColStd_HArray1OfReal)();
63 bool* anOldBool = 0; // an not work with internal arrays because of different indexing
64 Handle(TColStd_HArray1OfByte) aNewBool = (myType == ModelAPI_AttributeTables::BOOLEAN) ?
65 // internal array for boolean has 8 times lower size
66 new TColStd_HArray1OfByte(0, (aNewSize - 1)>>3) : Handle(TColStd_HArray1OfByte)();
67 Handle(TDataStd_BooleanArray) aBoolArray; // an existing array
68 Handle(TColStd_HArray1OfInteger) anOldInt, aNewInt =
69 (myType == ModelAPI_AttributeTables::INTEGER) ?
70 new TColStd_HArray1OfInteger(0, aNewSize - 1) : Handle(TColStd_HArray1OfInteger)();
71 Handle(TColStd_HArray1OfExtendedString) anOldStr, aNewStr =
72 (myType == ModelAPI_AttributeTables::STRING) ?
73 new TColStd_HArray1OfExtendedString(0, aNewSize - 1) :
74 Handle(TColStd_HArray1OfExtendedString)();
75 if (aSize != 0) { // copy the previous values into new positions, otherwise default values
76 Handle(TDF_Attribute) anArray;
77 myLab.FindAttribute(MY_ARRAY_ID(myType), anArray);
79 case ModelAPI_AttributeTables::DOUBLE:
80 anOldDouble = Handle(TDataStd_RealArray)::DownCast(anArray)->Array();
82 case ModelAPI_AttributeTables::BOOLEAN: {
83 anOldBool = new bool[aSize];
84 aBoolArray = Handle(TDataStd_BooleanArray)::DownCast(anArray);
85 for(int a = 0; a < aSize; a++)
86 anOldBool[a] = aBoolArray->Value(a);
87 aBoolArray->SetInternalArray(aNewBool);
90 case ModelAPI_AttributeTables::INTEGER:
91 anOldInt = Handle(TDataStd_IntegerArray)::DownCast(anArray)->Array();
93 case ModelAPI_AttributeTables::STRING:
94 anOldStr = Handle(TDataStd_ExtStringArray)::DownCast(anArray)->Array();
97 } else if (myType == ModelAPI_AttributeTables::BOOLEAN) {
98 aBoolArray = TDataStd_BooleanArray::Set(myLab, 0, aNewSize - 1);
100 for(int aTable = 0; aTable < theTables; aTable++) {
101 for(int aColumn = 0; aColumn < theColumns; aColumn++) {
102 for(int aRow = 0; aRow < theRows; aRow++) {
103 int anOldIndex, anIndex = aTable * theRows * theColumns + aRow * theColumns + aColumn;
104 bool aRestore = aTable < myTables && aColumn < myCols && aRow < myRows;
106 anOldIndex = aTable * myRows * myCols + aRow * myCols + aColumn;
108 case ModelAPI_AttributeTables::DOUBLE: {
109 aNewDouble->SetValue(anIndex, aRestore ? anOldDouble->Value(anOldIndex) : 0.);
112 case ModelAPI_AttributeTables::BOOLEAN: {
113 aBoolArray->SetValue(anIndex, aRestore ? anOldBool[anOldIndex] : Standard_False);
116 case ModelAPI_AttributeTables::INTEGER: {
117 aNewInt->SetValue(anIndex, aRestore ? anOldInt->Value(anOldIndex) : 0);
120 case ModelAPI_AttributeTables::STRING: {
121 aNewStr->SetValue(anIndex, aRestore ? anOldStr->Value(anOldIndex) : "");
128 // store the new array
130 case ModelAPI_AttributeTables::DOUBLE:
131 TDataStd_RealArray::Set(myLab, 0, aNewSize - 1)->ChangeArray(aNewDouble);
133 case ModelAPI_AttributeTables::BOOLEAN: // nothing to do: array was set in "else" of restore
135 case ModelAPI_AttributeTables::INTEGER:
136 TDataStd_IntegerArray::Set(myLab, 0, aNewSize - 1)->ChangeArray(aNewInt);
138 case ModelAPI_AttributeTables::STRING:
139 TDataStd_ExtStringArray::Set(myLab, 0, aNewSize - 1)->ChangeArray(aNewStr);
143 // store the new sizes
146 myTables = theTables;
148 myProp->Append(int(myType)); // default
149 myProp->Append(myTables);
150 myProp->Append(myRows);
151 myProp->Append(myCols);
152 owner()->data()->sendAttributeUpdated(this);
156 void Model_AttributeTables::setType(ModelAPI_AttributeTables::ValueType theType)
158 if (myType != theType) {
159 // remove the old attr
160 int aSize = myRows * myCols * myTables;
162 myLab.ForgetAttribute(MY_ARRAY_ID(myType));
164 int aTables = myTables;
165 myTables = 0; // to let setSize know that there is no old array
166 setSize(myRows, myCols, aTables);
169 owner()->data()->sendAttributeUpdated(this);
174 const ModelAPI_AttributeTables::ValueType& Model_AttributeTables::type() const
179 void Model_AttributeTables::setValue(const ModelAPI_AttributeTables::Value theValue,
180 const int theRow, const int theColumn, const int theTable)
182 int anIndex = theTable * myRows * myCols + theRow * myCols + theColumn;
183 Handle(TDF_Attribute) anArray;
184 myLab.FindAttribute(MY_ARRAY_ID(myType), anArray);
186 case ModelAPI_AttributeTables::DOUBLE: {
187 Handle(TDataStd_RealArray)::DownCast(anArray)->SetValue(anIndex, theValue.myDouble);
190 case ModelAPI_AttributeTables::BOOLEAN: {
191 Handle(TDataStd_BooleanArray)::DownCast(anArray)->SetValue(anIndex, theValue.myBool);
194 case ModelAPI_AttributeTables::INTEGER: {
195 Handle(TDataStd_IntegerArray)::DownCast(anArray)->SetValue(anIndex, theValue.myInt);
198 case ModelAPI_AttributeTables::STRING: {
199 Handle(TDataStd_ExtStringArray)::DownCast(anArray)->SetValue(anIndex, theValue.myStr.c_str());
203 owner()->data()->sendAttributeUpdated(this);
206 ModelAPI_AttributeTables::Value Model_AttributeTables::value(
207 const int theRow, const int theColumn, const int theTable)
209 ModelAPI_AttributeTables::Value aResult;
210 int anIndex = theTable * myRows * myCols + theRow * myCols + theColumn;
211 Handle(TDF_Attribute) anArray;
212 myLab.FindAttribute(MY_ARRAY_ID(myType), anArray);
214 case ModelAPI_AttributeTables::DOUBLE: {
215 aResult.myDouble = Handle(TDataStd_RealArray)::DownCast(anArray)->Value(anIndex);
218 case ModelAPI_AttributeTables::BOOLEAN: {
219 aResult.myBool = Handle(TDataStd_BooleanArray)::DownCast(anArray)->Value(anIndex) ==
223 case ModelAPI_AttributeTables::INTEGER: {
224 aResult.myInt = Handle(TDataStd_IntegerArray)::DownCast(anArray)->Value(anIndex);
227 case ModelAPI_AttributeTables::STRING: {
228 aResult.myStr = TCollection_AsciiString(Handle(TDataStd_ExtStringArray)::DownCast(anArray)->
229 Value(anIndex)).ToCString();
236 std::string Model_AttributeTables::valueStr(
237 const int theRow, const int theColumn, const int theTable)
239 std::ostringstream aStr;
241 case ModelAPI_AttributeTables::DOUBLE:
242 aStr<<value(theRow, theColumn, theTable).myDouble;
244 case ModelAPI_AttributeTables::BOOLEAN:
245 aStr<<(value(theRow, theColumn, theTable).myBool ? "True" :"False");
247 case ModelAPI_AttributeTables::INTEGER:
248 aStr<<value(theRow, theColumn, theTable).myInt;
250 case ModelAPI_AttributeTables::STRING:
251 aStr<<value(theRow, theColumn, theTable).myStr;
257 //==================================================================================================
258 Model_AttributeTables::Model_AttributeTables(TDF_Label& theLabel)
264 void Model_AttributeTables::reinit()
266 // check the attribute could be already presented in this doc (after load document)
268 myLab.FindAttribute(TDataStd_IntegerList::GetID(), myProp) == Standard_True;
269 if (!myIsInitialized) {
270 myProp = TDataStd_IntegerList::Set(myLab);
271 myProp->Append(int(Model_AttributeTables::DOUBLE)); // default
276 TColStd_ListIteratorOfListOfInteger aListIter(myProp->List());
277 myType = ModelAPI_AttributeTables::ValueType(aListIter.Value());
279 myTables = aListIter.Value();
281 myRows = aListIter.Value();
283 myCols = aListIter.Value();