FreeCAD

Форк
0
/
PropertyTopoShapeList.cpp 
276 строк · 9.2 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2023 WandererFan <wandererfan@gmail.com>                *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24

25
#include <BRepBuilderAPI_Copy.hxx>
26

27
#include <Base/Console.h>
28
#include <Base/Reader.h>
29
#include <Base/Writer.h>
30

31
#include "TopoShapePy.h"
32

33
#include "PropertyTopoShapeList.h"
34

35
using namespace App;
36
using namespace Base;
37
using namespace std;
38
using namespace Part;
39

40

41
//**************************************************************************
42
// PropertyTopoShapeList
43
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
44

45
TYPESYSTEM_SOURCE(Part::PropertyTopoShapeList, App::PropertyLists)
46

47
//**************************************************************************
48
// Construction/Destruction
49

50
PropertyTopoShapeList::PropertyTopoShapeList() = default;
51

52
PropertyTopoShapeList::~PropertyTopoShapeList() = default;
53

54
void PropertyTopoShapeList::setSize(int newSize)
55
{
56
    _lValueList.resize(newSize);
57
}
58

59
int PropertyTopoShapeList::getSize() const
60
{
61
    return static_cast<int>(_lValueList.size());
62
}
63

64
// this version of setValue is for the ADD_PROPERTY_TYPE macro to use when creating a
65
// new PropertyTopoShapeList.  In other list properties that use pointers (instead of
66
// references) a nullptr is passed to setValue to initialize the empty list, but we can
67
// not do that with references.
68
void PropertyTopoShapeList::setValue()
69
{
70
    // aboutToSetValue() and hasSetValue() are called in clear() so don't need
71
    // to be called here.
72
    clear();
73
}
74

75
void PropertyTopoShapeList::setValue(const TopoShape &ts)
76
{
77
    aboutToSetValue();
78
    _lValueList.resize(1);
79
    _lValueList[0] = ts;
80
    hasSetValue();
81
}
82

83
void PropertyTopoShapeList::setValues(const std::vector<TopoShape>& lValue)
84
{
85
    aboutToSetValue();
86
    _lValueList.resize(lValue.size());
87
    for (unsigned int i = 0; i < lValue.size(); i++) {
88
        _lValueList[i] = lValue[i];
89
    }
90
    hasSetValue();
91
}
92

93
// clean out the list
94
void PropertyTopoShapeList::clear()
95
{
96
    aboutToSetValue();
97
    _lValueList.clear();
98
    _lValueList.resize(0);
99
    hasSetValue();
100

101
}
102

103
// populate the lists with the TopoShapes that have now finished restoring
104
void PropertyTopoShapeList::afterRestore()
105
{
106
    aboutToSetValue();
107
    _lValueList.clear();
108
    for (auto& entry : m_restorePointers) {
109
        _lValueList.push_back(*entry);
110
    }
111
    hasSetValue();
112

113
    m_restorePointers.clear();
114
    App::PropertyLists::afterRestore();
115
}
116

117
PyObject *PropertyTopoShapeList::getPyObject()
118
{
119
    Py::List list;
120
    for (int i = 0; i < getSize(); i++) {
121
        list.append(Py::asObject(_lValueList[i].getPyObject()));
122
    }
123
    return Py::new_reference_to(list);
124
}
125

126
void PropertyTopoShapeList::setPyObject(PyObject *value)
127
{
128
    if (PySequence_Check(value)) {
129
        Py::Sequence sequence(value);
130
        Py_ssize_t nSize = sequence.size();
131
        std::vector<TopoShape> values;
132
        values.resize(nSize);
133

134
        for (Py_ssize_t i=0; i < nSize; ++i) {
135
            Py::Object item = sequence.getItem(i);
136
            if (!PyObject_TypeCheck(item.ptr(), &(TopoShapePy::Type))) {
137
                std::string error = std::string("types in list must be 'Shape', not ");
138
                error += item.ptr()->ob_type->tp_name;
139
                throw Base::TypeError(error);
140
            }
141

142
            values[i] = *static_cast<TopoShapePy*>(item.ptr())->getTopoShapePtr();
143
        }
144
        setValues(values);
145
    }
146
    else if (PyObject_TypeCheck(value, &(TopoShapePy::Type))) {
147
        TopoShapePy  *pcObject = static_cast<TopoShapePy*>(value);
148
        setValue(*pcObject->getTopoShapePtr());
149
    }
150
    else {
151
        std::string error = std::string("type must be 'Shape' or list of 'Shape', not ");
152
        error += value->ob_type->tp_name;
153
        throw Base::TypeError(error);
154
    }
155
}
156

157
void PropertyTopoShapeList::Save(Writer& writer) const
158
{
159
    writer.Stream() << writer.ind() << "<ShapeList count=\"" << getSize() << "\">" << endl;
160
    writer.incInd();
161
    for (int i = 0; i < getSize(); i++) {
162
        bool binary = writer.getMode("BinaryBrep");
163
        writer.Stream() << writer.ind() << "<TopoShape";
164
        if (!writer.isForceXML()) {
165
            // See SaveDocFile(), RestoreDocFile()
166
            //  add a filename to the writer's list.  Each file on the list is eventually
167
            //  processed by SaveDocFile().
168
            std::string ext(".");
169
            ext += std::to_string(i);
170
            if (binary) {
171
                ext += ".bin";
172
            }
173
            else {
174
                ext += ".brp";
175
            }
176
            writer.Stream() << writer.ind() << " file=\""
177
                            << writer.addFile(getFileName(ext.c_str()).c_str(), this) << "\"/>\n";
178
        }
179
        else if (binary) {
180
            writer.Stream() << " binary=\"1\">\n";
181
            _lValueList[i].exportBinary(writer.beginCharStream());
182
            writer.endCharStream() << writer.ind() << "</TopoShape>\n";
183
        }
184
        else {
185
            writer.Stream() << " brep=\"1\">\n";
186
            _lValueList[i].exportBrep(writer.beginCharStream() << '\n');
187
            writer.endCharStream() << '\n' << writer.ind() << "</TopoShape>\n";
188
        }
189
    }
190
    writer.decInd();
191
    writer.Stream() << writer.ind() << "</ShapeList>" << endl;
192
}
193

194
void PropertyTopoShapeList::SaveDocFile(Base::Writer& writer) const
195
{
196
    Base::FileInfo finfo(writer.ObjectName);
197
    bool binary = finfo.hasExtension("bin");
198
    int index = atoi(Base::FileInfo(finfo.fileNamePure()).extension().c_str());
199
    if (index < 0 || index >= static_cast<int>(_lValueList.size())) {
200
        return;
201
    }
202

203
    const TopoShape& shape = _lValueList[index];
204
    if (binary) {
205
        shape.exportBinary(writer.Stream());
206
    }
207
    else {
208
        shape.exportBrep(writer.Stream());
209
    }
210
}
211

212
void PropertyTopoShapeList::Restore(Base::XMLReader& reader)
213
{
214
    reader.readElement("ShapeList");
215
    int count = reader.getAttributeAsInteger("count");
216
    m_restorePointers.clear();  // just in case
217
    m_restorePointers.reserve(count);
218
    for (int i = 0; i < count; i++) {
219
        auto newShape = std::make_shared<TopoShape>();
220
        reader.readElement("TopoShape");
221
        std::string file(reader.getAttribute("file"));
222
        if (!file.empty()) {
223
            reader.addFile(file.c_str(), this);
224
        }
225
        else if (reader.hasAttribute("binary") && reader.getAttributeAsInteger("binary")) {
226
            newShape->importBinary(reader.beginCharStream());
227
        }
228
        else if (reader.hasAttribute("brep") && reader.getAttributeAsInteger("brep")) {
229
            newShape->importBrep(reader.beginCharStream());
230
        }
231
        m_restorePointers.push_back(newShape);
232
    }
233
    reader.readEndElement("ShapeList");
234
}
235

236
void PropertyTopoShapeList::RestoreDocFile(Base::Reader& reader)
237
{
238
    Base::FileInfo finfo(reader.getFileName());
239
    bool binary = finfo.hasExtension("bin");
240
    int index = atoi(Base::FileInfo(finfo.fileNamePure()).extension().c_str());
241
    if (index < 0 || index >= static_cast<int>(m_restorePointers.size())) {
242
        return;
243
    }
244
    if (binary) {
245
        m_restorePointers[index]->importBinary(reader);
246
    }
247
    else {
248
        m_restorePointers[index]->importBrep(reader);
249
    }
250
}
251

252
App::Property *PropertyTopoShapeList::Copy() const
253
{
254
    PropertyTopoShapeList *p = new PropertyTopoShapeList();
255
    std::vector<TopoShape> copiedShapes;
256
    for (auto& shape : _lValueList) {
257
        BRepBuilderAPI_Copy copy(shape.getShape());
258
        copiedShapes.emplace_back(copy.Shape());
259
    }
260
    p->setValues(copiedShapes);
261
    return p;
262
}
263

264
void PropertyTopoShapeList::Paste(const Property &from)
265
{
266
    const PropertyTopoShapeList& FromList = dynamic_cast<const PropertyTopoShapeList&>(from);
267
    setValues(FromList._lValueList);
268
}
269

270
unsigned int PropertyTopoShapeList::getMemSize() const
271
{
272
    int size = sizeof(PropertyTopoShapeList);
273
    for (int i = 0; i < getSize(); i++)
274
        size += _lValueList[i].getMemSize();
275
    return size;
276
}
277

278

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.