diff --git a/src/Mod/Part/App/AppPart.cpp b/src/Mod/Part/App/AppPart.cpp index 8931199413..c4db9845ab 100644 --- a/src/Mod/Part/App/AppPart.cpp +++ b/src/Mod/Part/App/AppPart.cpp @@ -126,6 +126,7 @@ #include "OCCError.h" #include "PrismExtension.h" #include "PropertyGeometryList.h" +#include "PropertyTopoShapeList.h" #include @@ -396,6 +397,7 @@ PyMOD_INIT_FUNC(Part) Part::PropertyGeometryList ::init(); Part::PropertyShapeHistory ::init(); Part::PropertyFilletEdges ::init(); + Part::PropertyTopoShapeList ::init(); Part::FaceMaker ::init(); Part::FaceMakerPublic ::init(); diff --git a/src/Mod/Part/App/CMakeLists.txt b/src/Mod/Part/App/CMakeLists.txt index 3134bd062b..fa3627600d 100644 --- a/src/Mod/Part/App/CMakeLists.txt +++ b/src/Mod/Part/App/CMakeLists.txt @@ -229,6 +229,8 @@ SET(Properties_SRCS PropertyTopoShape.h PropertyGeometryList.cpp PropertyGeometryList.h + PropertyTopoShapeList.cpp + PropertyTopoShapeList.h ) SOURCE_GROUP("Properties" FILES ${Properties_SRCS}) diff --git a/src/Mod/Part/App/PropertyTopoShapeList.cpp b/src/Mod/Part/App/PropertyTopoShapeList.cpp new file mode 100644 index 0000000000..5e93dcd4d6 --- /dev/null +++ b/src/Mod/Part/App/PropertyTopoShapeList.cpp @@ -0,0 +1,193 @@ +/*************************************************************************** + * Copyright (c) 2023 WandererFan * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" + +#include +#include +#include + +#include "TopoShapePy.h" +#include "Part2DObject.h" + +#include "PropertyTopoShapeList.h" + +using namespace App; +using namespace Base; +using namespace std; +using namespace Part; + + +//************************************************************************** +// PropertyTopoShapeList +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TYPESYSTEM_SOURCE(Part::PropertyTopoShapeList, App::PropertyLists) + +//************************************************************************** +// Construction/Destruction + +PropertyTopoShapeList::PropertyTopoShapeList() +{ + +} + +PropertyTopoShapeList::~PropertyTopoShapeList() +{ + for (std::vector::iterator it = _lValueList.begin(); it != _lValueList.end(); ++it) + if (*it) delete *it; +} + +void PropertyTopoShapeList::setSize(int newSize) +{ + for (unsigned int i = newSize; i < _lValueList.size(); i++) + delete _lValueList[i]; + _lValueList.resize(newSize); +} + +int PropertyTopoShapeList::getSize() const +{ + return static_cast(_lValueList.size()); +} + +void PropertyTopoShapeList::setValue(TopoShape* lValue) +{ + if (lValue) { + aboutToSetValue(); + _lValueList.resize(1); + _lValueList[0] = lValue; + hasSetValue(); + } +} + +void PropertyTopoShapeList::setValues(const std::vector& lValue) +{ + aboutToSetValue(); + _lValueList.resize(lValue.size()); + for (unsigned int i = 0; i < lValue.size(); i++) + _lValueList[i] = lValue[i]; + hasSetValue(); +} + +PyObject *PropertyTopoShapeList::getPyObject() +{ + PyObject* list = PyList_New(getSize()); + for (int i = 0; i < getSize(); i++) + PyList_SetItem( list, i, _lValueList[i]->getPyObject()); + return list; +} + + +void PropertyTopoShapeList::setPyObject(PyObject *value) +{ + // check container of this property to notify about changes + Part2DObject* part2d = dynamic_cast(this->getContainer()); + + if (PySequence_Check(value)) { + Py_ssize_t nSize = PySequence_Size(value); + std::vector values; + values.resize(nSize); + + for (Py_ssize_t i=0; i < nSize; ++i) { + PyObject* item = PySequence_GetItem(value, i); + if (!PyObject_TypeCheck(item, &(TopoShapePy::Type))) { + std::string error = std::string("types in list must be 'Shape', not "); + error += item->ob_type->tp_name; + throw Base::TypeError(error); + } + + values[i] = static_cast(item)->getTopoShapePtr(); + } + + setValues(values); + if (part2d) + part2d->acceptGeometry(); + } + else if (PyObject_TypeCheck(value, &(TopoShapePy::Type))) { + TopoShapePy *pcObject = static_cast(value); + setValue(pcObject->getTopoShapePtr()); + if (part2d) + part2d->acceptGeometry(); + } + else { + std::string error = std::string("type must be 'Shape' or list of 'Shape', not "); + error += value->ob_type->tp_name; + throw Base::TypeError(error); + } +} + +void PropertyTopoShapeList::Save(Writer &writer) const +{ + writer.Stream() << writer.ind() << "" << endl; + writer.incInd(); + for (int i = 0; i < getSize(); i++) { + _lValueList[i]->Save(writer); + } + writer.decInd(); + writer.Stream() << writer.ind() << "" << endl ; +} + +void PropertyTopoShapeList::Restore(Base::XMLReader &reader) +{ + reader.readElement("ShapeList"); + int count = reader.getAttributeAsInteger("count"); + std::vector values; + values.reserve(count); + for (int i = 0; i < count; i++) { + reader.readElement("TopoShape"); + std::string file (reader.getAttribute("file") ); + if (!file.empty()) { + // add file to reader's list of files to be loaded by each newShape's RestoreDocFile() + TopoShape* newShape = new TopoShape(); + values.push_back(newShape); + reader.addFile(file.c_str(), newShape); + } + } + reader.readEndElement("ShapeList"); + + // set the list to the restored values + setValues(std::move(values)); +} + + +App::Property *PropertyTopoShapeList::Copy() const +{ + PropertyTopoShapeList *p = new PropertyTopoShapeList(); + p->setValues(_lValueList); + return p; +} + +void PropertyTopoShapeList::Paste(const Property &from) +{ + const PropertyTopoShapeList& FromList = dynamic_cast(from); + setValues(FromList._lValueList); +} + +unsigned int PropertyTopoShapeList::getMemSize() const +{ + int size = sizeof(PropertyTopoShapeList); + for (int i = 0; i < getSize(); i++) + size += _lValueList[i]->getMemSize(); + return size; +} + + diff --git a/src/Mod/Part/App/PropertyTopoShapeList.h b/src/Mod/Part/App/PropertyTopoShapeList.h new file mode 100644 index 0000000000..17a0aee0c9 --- /dev/null +++ b/src/Mod/Part/App/PropertyTopoShapeList.h @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (c) 2023 Wandererfan * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef PropertyTopoShapeList_H +#define PropertyTopoShapeList_H + +#include + +#include + +#include + + +#include "TopoShape.h" + + +namespace Base { +class Writer; +class XMLReader; +} + +namespace Part +{ +class TopoShape; + +class PartExport PropertyTopoShapeList: public App::PropertyLists +{ + TYPESYSTEM_HEADER_WITH_OVERRIDE(); + +public: + /** + * A constructor. + * A more elaborate description of the constructor. + */ + PropertyTopoShapeList(); + + /** + * A destructor. + * A more elaborate description of the destructor. + */ + ~PropertyTopoShapeList() override; + + void setSize(int newSize) override; + int getSize() const override; + + /** Sets the property + */ + void setValue(TopoShape*); + void setValues(const std::vector&); + + /// index operator + const TopoShape* operator[] (const int idx) const { + return _lValueList[idx]; + } + + const std::vector& getValues() const { + return _lValueList; + } + + PyObject *getPyObject() override; + void setPyObject(PyObject *) override; + + void Save(Base::Writer &writer) const override; + void Restore(Base::XMLReader &reader) override; + + App::Property *Copy() const override; + void Paste(const App::Property &from) override; + + unsigned int getMemSize() const override; + +private: + std::vector _lValueList; +}; + +} // namespace Part + + +#endif // APP_PropertyTopoShapeList_H + + diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index 9b1d3ab9c5..8f6b306170 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -171,6 +171,8 @@ #include #include #include +#include +#include #include "TopoShape.h" #include "BRepOffsetAPI_MakeOffsetFix.h" @@ -994,7 +996,7 @@ void TopoShape::exportBrep(std::ostream& out) const SS.Write(this->_Shape, out); } -void TopoShape::exportBinary(std::ostream& out) +void TopoShape::exportBinary(std::ostream& out) const { // See BinTools_FormatVersion of OCCT 7.6 enum { @@ -1202,20 +1204,57 @@ bool TopoShape::getCenterOfGravity(Base::Vector3d& center) const return true; } -void TopoShape::Save (Base::Writer & ) const +void TopoShape::Save (Base::Writer& writer) const { + if(!writer.isForceXML()) { + //See SaveDocFile(), RestoreDocFile() + // add a filename to the writer's list. Each file on the list is eventually + // processed by SaveDocFile(). + if (writer.getMode("BinaryBrep")) { + writer.Stream() << writer.ind() << "" << std::endl; + } + else { + writer.Stream() << writer.ind() << "" << std::endl; + } + }} + +void TopoShape::Restore(Base::XMLReader& reader) +{ + reader.readElement("TopoShape"); + std::string file (reader.getAttribute("file") ); + + if (!file.empty()) { + // add a filename to the writer's list. Each file on the list is eventually + // processed by RestoreDocFile(). + reader.addFile(file.c_str(),this); + } } -void TopoShape::Restore(Base::XMLReader &) +void TopoShape::SaveDocFile (Base::Writer& writer) const { + if (getShape().IsNull()) { + return; + } + //the writer has already opened a stream with the appropriate filename + if (writer.getMode("BinaryBrep")) { + exportBinary(writer.Stream()); + } else { + exportBrep(writer.Stream()); + } } -void TopoShape::SaveDocFile (Base::Writer &) const -{ -} - -void TopoShape::RestoreDocFile(Base::Reader &) +void TopoShape::RestoreDocFile(Base::Reader& reader) { + Base::FileInfo brep(reader.getFileName()); + if (brep.hasExtension("bin")) { + importBinary(reader); + } else { + importBrep(reader); + } } unsigned int TopoShape_RefCountShapes(const TopoDS_Shape& aShape) diff --git a/src/Mod/Part/App/TopoShape.h b/src/Mod/Part/App/TopoShape.h index bf608f6159..1d86fba488 100644 --- a/src/Mod/Part/App/TopoShape.h +++ b/src/Mod/Part/App/TopoShape.h @@ -212,7 +212,7 @@ public: void exportStep(const char *FileName) const; void exportBrep(const char *FileName) const; void exportBrep(std::ostream&) const; - void exportBinary(std::ostream&); + void exportBinary(std::ostream&) const; void exportStl (const char *FileName, double deflection) const; void exportFaceSet(double, double, const std::vector&, std::ostream&) const; void exportLineSet(std::ostream&) const;