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(TDataStd_BooleanArray) aBoolArray; // an existing array
65 Handle(TColStd_HArray1OfInteger) anOldInt, aNewInt =
66 (myType == ModelAPI_AttributeTables::INTEGER) ?
67 new TColStd_HArray1OfInteger(0, aNewSize - 1) : Handle(TColStd_HArray1OfInteger)();
68 Handle(TColStd_HArray1OfExtendedString) anOldStr, aNewStr =
69 (myType == ModelAPI_AttributeTables::STRING) ?
70 new TColStd_HArray1OfExtendedString(0, aNewSize - 1) :
71 Handle(TColStd_HArray1OfExtendedString)();
72 if (aSize != 0) { // copy the previous values into new positions, otherwise default values
73 Handle(TDF_Attribute) anArray;
74 myLab.FindAttribute(MY_ARRAY_ID(myType), anArray);
76 case ModelAPI_AttributeTables::DOUBLE:
77 anOldDouble = Handle(TDataStd_RealArray)::DownCast(anArray)->Array();
79 case ModelAPI_AttributeTables::BOOLEAN: {
80 anOldBool = new bool[aSize];
81 aBoolArray = Handle(TDataStd_BooleanArray)::DownCast(anArray);
82 for(int a = 0; a < aSize; a++)
83 anOldBool[a] = aBoolArray->Value(a);
84 aBoolArray->Init(0, aNewSize - 1);
87 case ModelAPI_AttributeTables::INTEGER:
88 anOldInt = Handle(TDataStd_IntegerArray)::DownCast(anArray)->Array();
90 case ModelAPI_AttributeTables::STRING:
91 anOldStr = Handle(TDataStd_ExtStringArray)::DownCast(anArray)->Array();
94 } else if (myType == ModelAPI_AttributeTables::BOOLEAN) {
95 aBoolArray = TDataStd_BooleanArray::Set(myLab, 0, aNewSize - 1);
97 for(int aTable = 0; aTable < theTables; aTable++) {
98 for(int aColumn = 0; aColumn < theColumns; aColumn++) {
99 for(int aRow = 0; aRow < theRows; aRow++) {
100 int anOldIndex, anIndex = aTable * theRows * theColumns + aRow * theColumns + aColumn;
101 bool aRestore = aTable < myTables && aColumn < myCols && aRow < myRows;
103 anOldIndex = aTable * myRows * myCols + aRow * myCols + aColumn;
105 case ModelAPI_AttributeTables::DOUBLE: {
106 aNewDouble->SetValue(anIndex, aRestore ? anOldDouble->Value(anOldIndex) : 0.);
109 case ModelAPI_AttributeTables::BOOLEAN: {
110 aBoolArray->SetValue(anIndex, aRestore ? anOldBool[anOldIndex] : Standard_False);
113 case ModelAPI_AttributeTables::INTEGER: {
114 aNewInt->SetValue(anIndex, aRestore ? anOldInt->Value(anOldIndex) : 0);
117 case ModelAPI_AttributeTables::STRING: {
118 aNewStr->SetValue(anIndex, aRestore ? anOldStr->Value(anOldIndex) : "");
125 // store the new array
127 case ModelAPI_AttributeTables::DOUBLE:
128 TDataStd_RealArray::Set(myLab, 0, aNewSize - 1)->ChangeArray(aNewDouble);
130 case ModelAPI_AttributeTables::BOOLEAN: // nothing to do: array was set in "else" of restore
132 case ModelAPI_AttributeTables::INTEGER:
133 TDataStd_IntegerArray::Set(myLab, 0, aNewSize - 1)->ChangeArray(aNewInt);
135 case ModelAPI_AttributeTables::STRING:
136 TDataStd_ExtStringArray::Set(myLab, 0, aNewSize - 1)->ChangeArray(aNewStr);
140 // store the new sizes
143 myTables = theTables;
145 myProp->Append(int(myType)); // default
146 myProp->Append(myTables);
147 myProp->Append(myRows);
148 myProp->Append(myCols);
149 owner()->data()->sendAttributeUpdated(this);
153 void Model_AttributeTables::setType(ModelAPI_AttributeTables::ValueType theType)
155 if (myType != theType) {
156 // remove the old attr
157 int aSize = myRows * myCols * myTables;
159 myLab.ForgetAttribute(MY_ARRAY_ID(myType));
161 int aTables = myTables;
162 myTables = 0; // to let setSize know that there is no old array
163 setSize(myRows, myCols, aTables);
166 owner()->data()->sendAttributeUpdated(this);
171 const ModelAPI_AttributeTables::ValueType& Model_AttributeTables::type() const
176 void Model_AttributeTables::setValue(const ModelAPI_AttributeTables::Value theValue,
177 const int theRow, const int theColumn, const int theTable)
179 int anIndex = theTable * myRows * myCols + theRow * myCols + theColumn;
180 Handle(TDF_Attribute) anArray;
181 myLab.FindAttribute(MY_ARRAY_ID(myType), anArray);
183 case ModelAPI_AttributeTables::DOUBLE: {
184 Handle(TDataStd_RealArray)::DownCast(anArray)->SetValue(anIndex, theValue.myDouble);
187 case ModelAPI_AttributeTables::BOOLEAN: {
188 Handle(TDataStd_BooleanArray)::DownCast(anArray)->SetValue(anIndex, theValue.myBool);
191 case ModelAPI_AttributeTables::INTEGER: {
192 Handle(TDataStd_IntegerArray)::DownCast(anArray)->SetValue(anIndex, theValue.myInt);
195 case ModelAPI_AttributeTables::STRING: {
196 Handle(TDataStd_ExtStringArray)::DownCast(anArray)->SetValue(anIndex, theValue.myStr.c_str());
200 owner()->data()->sendAttributeUpdated(this);
203 ModelAPI_AttributeTables::Value Model_AttributeTables::value(
204 const int theRow, const int theColumn, const int theTable)
206 ModelAPI_AttributeTables::Value aResult;
207 int anIndex = theTable * myRows * myCols + theRow * myCols + theColumn;
208 Handle(TDF_Attribute) anArray;
209 myLab.FindAttribute(MY_ARRAY_ID(myType), anArray);
211 case ModelAPI_AttributeTables::DOUBLE: {
212 aResult.myDouble = Handle(TDataStd_RealArray)::DownCast(anArray)->Value(anIndex);
215 case ModelAPI_AttributeTables::BOOLEAN: {
216 aResult.myBool = Handle(TDataStd_BooleanArray)::DownCast(anArray)->Value(anIndex) ==
220 case ModelAPI_AttributeTables::INTEGER: {
221 aResult.myInt = Handle(TDataStd_IntegerArray)::DownCast(anArray)->Value(anIndex);
224 case ModelAPI_AttributeTables::STRING: {
225 aResult.myStr = TCollection_AsciiString(Handle(TDataStd_ExtStringArray)::DownCast(anArray)->
226 Value(anIndex)).ToCString();
233 std::string Model_AttributeTables::valueStr(
234 const int theRow, const int theColumn, const int theTable)
236 std::ostringstream aStr;
238 case ModelAPI_AttributeTables::DOUBLE:
239 aStr<<value(theRow, theColumn, theTable).myDouble;
241 case ModelAPI_AttributeTables::BOOLEAN:
242 aStr<<(value(theRow, theColumn, theTable).myBool ? "True" :"False");
244 case ModelAPI_AttributeTables::INTEGER:
245 aStr<<value(theRow, theColumn, theTable).myInt;
247 case ModelAPI_AttributeTables::STRING:
248 aStr<<value(theRow, theColumn, theTable).myStr;
254 //==================================================================================================
255 Model_AttributeTables::Model_AttributeTables(TDF_Label& theLabel)
261 void Model_AttributeTables::reinit()
263 // check the attribute could be already presented in this doc (after load document)
265 myLab.FindAttribute(TDataStd_IntegerList::GetID(), myProp) == Standard_True;
266 if (!myIsInitialized) {
267 myProp = TDataStd_IntegerList::Set(myLab);
268 myProp->Append(int(Model_AttributeTables::DOUBLE)); // default
273 TColStd_ListIteratorOfListOfInteger aListIter(myProp->List());
274 myType = ModelAPI_AttributeTables::ValueType(aListIter.Value());
276 myTables = aListIter.Value();
278 myRows = aListIter.Value();
280 myCols = aListIter.Value();