00001 /*************************************************************************** 00002 * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2010 * 00003 * * 00004 * This file is part of the FreeCAD CAx development system. * 00005 * * 00006 * This library is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU Library General Public * 00008 * License as published by the Free Software Foundation; either * 00009 * version 2 of the License, or (at your option) any later version. * 00010 * * 00011 * This library is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU Library General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Library General Public * 00017 * License along with this library; see the file COPYING.LIB. If not, * 00018 * write to the Free Software Foundation, Inc., 59 Temple Place, * 00019 * Suite 330, Boston, MA 02111-1307, USA * 00020 * * 00021 ***************************************************************************/ 00022 00023 00024 #include "PreCompiled.h" 00025 00026 #ifndef _PreComp_ 00027 # include <assert.h> 00028 #endif 00029 00031 00032 #include <Base/Exception.h> 00033 #include <Base/Reader.h> 00034 #include <Base/Writer.h> 00035 00036 #include "Geometry.h" 00037 #include "GeometryPy.h" 00038 00039 #include "PropertyGeometryList.h" 00040 00041 using namespace App; 00042 using namespace Base; 00043 using namespace std; 00044 using namespace Part; 00045 00046 00047 //************************************************************************** 00048 // PropertyGeometryList 00049 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00050 00051 TYPESYSTEM_SOURCE(Part::PropertyGeometryList, App::PropertyLists); 00052 00053 //************************************************************************** 00054 // Construction/Destruction 00055 00056 00057 PropertyGeometryList::PropertyGeometryList() 00058 { 00059 00060 } 00061 00062 PropertyGeometryList::~PropertyGeometryList() 00063 { 00064 for (std::vector<Geometry*>::iterator it = _lValueList.begin(); it != _lValueList.end(); ++it) 00065 if (*it) delete *it; 00066 } 00067 00068 void PropertyGeometryList::setSize(int newSize) 00069 { 00070 for (unsigned int i = newSize; i < _lValueList.size(); i++) 00071 delete _lValueList[i]; 00072 _lValueList.resize(newSize); 00073 } 00074 00075 int PropertyGeometryList::getSize(void) const 00076 { 00077 return static_cast<int>(_lValueList.size()); 00078 } 00079 00080 void PropertyGeometryList::setValue(const Geometry* lValue) 00081 { 00082 if (lValue) { 00083 aboutToSetValue(); 00084 Geometry* newVal = lValue->clone(); 00085 for (unsigned int i = 0; i < _lValueList.size(); i++) 00086 delete _lValueList[i]; 00087 _lValueList.resize(1); 00088 _lValueList[0] = newVal; 00089 hasSetValue(); 00090 } 00091 } 00092 00093 void PropertyGeometryList::setValues(const std::vector<Geometry*>& lValue) 00094 { 00095 aboutToSetValue(); 00096 std::vector<Geometry*> oldVals(_lValueList); 00097 _lValueList.resize(lValue.size()); 00098 // copy all objects 00099 for (unsigned int i = 0; i < lValue.size(); i++) 00100 _lValueList[i] = lValue[i]->clone(); 00101 for (unsigned int i = 0; i < oldVals.size(); i++) 00102 delete oldVals[i]; 00103 hasSetValue(); 00104 } 00105 00106 PyObject *PropertyGeometryList::getPyObject(void) 00107 { 00108 PyObject* list = PyList_New(getSize()); 00109 for (int i = 0; i < getSize(); i++) 00110 PyList_SetItem( list, i, _lValueList[i]->getPyObject()); 00111 return list; 00112 } 00113 00114 void PropertyGeometryList::setPyObject(PyObject *value) 00115 { 00116 if (PyList_Check(value)) { 00117 Py_ssize_t nSize = PyList_Size(value); 00118 std::vector<Geometry*> values; 00119 values.resize(nSize); 00120 00121 for (Py_ssize_t i=0; i < nSize; ++i) { 00122 PyObject* item = PyList_GetItem(value, i); 00123 if (!PyObject_TypeCheck(item, &(GeometryPy::Type))) { 00124 std::string error = std::string("types in list must be 'Geometry', not "); 00125 error += item->ob_type->tp_name; 00126 throw Py::TypeError(error); 00127 } 00128 00129 values[i] = static_cast<GeometryPy*>(item)->getGeometryPtr(); 00130 } 00131 00132 setValues(values); 00133 } 00134 else if (PyObject_TypeCheck(value, &(GeometryPy::Type))) { 00135 GeometryPy *pcObject = static_cast<GeometryPy*>(value); 00136 setValue(pcObject->getGeometryPtr()); 00137 } 00138 else { 00139 std::string error = std::string("type must be 'Geometry' or list of 'Geometry', not "); 00140 error += value->ob_type->tp_name; 00141 throw Py::TypeError(error); 00142 } 00143 } 00144 00145 void PropertyGeometryList::Save(Writer &writer) const 00146 { 00147 writer.Stream() << writer.ind() << "<GeometryList count=\"" << getSize() <<"\">" << endl; 00148 writer.incInd(); 00149 for (int i = 0; i < getSize(); i++) { 00150 writer.Stream() << writer.ind() << "<Geometry type=\"" 00151 << _lValueList[i]->getTypeId().getName() << "\">" << endl;; 00152 writer.incInd(); 00153 _lValueList[i]->Save(writer); 00154 writer.decInd(); 00155 writer.Stream() << writer.ind() << "</Geometry>" << endl; 00156 } 00157 writer.decInd(); 00158 writer.Stream() << writer.ind() << "</GeometryList>" << endl ; 00159 } 00160 00161 void PropertyGeometryList::Restore(Base::XMLReader &reader) 00162 { 00163 // read my element 00164 reader.readElement("GeometryList"); 00165 // get the value of my attribute 00166 int count = reader.getAttributeAsInteger("count"); 00167 00168 std::vector<Geometry*> values; 00169 values.reserve(count); 00170 for (int i = 0; i < count; i++) { 00171 reader.readElement("Geometry"); 00172 const char* TypeName = reader.getAttribute("type"); 00173 Geometry *newG = (Geometry *)Base::Type::fromName(TypeName).createInstance(); 00174 newG->Restore(reader); 00175 values.push_back(newG); 00176 reader.readEndElement("Geometry"); 00177 } 00178 00179 reader.readEndElement("GeometryList"); 00180 00181 // assignment 00182 setValues(values); 00183 } 00184 00185 Property *PropertyGeometryList::Copy(void) const 00186 { 00187 PropertyGeometryList *p = new PropertyGeometryList(); 00188 p->setValues(_lValueList); 00189 return p; 00190 } 00191 00192 void PropertyGeometryList::Paste(const Property &from) 00193 { 00194 const PropertyGeometryList& FromList = dynamic_cast<const PropertyGeometryList&>(from); 00195 setValues(FromList._lValueList); 00196 } 00197 00198 unsigned int PropertyGeometryList::getMemSize(void) const 00199 { 00200 int size = sizeof(PropertyGeometryList); 00201 for (int i = 0; i < getSize(); i++) 00202 size += _lValueList[i]->getMemSize(); 00203 return size; 00204 }