FreeCAD

Форк
0
/
AppDrawingPy.cpp 
384 строки · 15.4 Кб
1
/***************************************************************************
2
 *   Copyright (c) Jürgen Riegel          (juergen.riegel@web.de) 2002     *
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
#ifndef _PreComp_
25
#include <boost/regex.hpp>
26
#endif
27

28
#include <Base/Console.h>
29
#include <Base/Interpreter.h>
30
#include <Base/PyWrapParseTupleAndKeywords.h>
31
#include <Base/VectorPy.h>
32
#include <Mod/Part/App/OCCError.h>
33
#include <Mod/Part/App/TopoShapePy.h>
34

35
#include "ProjectionAlgos.h"
36

37

38
using namespace std;
39
using Part::TopoShape;
40
using Part::TopoShapePy;
41

42
namespace Drawing
43
{
44

45
/** Copies a Python dictionary of Python strings to a C++ container.
46
 *
47
 * After the function call, the key-value pairs of the Python
48
 * dictionary are copied into the target buffer as C++ pairs
49
 * (pair<string, string>).
50
 *
51
 * @param sourceRange is a Python dictionary (Py::Dict). Both, the
52
 * keys and the values must be Python strings.
53
 *
54
 * @param targetIt refers to where the data should be inserted. Must
55
 * be of concept output iterator.
56
 */
57
template<typename OutputIt>
58
void copy(Py::Dict sourceRange, OutputIt targetIt)
59
{
60
    string key;
61
    string value;
62

63
    for (const auto& keyPy : sourceRange.keys()) {
64
        key = Py::String(keyPy);
65
        value = Py::String(sourceRange[keyPy]);
66
        *targetIt = {key, value};
67
        ++targetIt;
68
    }
69
}
70

71

72
class Module: public Py::ExtensionModule<Module>
73
{
74
public:
75
    Module()
76
        : Py::ExtensionModule<Module>("Drawing")
77
    {
78
        add_varargs_method("project",
79
                           &Module::project,
80
                           "[visiblyG0,visiblyG1,hiddenG0,hiddenG1] = "
81
                           "project(TopoShape[,App.Vector Direction, string type])\n"
82
                           " -- Project a shape and return the visible/invisible parts of it.");
83
        add_varargs_method("projectEx",
84
                           &Module::projectEx,
85
                           "[V,V1,VN,VO,VI,H,H1,HN,HO,HI] = projectEx(TopoShape[,App.Vector "
86
                           "Direction, string type])\n"
87
                           " -- Project a shape and return the all parts of it.");
88
        add_keyword_method(
89
            "projectToSVG",
90
            &Module::projectToSVG,
91
            "string = projectToSVG(TopoShape[, App.Vector direction, string type, float tolerance, "
92
            "dict vStyle, dict v0Style, dict v1Style, dict hStyle, dict h0Style, dict h1Style])\n"
93
            " -- Project a shape and return the SVG representation as string.");
94
        add_varargs_method("projectToDXF",
95
                           &Module::projectToDXF,
96
                           "string = projectToDXF(TopoShape[,App.Vector Direction, string type])\n"
97
                           " -- Project a shape and return the DXF representation as string.");
98
        add_varargs_method(
99
            "removeSvgTags",
100
            &Module::removeSvgTags,
101
            "string = removeSvgTags(string) -- Removes the opening and closing svg tags\n"
102
            "and other metatags from a svg code, making it embeddable");
103
        initialize("This module is the Drawing module.");  // register with Python
104
    }
105

106
    virtual ~Module()
107
    {}
108

109
private:
110
    virtual Py::Object invoke_method_varargs(void* method_def, const Py::Tuple& args)
111
    {
112
        try {
113
            return Py::ExtensionModule<Module>::invoke_method_varargs(method_def, args);
114
        }
115
        catch (const Standard_Failure& e) {
116
            std::string str;
117
            Standard_CString msg = e.GetMessageString();
118
            str += typeid(e).name();
119
            str += " ";
120
            if (msg) {
121
                str += msg;
122
            }
123
            else {
124
                str += "No OCCT Exception Message";
125
            }
126
            Base::Console().Error("%s\n", str.c_str());
127
            throw Py::Exception(Part::PartExceptionOCCError, str);
128
        }
129
        catch (const Base::Exception& e) {
130
            std::string str;
131
            str += "FreeCAD exception thrown (";
132
            str += e.what();
133
            str += ")";
134
            e.ReportException();
135
            throw Py::RuntimeError(str);
136
        }
137
        catch (const std::exception& e) {
138
            std::string str;
139
            str += "C++ exception thrown (";
140
            str += e.what();
141
            str += ")";
142
            Base::Console().Error("%s\n", str.c_str());
143
            throw Py::RuntimeError(str);
144
        }
145
    }
146
    Py::Object project(const Py::Tuple& args)
147
    {
148
        PyObject* pcObjShape;
149
        PyObject* pcObjDir = nullptr;
150

151
        if (!PyArg_ParseTuple(args.ptr(),
152
                              "O!|O!",
153
                              &(Part::TopoShapePy::Type),
154
                              &pcObjShape,
155
                              &(Base::VectorPy::Type),
156
                              &pcObjDir)) {
157
            throw Py::Exception();
158
        }
159

160
        Part::TopoShapePy* pShape = static_cast<Part::TopoShapePy*>(pcObjShape);
161
        Base::Vector3d Vector(0, 0, 1);
162
        if (pcObjDir) {
163
            Vector = *static_cast<Base::VectorPy*>(pcObjDir)->getVectorPtr();
164
        }
165

166
        ProjectionAlgos Alg(pShape->getTopoShapePtr()->getShape(), Vector);
167

168
        Py::List list;
169
        list.append(Py::Object(new Part::TopoShapePy(new Part::TopoShape(Alg.V)), true));
170
        list.append(Py::Object(new Part::TopoShapePy(new Part::TopoShape(Alg.V1)), true));
171
        list.append(Py::Object(new Part::TopoShapePy(new Part::TopoShape(Alg.H)), true));
172
        list.append(Py::Object(new Part::TopoShapePy(new Part::TopoShape(Alg.H1)), true));
173

174
        return list;
175
    }
176
    Py::Object projectEx(const Py::Tuple& args)
177
    {
178
        PyObject* pcObjShape;
179
        PyObject* pcObjDir = nullptr;
180

181
        if (!PyArg_ParseTuple(args.ptr(),
182
                              "O!|O!",
183
                              &(TopoShapePy::Type),
184
                              &pcObjShape,
185
                              &(Base::VectorPy::Type),
186
                              &pcObjDir)) {
187
            throw Py::Exception();
188
        }
189

190
        TopoShapePy* pShape = static_cast<TopoShapePy*>(pcObjShape);
191
        Base::Vector3d Vector(0, 0, 1);
192
        if (pcObjDir) {
193
            Vector = *static_cast<Base::VectorPy*>(pcObjDir)->getVectorPtr();
194
        }
195

196
        ProjectionAlgos Alg(pShape->getTopoShapePtr()->getShape(), Vector);
197

198
        Py::List list;
199
        list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.V)), true));
200
        list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.V1)), true));
201
        list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.VN)), true));
202
        list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.VO)), true));
203
        list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.VI)), true));
204
        list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.H)), true));
205
        list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.H1)), true));
206
        list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.HN)), true));
207
        list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.HO)), true));
208
        list.append(Py::Object(new TopoShapePy(new TopoShape(Alg.HI)), true));
209

210
        return list;
211
    }
212

213
    Py::Object projectToSVG(const Py::Tuple& args, const Py::Dict& keys)
214
    {
215
        static const std::array<const char*, 11> argNames {"topoShape",
216
                                                           "direction",
217
                                                           "type",
218
                                                           "tolerance",
219
                                                           "vStyle",
220
                                                           "v0Style",
221
                                                           "v1Style",
222
                                                           "hStyle",
223
                                                           "h0Style",
224
                                                           "h1Style",
225
                                                           nullptr};
226
        PyObject* pcObjShape = nullptr;
227
        PyObject* pcObjDir = nullptr;
228
        const char* extractionTypePy = nullptr;
229
        ProjectionAlgos::ExtractionType extractionType = ProjectionAlgos::Plain;
230
        const float tol = 0.1f;
231
        PyObject* vStylePy = nullptr;
232
        ProjectionAlgos::XmlAttributes vStyle;
233
        PyObject* v0StylePy = nullptr;
234
        ProjectionAlgos::XmlAttributes v0Style;
235
        PyObject* v1StylePy = nullptr;
236
        ProjectionAlgos::XmlAttributes v1Style;
237
        PyObject* hStylePy = nullptr;
238
        ProjectionAlgos::XmlAttributes hStyle;
239
        PyObject* h0StylePy = nullptr;
240
        ProjectionAlgos::XmlAttributes h0Style;
241
        PyObject* h1StylePy = nullptr;
242
        ProjectionAlgos::XmlAttributes h1Style;
243

244
        // Get the arguments
245

246
        if (!Base::Wrapped_ParseTupleAndKeywords(args.ptr(),
247
                                                 keys.ptr(),
248
                                                 "O!|O!sfOOOOOO",
249
                                                 argNames,
250
                                                 &(TopoShapePy::Type),
251
                                                 &pcObjShape,
252
                                                 &(Base::VectorPy::Type),
253
                                                 &pcObjDir,
254
                                                 &extractionTypePy,
255
                                                 &tol,
256
                                                 &vStylePy,
257
                                                 &v0StylePy,
258
                                                 &v1StylePy,
259
                                                 &hStylePy,
260
                                                 &h0StylePy,
261
                                                 &h1StylePy)) {
262

263
            throw Py::Exception();
264
        }
265

266
        // Convert all arguments into the right format
267

268
        TopoShapePy* pShape = static_cast<TopoShapePy*>(pcObjShape);
269

270
        Base::Vector3d directionVector(0, 0, 1);
271
        if (pcObjDir) {
272
            directionVector = static_cast<Base::VectorPy*>(pcObjDir)->value();
273
        }
274

275
        if (extractionTypePy && string(extractionTypePy) == "ShowHiddenLines") {
276
            extractionType = ProjectionAlgos::WithHidden;
277
        }
278

279
        if (vStylePy) {
280
            copy(Py::Dict(vStylePy), inserter(vStyle, vStyle.begin()));
281
        }
282
        if (v0StylePy) {
283
            copy(Py::Dict(v0StylePy), inserter(v0Style, v0Style.begin()));
284
        }
285
        if (v1StylePy) {
286
            copy(Py::Dict(v1StylePy), inserter(v1Style, v1Style.begin()));
287
        }
288
        if (hStylePy) {
289
            copy(Py::Dict(hStylePy), inserter(hStyle, hStyle.begin()));
290
        }
291
        if (h0StylePy) {
292
            copy(Py::Dict(h0StylePy), inserter(h0Style, h0Style.begin()));
293
        }
294
        if (h1StylePy) {
295
            copy(Py::Dict(h1StylePy), inserter(h1Style, h1Style.begin()));
296
        }
297

298
        // Execute the SVG generation
299

300
        ProjectionAlgos Alg(pShape->getTopoShapePtr()->getShape(), directionVector);
301
        Py::String result(
302
            Alg.getSVG(extractionType, tol, vStyle, v0Style, v1Style, hStyle, h0Style, h1Style));
303
        return result;
304
    }
305

306
    Py::Object projectToDXF(const Py::Tuple& args)
307
    {
308
        PyObject* pcObjShape;
309
        PyObject* pcObjDir = nullptr;
310
        const char* type = nullptr;
311
        float scale = 1.0f;
312
        float tol = 0.1f;
313

314
        if (!PyArg_ParseTuple(args.ptr(),
315
                              "O!|O!sff",
316
                              &(TopoShapePy::Type),
317
                              &pcObjShape,
318
                              &(Base::VectorPy::Type),
319
                              &pcObjDir,
320
                              &type,
321
                              &scale,
322
                              &tol)) {
323
            throw Py::Exception();
324
        }
325

326
        TopoShapePy* pShape = static_cast<TopoShapePy*>(pcObjShape);
327
        Base::Vector3d Vector(0, 0, 1);
328
        if (pcObjDir) {
329
            Vector = static_cast<Base::VectorPy*>(pcObjDir)->value();
330
        }
331
        ProjectionAlgos Alg(pShape->getTopoShapePtr()->getShape(), Vector);
332

333
        bool hidden = false;
334
        if (type && std::string(type) == "ShowHiddenLines") {
335
            hidden = true;
336
        }
337

338
        Py::String result(
339
            Alg.getDXF(hidden ? ProjectionAlgos::WithHidden : ProjectionAlgos::Plain, scale, tol));
340
        return result;
341
    }
342
    Py::Object removeSvgTags(const Py::Tuple& args)
343
    {
344
        const char* svgcode;
345
        if (!PyArg_ParseTuple(args.ptr(), "s", &svgcode)) {
346
            throw Py::Exception();
347
        }
348

349
        std::string svg(svgcode);
350
        std::string empty = "";
351
        std::string endline = "--endOfLine--";
352
        std::string linebreak = "\\n";
353
        // removing linebreaks for regex to work
354
        boost::regex e1("\\n");
355
        svg = boost::regex_replace(svg, e1, endline);
356
        // removing starting xml definition
357
        boost::regex e2("<\\?xml.*?\\?>");
358
        svg = boost::regex_replace(svg, e2, empty);
359
        // removing starting svg tag
360
        boost::regex e3("<svg.*?>");
361
        svg = boost::regex_replace(svg, e3, empty);
362
        // removing sodipodi tags -- DANGEROUS, some sodipodi tags are single, better leave it
363
        // boost::regex e4 ("<sodipodi.*?>");
364
        // svg = boost::regex_replace(svg, e4, empty);
365
        // removing metadata tags
366
        boost::regex e5("<metadata.*?</metadata>");
367
        svg = boost::regex_replace(svg, e5, empty);
368
        // removing closing svg tags
369
        boost::regex e6("</svg>");
370
        svg = boost::regex_replace(svg, e6, empty);
371
        // restoring linebreaks
372
        boost::regex e7("--endOfLine--");
373
        svg = boost::regex_replace(svg, e7, linebreak);
374
        Py::String result(svg);
375
        return result;
376
    }
377
};
378

379
PyObject* initModule()
380
{
381
    return Base::Interpreter().addModule(new Module);
382
}
383

384
}  // namespace Drawing
385

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

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

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

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