1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "Model_AttributeTables.h"
23 #include <ModelAPI_Data.h>
24 #include <ModelAPI_Object.h>
26 #include <TColStd_ListIteratorOfListOfInteger.hxx>
27 #include <TDataStd_RealArray.hxx>
28 #include <TDataStd_BooleanArray.hxx>
29 #include <TDataStd_IntegerArray.hxx>
30 #include <TDataStd_ExtStringArray.hxx>
32 #include <TColStd_HArray1OfReal.hxx>
33 #include <TColStd_HArray1OfByte.hxx>
34 #include <TColStd_HArray1OfInteger.hxx>
35 #include <TColStd_HArray1OfExtendedString.hxx>
39 // returns the array attribute GUID for the given type
40 #define MY_ARRAY_ID(type) \
41 ((type) == ModelAPI_AttributeTables::DOUBLE ? TDataStd_RealArray::GetID(): \
42 ((type) == ModelAPI_AttributeTables::BOOLEAN ? TDataStd_BooleanArray::GetID(): \
43 ((type) == ModelAPI_AttributeTables::INTEGER? TDataStd_IntegerArray::GetID(): \
44 TDataStd_ExtStringArray::GetID())))
46 int Model_AttributeTables::rows()
51 int Model_AttributeTables::columns()
56 int Model_AttributeTables::tables()
61 void Model_AttributeTables::setSize(const int theRows, const int theColumns, const int theTables)
63 if (theRows != myRows || theColumns != myCols || theTables != myTables) {
64 owner()->data()->sendAttributeUpdated(this);
65 int aSize = myRows * myCols * myTables;
66 int aNewSize = theRows * theColumns * theTables;
67 if (aSize == 0 && aNewSize == 0) {
69 } else if (aNewSize == 0) {
71 myLab.ForgetAttribute(MY_ARRAY_ID(myType));
74 Handle(TColStd_HArray1OfReal) anOldDouble, aNewDouble =
75 (myType == ModelAPI_AttributeTables::DOUBLE) ?
76 new TColStd_HArray1OfReal(0, aNewSize - 1) : Handle(TColStd_HArray1OfReal)();
77 bool* anOldBool = 0; // an not work with internal arrays because of different indexing
78 Handle(TDataStd_BooleanArray) aBoolArray; // an existing array
79 Handle(TColStd_HArray1OfInteger) anOldInt, aNewInt =
80 (myType == ModelAPI_AttributeTables::INTEGER) ?
81 new TColStd_HArray1OfInteger(0, aNewSize - 1) : Handle(TColStd_HArray1OfInteger)();
82 Handle(TColStd_HArray1OfExtendedString) anOldStr, aNewStr =
83 (myType == ModelAPI_AttributeTables::STRING) ?
84 new TColStd_HArray1OfExtendedString(0, aNewSize - 1) :
85 Handle(TColStd_HArray1OfExtendedString)();
86 if (aSize != 0) { // copy the previous values into new positions, otherwise default values
87 Handle(TDF_Attribute) anArray;
88 myLab.FindAttribute(MY_ARRAY_ID(myType), anArray);
90 case ModelAPI_AttributeTables::DOUBLE:
91 anOldDouble = Handle(TDataStd_RealArray)::DownCast(anArray)->Array();
93 case ModelAPI_AttributeTables::BOOLEAN: {
94 anOldBool = new bool[aSize];
95 aBoolArray = Handle(TDataStd_BooleanArray)::DownCast(anArray);
96 for(int a = 0; a < aSize; a++)
97 anOldBool[a] = aBoolArray->Value(a);
98 aBoolArray->Init(0, aNewSize - 1);
101 case ModelAPI_AttributeTables::INTEGER:
102 anOldInt = Handle(TDataStd_IntegerArray)::DownCast(anArray)->Array();
104 case ModelAPI_AttributeTables::STRING:
105 anOldStr = Handle(TDataStd_ExtStringArray)::DownCast(anArray)->Array();
108 } else if (myType == ModelAPI_AttributeTables::BOOLEAN) {
109 aBoolArray = TDataStd_BooleanArray::Set(myLab, 0, aNewSize - 1);
111 for(int aTable = 0; aTable < theTables; aTable++) {
112 for(int aColumn = 0; aColumn < theColumns; aColumn++) {
113 for(int aRow = 0; aRow < theRows; aRow++) {
114 int anOldIndex, anIndex = aTable * theRows * theColumns + aRow * theColumns + aColumn;
115 bool aRestore = aTable < myTables && aColumn < myCols && aRow < myRows;
117 anOldIndex = aTable * myRows * myCols + aRow * myCols + aColumn;
119 case ModelAPI_AttributeTables::DOUBLE: {
120 aNewDouble->SetValue(anIndex, aRestore ? anOldDouble->Value(anOldIndex) : 0.);
123 case ModelAPI_AttributeTables::BOOLEAN: {
124 aBoolArray->SetValue(anIndex, aRestore ? anOldBool[anOldIndex] : Standard_False);
127 case ModelAPI_AttributeTables::INTEGER: {
128 aNewInt->SetValue(anIndex, aRestore ? anOldInt->Value(anOldIndex) : 0);
131 case ModelAPI_AttributeTables::STRING: {
132 aNewStr->SetValue(anIndex, aRestore ? anOldStr->Value(anOldIndex) : "");
139 // store the new array
141 case ModelAPI_AttributeTables::DOUBLE:
142 TDataStd_RealArray::Set(myLab, 0, aNewSize - 1)->ChangeArray(aNewDouble);
144 case ModelAPI_AttributeTables::BOOLEAN: // nothing to do: array was set in "else" of restore
146 case ModelAPI_AttributeTables::INTEGER:
147 TDataStd_IntegerArray::Set(myLab, 0, aNewSize - 1)->ChangeArray(aNewInt);
149 case ModelAPI_AttributeTables::STRING:
150 TDataStd_ExtStringArray::Set(myLab, 0, aNewSize - 1)->ChangeArray(aNewStr);
154 // store the new sizes
157 myTables = theTables;
159 myProp->Append(int(myType)); // default
160 myProp->Append(myTables);
161 myProp->Append(myRows);
162 myProp->Append(myCols);
163 owner()->data()->sendAttributeUpdated(this);
167 void Model_AttributeTables::setType(ModelAPI_AttributeTables::ValueType theType)
169 if (myType != theType) {
170 // remove the old attr
171 int aSize = myRows * myCols * myTables;
173 myLab.ForgetAttribute(MY_ARRAY_ID(myType));
175 int aTables = myTables;
176 myTables = 0; // to let setSize know that there is no old array
177 setSize(myRows, myCols, aTables);
180 owner()->data()->sendAttributeUpdated(this);
185 const ModelAPI_AttributeTables::ValueType& Model_AttributeTables::type() const
190 void Model_AttributeTables::setValue(const ModelAPI_AttributeTables::Value theValue,
191 const int theRow, const int theColumn, const int theTable)
193 int anIndex = theTable * myRows * myCols + theRow * myCols + theColumn;
194 Handle(TDF_Attribute) anArray;
195 myLab.FindAttribute(MY_ARRAY_ID(myType), anArray);
197 case ModelAPI_AttributeTables::DOUBLE: {
198 Handle(TDataStd_RealArray)::DownCast(anArray)->SetValue(anIndex, theValue.myDouble);
201 case ModelAPI_AttributeTables::BOOLEAN: {
202 Handle(TDataStd_BooleanArray)::DownCast(anArray)->SetValue(anIndex, theValue.myBool);
205 case ModelAPI_AttributeTables::INTEGER: {
206 Handle(TDataStd_IntegerArray)::DownCast(anArray)->SetValue(anIndex, theValue.myInt);
209 case ModelAPI_AttributeTables::STRING: {
210 Handle(TDataStd_ExtStringArray)::DownCast(anArray)->SetValue(anIndex, theValue.myStr.c_str());
214 owner()->data()->sendAttributeUpdated(this);
217 ModelAPI_AttributeTables::Value Model_AttributeTables::value(
218 const int theRow, const int theColumn, const int theTable)
220 ModelAPI_AttributeTables::Value aResult;
221 int anIndex = theTable * myRows * myCols + theRow * myCols + theColumn;
222 Handle(TDF_Attribute) anArray;
223 myLab.FindAttribute(MY_ARRAY_ID(myType), anArray);
225 case ModelAPI_AttributeTables::DOUBLE: {
226 aResult.myDouble = Handle(TDataStd_RealArray)::DownCast(anArray)->Value(anIndex);
229 case ModelAPI_AttributeTables::BOOLEAN: {
230 aResult.myBool = Handle(TDataStd_BooleanArray)::DownCast(anArray)->Value(anIndex) ==
234 case ModelAPI_AttributeTables::INTEGER: {
235 aResult.myInt = Handle(TDataStd_IntegerArray)::DownCast(anArray)->Value(anIndex);
238 case ModelAPI_AttributeTables::STRING: {
239 aResult.myStr = TCollection_AsciiString(Handle(TDataStd_ExtStringArray)::DownCast(anArray)->
240 Value(anIndex)).ToCString();
247 std::string Model_AttributeTables::valueStr(
248 const int theRow, const int theColumn, const int theTable)
250 std::ostringstream aStr;
252 case ModelAPI_AttributeTables::DOUBLE:
253 aStr<<value(theRow, theColumn, theTable).myDouble;
255 case ModelAPI_AttributeTables::BOOLEAN:
256 aStr<<(value(theRow, theColumn, theTable).myBool ? "True" :"False");
258 case ModelAPI_AttributeTables::INTEGER:
259 aStr<<value(theRow, theColumn, theTable).myInt;
261 case ModelAPI_AttributeTables::STRING:
262 aStr<<value(theRow, theColumn, theTable).myStr;
268 //==================================================================================================
269 Model_AttributeTables::Model_AttributeTables(TDF_Label& theLabel)
275 void Model_AttributeTables::reinit()
277 // check the attribute could be already presented in this doc (after load document)
279 myLab.FindAttribute(TDataStd_IntegerList::GetID(), myProp) == Standard_True;
280 if (!myIsInitialized) {
281 myProp = TDataStd_IntegerList::Set(myLab);
282 myProp->Append(int(Model_AttributeTables::DOUBLE)); // default
287 TColStd_ListIteratorOfListOfInteger aListIter(myProp->List());
288 myType = ModelAPI_AttributeTables::ValueType(aListIter.Value());
290 myTables = aListIter.Value();
292 myRows = aListIter.Value();
294 myCols = aListIter.Value();