FreeCAD

Форк
0
/
AppMeshPy.cpp 
638 строк · 24.4 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2004 Werner Mayer <wmayer[at]users.sourceforge.net>     *
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 <algorithm>
26
#include <map>
27
#include <memory>
28
#endif
29

30
#include <App/Application.h>
31
#include <App/Document.h>
32
#include <App/DocumentObjectPy.h>
33
#include <Base/GeometryPyCXX.h>
34
#include <Base/Interpreter.h>
35
#include <Base/PlacementPy.h>
36
#include <Base/PyWrapParseTupleAndKeywords.h>
37
#include <Base/VectorPy.h>
38
#include "Core/Approximation.h"
39
#include "Core/Evaluation.h"
40
#include "Core/Iterator.h"
41
#include "Core/MeshIO.h"
42
#include "Core/MeshKernel.h"
43
#include "WildMagic4/Wm4ContBox3.h"
44

45
#include "Exporter.h"
46
#include "Importer.h"
47
#include "Mesh.h"
48
#include "MeshPy.h"
49

50

51
using namespace Mesh;
52
using namespace MeshCore;
53

54
namespace Mesh
55
{
56
class Module: public Py::ExtensionModule<Module>
57
{
58
public:
59
    Module()
60
        : Py::ExtensionModule<Module>("Mesh")
61
    {
62
        add_varargs_method("read",
63
                           &Module::read,
64
                           "Read a mesh from a file and returns a Mesh object.");
65
        add_varargs_method("open",
66
                           &Module::open,
67
                           "open(string)\n"
68
                           "Create a new document and a Mesh feature to load the file into\n"
69
                           "the document.");
70
        add_varargs_method("insert",
71
                           &Module::importer,
72
                           "insert(string|mesh,[string])\n"
73
                           "Load or insert a mesh into the given or active document.");
74
        add_keyword_method("export",
75
                           &Module::exporter,
76
                           "export(objects, filename, [tolerance=0.1, exportAmfCompressed=True])\n"
77
                           "Export a list of objects into a single file identified by filename.\n"
78
                           "tolerance is in mm and specifies the maximum acceptable deviation\n"
79
                           "between the specified objects and the exported mesh.\n"
80
                           "exportAmfCompressed specifies whether exported AMF files should be\n"
81
                           "compressed.\n");
82
        add_varargs_method("show",
83
                           &Module::show,
84
                           "show(shape,[string]) -- Add the mesh to the active document or create "
85
                           "one if no document exists.");
86
        add_varargs_method("createBox", &Module::createBox, "Create a solid mesh box");
87
        add_varargs_method("createPlane", &Module::createPlane, "Create a mesh XY plane normal +Z");
88
        add_varargs_method("createSphere", &Module::createSphere, "Create a tessellated sphere");
89
        add_varargs_method("createEllipsoid",
90
                           &Module::createEllipsoid,
91
                           "Create a tessellated ellipsoid");
92
        add_varargs_method("createCylinder",
93
                           &Module::createCylinder,
94
                           "Create a tessellated cylinder");
95
        add_varargs_method("createCone", &Module::createCone, "Create a tessellated cone");
96
        add_varargs_method("createTorus", &Module::createTorus, "Create a tessellated torus");
97
        add_varargs_method("calculateEigenTransform",
98
                           &Module::calculateEigenTransform,
99
                           "calculateEigenTransform(seq(Base.Vector))\n"
100
                           "Calculates the eigen Transformation from a list of points.\n"
101
                           "calculate the point's local coordinate system with the center\n"
102
                           "of gravity as origin. The local coordinate system is computed\n"
103
                           "this way that u has minimum and w has maximum expansion.\n"
104
                           "The local coordinate system is right-handed.\n");
105
        add_varargs_method("polynomialFit",
106
                           &Module::polynomialFit,
107
                           "polynomialFit(seq(Base.Vector)) -- Calculates a polynomial fit.");
108
        add_varargs_method(
109
            "minimumVolumeOrientedBox",
110
            &Module::minimumVolumeOrientedBox,
111
            "minimumVolumeOrientedBox(seq(Base.Vector)) -- Calculates the minimum\n"
112
            "volume oriented box containing all points. The return value is a\n"
113
            "tuple of seven items:\n"
114
            "    center, u, v, w directions and the lengths of the three vectors.\n");
115
        initialize("The functions in this module allow working with mesh objects.\n"
116
                   "A set of functions are provided for reading in registered mesh\n"
117
                   "file formats to either a new or existing document.\n"
118
                   "\n"
119
                   "open(string) -- Create a new document and a Mesh feature\n"
120
                   "                to load the file into the document.\n"
121
                   "insert(string, string) -- Create a Mesh feature to load\n"
122
                   "                          the file into the given document.\n"
123
                   "Mesh() -- Create an empty mesh object.\n"
124
                   "\n");
125
    }
126

127
private:
128
    Py::Object invoke_method_varargs(void* method_def, const Py::Tuple& args) override
129
    {
130
        try {
131
            return Py::ExtensionModule<Module>::invoke_method_varargs(method_def, args);
132
        }
133
        catch (const Base::Exception& e) {
134
            throw Py::RuntimeError(e.what());
135
        }
136
        catch (const std::exception& e) {
137
            throw Py::RuntimeError(e.what());
138
        }
139
    }
140
    Py::Object read(const Py::Tuple& args)
141
    {
142
        char* Name {};
143
        if (!PyArg_ParseTuple(args.ptr(), "et", "utf-8", &Name)) {
144
            throw Py::Exception();
145
        }
146
        std::string EncodedName = std::string(Name);
147
        PyMem_Free(Name);
148

149
        std::unique_ptr<MeshObject> mesh(new MeshObject);
150
        mesh->load(EncodedName.c_str());
151
        return Py::asObject(new MeshPy(mesh.release()));
152
    }
153
    Py::Object open(const Py::Tuple& args)
154
    {
155
        char* Name {};
156
        if (!PyArg_ParseTuple(args.ptr(), "et", "utf-8", &Name)) {
157
            throw Py::Exception();
158
        }
159

160
        std::string EncodedName = std::string(Name);
161
        PyMem_Free(Name);
162

163
        // create new document and add Import feature
164
        App::Document* pcDoc = App::GetApplication().newDocument();
165

166
        Mesh::Importer import(pcDoc);
167
        import.load(EncodedName);
168

169
        return Py::None();
170
    }
171
    Py::Object importer(const Py::Tuple& args)
172
    {
173
        char* Name {};
174
        char* DocName = nullptr;
175
        if (!PyArg_ParseTuple(args.ptr(), "et|s", "utf-8", &Name, &DocName)) {
176
            throw Py::Exception();
177
        }
178

179
        std::string EncodedName = std::string(Name);
180
        PyMem_Free(Name);
181

182
        App::Document* pcDoc = nullptr;
183
        if (DocName) {
184
            pcDoc = App::GetApplication().getDocument(DocName);
185
        }
186
        else {
187
            pcDoc = App::GetApplication().getActiveDocument();
188
        }
189

190
        if (!pcDoc) {
191
            pcDoc = App::GetApplication().newDocument(DocName);
192
        }
193

194
        Mesh::Importer import(pcDoc);
195
        import.load(EncodedName);
196

197
        return Py::None();
198
    }
199

200
    Py::Object exporter(const Py::Tuple& args, const Py::Dict& keywds)
201
    {
202
        PyObject* objects {};
203
        char* fileNamePy {};
204

205
        // If tolerance is specified via python interface, use that.
206
        // If not, use the preference, if that exists, else default to 0.1mm.
207
        auto hGrp(App::GetApplication().GetParameterGroupByPath(
208
            "User parameter:BaseApp/Preferences/Mod/Mesh"));
209
        auto fTolerance(hGrp->GetFloat("MaxDeviationExport", 0.1f));
210

211
        int exportAmfCompressed(hGrp->GetBool("ExportAmfCompressed", true));
212
        bool export3mfModel(hGrp->GetBool("Export3mfModel", true));
213

214
        static const std::array<const char*, 5> kwList {"objectList",
215
                                                        "filename",
216
                                                        "tolerance",
217
                                                        "exportAmfCompressed",
218
                                                        nullptr};
219

220
        if (!Base::Wrapped_ParseTupleAndKeywords(args.ptr(),
221
                                                 keywds.ptr(),
222
                                                 "Oet|dp",
223
                                                 kwList,
224
                                                 &objects,
225
                                                 "utf-8",
226
                                                 &fileNamePy,
227
                                                 &fTolerance,
228
                                                 &exportAmfCompressed)) {
229
            throw Py::Exception();
230
        }
231

232
        std::string outputFileName(fileNamePy);
233
        PyMem_Free(fileNamePy);
234

235
        // Construct list of objects to export before making the Exporter, so
236
        // we don't get empty exports if the list can't be constructed.
237
        Py::Sequence list(objects);
238
        if (list.length() == 0) {
239
            return Py::None();
240
        }
241

242
        // collect all object types that can be exported as mesh
243
        std::vector<App::DocumentObject*> objectList;
244
        for (const auto& it : list) {
245
            PyObject* item = it.ptr();
246
            if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
247
                auto obj(static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr());
248
                objectList.push_back(obj);
249
            }
250
        }
251

252
        if (objectList.empty()) {
253
            throw Py::TypeError("None of the objects can be exported to a mesh file");
254
        }
255

256
        auto exportFormat(MeshOutput::GetFormat(outputFileName.c_str()));
257

258
        std::unique_ptr<Exporter> exporter;
259
        if (exportFormat == MeshIO::AMF) {
260
            std::map<std::string, std::string> meta;
261
            meta["cad"] = App::Application::Config()["ExeName"] + " "
262
                + App::Application::Config()["ExeVersion"];
263
            meta[App::Application::Config()["ExeName"] + "-buildRevisionHash"] =
264
                App::Application::Config()["BuildRevisionHash"];
265

266
            exporter = std::make_unique<ExporterAMF>(outputFileName, meta, exportAmfCompressed);
267
        }
268
        else if (exportFormat == MeshIO::ThreeMF) {
269
            Extension3MFFactory::initialize();
270
            exporter = std::make_unique<Exporter3MF>(outputFileName,
271
                                                     Extension3MFFactory::createExtensions());
272
            dynamic_cast<Exporter3MF*>(exporter.get())->setForceModel(export3mfModel);
273
        }
274
        else if (exportFormat != MeshIO::Undefined) {
275
            exporter = std::make_unique<MergeExporter>(outputFileName, exportFormat);
276
        }
277
        else {
278
            std::string exStr("Can't determine mesh format from file name.\nPlease specify mesh "
279
                              "format file extension: '");
280
            exStr += outputFileName + "'";
281
            throw Py::ValueError(exStr.c_str());
282
        }
283

284
        for (auto it : objectList) {
285
            exporter->addObject(it, fTolerance);
286
        }
287

288
        exporter.reset();  // deletes Exporter, mesh file is written by destructor
289

290
        return Py::None();
291
    }
292

293
    Py::Object show(const Py::Tuple& args)
294
    {
295
        PyObject* pcObj {};
296
        const char* name = "Mesh";
297
        if (!PyArg_ParseTuple(args.ptr(), "O!|s", &(MeshPy::Type), &pcObj, &name)) {
298
            throw Py::Exception();
299
        }
300

301
        App::Document* pcDoc = App::GetApplication().getActiveDocument();
302
        if (!pcDoc) {
303
            pcDoc = App::GetApplication().newDocument();
304
        }
305
        MeshPy* pMesh = static_cast<MeshPy*>(pcObj);
306
        Mesh::Feature* pcFeature =
307
            static_cast<Mesh::Feature*>(pcDoc->addObject("Mesh::Feature", name));
308
        Mesh::MeshObject* mo = pMesh->getMeshObjectPtr();
309
        if (!mo) {
310
            throw Py::Exception(PyExc_ReferenceError, "object doesn't reference a valid mesh");
311
        }
312
        // copy the data
313
        pcFeature->Mesh.setValue(*mo);
314

315
        return Py::None();
316
    }
317
    Py::Object createBox(const Py::Tuple& args)
318
    {
319
        MeshObject* mesh = nullptr;
320

321
        do {
322
            float length = 10.0f;
323
            float width = 10.0f;
324
            float height = 10.0f;
325
            float edgelen = -1.0f;
326
            if (PyArg_ParseTuple(args.ptr(), "|ffff", &length, &width, &height, &edgelen)) {
327
                if (edgelen < 0.0f) {
328
                    mesh = MeshObject::createCube(length, width, height);
329
                }
330
                else {
331
                    mesh = MeshObject::createCube(length, width, height, edgelen);
332
                }
333
                break;
334
            }
335

336
            PyErr_Clear();
337
            PyObject* box {};
338
            if (PyArg_ParseTuple(args.ptr(), "O!", &Base::BoundBoxPy::Type, &box)) {
339
                Py::BoundingBox bbox(box, false);
340
                mesh = MeshObject::createCube(bbox.getValue());
341
                break;
342
            }
343

344
            throw Py::TypeError("Must be real numbers or BoundBox");
345
        } while (false);
346
        if (!mesh) {
347
            throw Py::RuntimeError("Creation of box failed");
348
        }
349
        return Py::asObject(new MeshPy(mesh));
350
    }
351
    Py::Object createPlane(const Py::Tuple& args)
352
    {
353
        float x = 1, y = 0, z = 0;
354
        if (!PyArg_ParseTuple(args.ptr(), "|fff", &x, &y, &z)) {
355
            throw Py::Exception();
356
        }
357

358
        if (y == 0) {
359
            y = x;
360
        }
361

362
        float hx = x / 2.0f;
363
        float hy = y / 2.0f;
364

365
        std::vector<MeshCore::MeshGeomFacet> TriaList;
366
        TriaList.emplace_back(Base::Vector3f(-hx, -hy, 0.0),
367
                              Base::Vector3f(hx, hy, 0.0),
368
                              Base::Vector3f(-hx, hy, 0.0));
369
        TriaList.emplace_back(Base::Vector3f(-hx, -hy, 0.0),
370
                              Base::Vector3f(hx, -hy, 0.0),
371
                              Base::Vector3f(hx, hy, 0.0));
372

373
        std::unique_ptr<MeshObject> mesh(new MeshObject);
374
        mesh->addFacets(TriaList);
375
        return Py::asObject(new MeshPy(mesh.release()));
376
    }
377
    Py::Object createSphere(const Py::Tuple& args)
378
    {
379
        float radius = 5.0f;
380
        int sampling = 50;
381
        if (!PyArg_ParseTuple(args.ptr(), "|fi", &radius, &sampling)) {
382
            throw Py::Exception();
383
        }
384

385
        MeshObject* mesh = MeshObject::createSphere(radius, sampling);
386
        if (!mesh) {
387
            throw Py::RuntimeError("Creation of sphere failed");
388
        }
389
        return Py::asObject(new MeshPy(mesh));
390
    }
391
    Py::Object createEllipsoid(const Py::Tuple& args)
392
    {
393
        float radius1 = 2.0f;
394
        float radius2 = 4.0f;
395
        int sampling = 50;
396
        if (!PyArg_ParseTuple(args.ptr(), "|ffi", &radius1, &radius2, &sampling)) {
397
            throw Py::Exception();
398
        }
399

400
        MeshObject* mesh = MeshObject::createEllipsoid(radius1, radius2, sampling);
401
        if (!mesh) {
402
            throw Py::RuntimeError("Creation of ellipsoid failed");
403
        }
404
        return Py::asObject(new MeshPy(mesh));
405
    }
406
    Py::Object createCylinder(const Py::Tuple& args)
407
    {
408
        float radius = 2.0f;
409
        float length = 10.0f;
410
        int closed = 1;
411
        float edgelen = 1.0f;
412
        int sampling = 50;
413
        if (!PyArg_ParseTuple(args.ptr(),
414
                              "|ffifi",
415
                              &radius,
416
                              &length,
417
                              &closed,
418
                              &edgelen,
419
                              &sampling)) {
420
            throw Py::Exception();
421
        }
422

423
        MeshObject* mesh = MeshObject::createCylinder(radius, length, closed, edgelen, sampling);
424
        if (!mesh) {
425
            throw Py::RuntimeError("Creation of cylinder failed");
426
        }
427
        return Py::asObject(new MeshPy(mesh));
428
    }
429
    Py::Object createCone(const Py::Tuple& args)
430
    {
431
        float radius1 = 2.0f;
432
        float radius2 = 4.0f;
433
        float len = 10.0f;
434
        int closed = 1;
435
        float edgelen = 1.0f;
436
        int sampling = 50;
437
        if (!PyArg_ParseTuple(args.ptr(),
438
                              "|fffifi",
439
                              &radius1,
440
                              &radius2,
441
                              &len,
442
                              &closed,
443
                              &edgelen,
444
                              &sampling)) {
445
            throw Py::Exception();
446
        }
447

448
        MeshObject* mesh = MeshObject::createCone(radius1, radius2, len, closed, edgelen, sampling);
449
        if (!mesh) {
450
            throw Py::RuntimeError("Creation of cone failed");
451
        }
452
        return Py::asObject(new MeshPy(mesh));
453
    }
454
    Py::Object createTorus(const Py::Tuple& args)
455
    {
456
        float radius1 = 10.0f;
457
        float radius2 = 2.0f;
458
        int sampling = 50;
459
        if (!PyArg_ParseTuple(args.ptr(), "|ffi", &radius1, &radius2, &sampling)) {
460
            throw Py::Exception();
461
        }
462

463
        MeshObject* mesh = MeshObject::createTorus(radius1, radius2, sampling);
464
        if (!mesh) {
465
            throw Py::RuntimeError("Creation of torus failed");
466
        }
467
        return Py::asObject(new MeshPy(mesh));
468
    }
469
    Py::Object calculateEigenTransform(const Py::Tuple& args)
470
    {
471
        PyObject* input {};
472

473
        if (!PyArg_ParseTuple(args.ptr(), "O", &input)) {
474
            throw Py::Exception();
475
        }
476

477
        if (!PySequence_Check(input)) {
478
            throw Py::TypeError("Input has to be a sequence of Base.Vector()");
479
        }
480

481
        MeshCore::MeshKernel aMesh;
482
        MeshCore::MeshPointArray vertices;
483
        vertices.clear();
484
        MeshCore::MeshFacetArray faces;
485
        faces.clear();
486
        MeshCore::MeshPoint current_node;
487

488
        Py::Sequence list(input);
489
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
490
            PyObject* value = (*it).ptr();
491
            if (PyObject_TypeCheck(value, &(Base::VectorPy::Type))) {
492
                Base::VectorPy* pcObject = static_cast<Base::VectorPy*>(value);
493
                Base::Vector3d* val = pcObject->getVectorPtr();
494

495

496
                current_node.Set(float(val->x), float(val->y), float(val->z));
497
                vertices.push_back(current_node);
498
            }
499
        }
500

501
        MeshCore::MeshFacet aFacet;
502
        aFacet._aulPoints[0] = 0;
503
        aFacet._aulPoints[1] = 1;
504
        aFacet._aulPoints[2] = 2;
505
        faces.push_back(aFacet);
506
        // Fill the Kernel with the temp mesh structure and delete the current containers
507
        aMesh.Adopt(vertices, faces);
508
        MeshCore::MeshEigensystem pca(aMesh);
509
        pca.Evaluate();
510
        Base::Matrix4D Trafo = pca.Transform();
511

512
        return Py::asObject(new Base::PlacementPy(new Base::Placement(Trafo)));
513
    }
514
    Py::Object polynomialFit(const Py::Tuple& args)
515
    {
516
        PyObject* input {};
517

518
        if (!PyArg_ParseTuple(args.ptr(), "O", &input)) {
519
            throw Py::Exception();
520
        }
521

522
        if (!PySequence_Check(input)) {
523
            throw Py::TypeError("Input has to be a sequence of Base.Vector()");
524
        }
525

526
        MeshCore::SurfaceFit polyFit;
527

528
        Base::Vector3f point;
529
        Py::Sequence list(input);
530
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
531
            PyObject* value = (*it).ptr();
532
            if (PyObject_TypeCheck(value, &(Base::VectorPy::Type))) {
533
                Base::VectorPy* pcObject = static_cast<Base::VectorPy*>(value);
534
                Base::Vector3d* val = pcObject->getVectorPtr();
535
                point.Set(float(val->x), float(val->y), float(val->z));
536
                polyFit.AddPoint(point);
537
            }
538
        }
539

540
        // fit quality
541
        float fit = polyFit.Fit();
542
        Py::Dict dict;
543
        dict.setItem(Py::String("Sigma"), Py::Float(fit));
544

545
        // coefficients
546
        double a {}, b {}, c {}, d {}, e {}, f {};
547
        polyFit.GetCoefficients(a, b, c, d, e, f);
548
        Py::Tuple p(6);
549
        p.setItem(0, Py::Float(a));
550
        p.setItem(1, Py::Float(b));
551
        p.setItem(2, Py::Float(c));
552
        p.setItem(3, Py::Float(d));
553
        p.setItem(4, Py::Float(e));
554
        p.setItem(5, Py::Float(f));
555
        dict.setItem(Py::String("Coefficients"), p);
556

557
        // residuals
558
        std::vector<Base::Vector3f> local = polyFit.GetLocalPoints();
559
        Py::Tuple r(local.size());
560
        for (std::vector<Base::Vector3f>::iterator it = local.begin(); it != local.end(); ++it) {
561
            double z = polyFit.Value(it->x, it->y);
562
            double d = it->z - z;
563
            r.setItem(it - local.begin(), Py::Float(d));
564
        }
565
        dict.setItem(Py::String("Residuals"), r);
566

567
        return dict;  // NOLINT
568
    }
569
    Py::Object minimumVolumeOrientedBox(const Py::Tuple& args)
570
    {
571
        PyObject* input {};
572

573
        if (!PyArg_ParseTuple(args.ptr(), "O", &input)) {
574
            throw Py::Exception();
575
        }
576

577
        if (!PySequence_Check(input)) {
578
            throw Py::TypeError("Input has to be a sequence of Base.Vector()");
579
        }
580

581
        Py::Sequence list(input);
582
        std::vector<Wm4::Vector3d> points;
583
        points.reserve(list.size());
584
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
585
            PyObject* value = (*it).ptr();
586
            if (PyObject_TypeCheck(value, &(Base::VectorPy::Type))) {
587
                Base::VectorPy* pcObject = static_cast<Base::VectorPy*>(value);
588
                Base::Vector3d* val = pcObject->getVectorPtr();
589
                Wm4::Vector3d pt;
590
                pt[0] = val->x;
591
                pt[1] = val->y;
592
                pt[2] = val->z;
593
                points.push_back(pt);
594
            }
595
        }
596

597
        if (points.size() < 4) {
598
            throw Py::RuntimeError("Too few points");
599
        }
600

601
        Wm4::Box3d mobox = Wm4::ContMinBox(points.size(), &(points[0]), 0.001, Wm4::Query::QT_REAL);
602
        Py::Tuple result(7);
603
        Base::Vector3d v;
604

605
        v.x = mobox.Center[0];
606
        v.y = mobox.Center[1];
607
        v.z = mobox.Center[2];
608
        result.setItem(0, Py::Vector(v));
609

610
        v.x = mobox.Axis[0][0];
611
        v.y = mobox.Axis[0][1];
612
        v.z = mobox.Axis[0][2];
613
        result.setItem(1, Py::Vector(v));
614

615
        v.x = mobox.Axis[1][0];
616
        v.y = mobox.Axis[1][1];
617
        v.z = mobox.Axis[1][2];
618
        result.setItem(2, Py::Vector(v));
619

620
        v.x = mobox.Axis[2][0];
621
        v.y = mobox.Axis[2][1];
622
        v.z = mobox.Axis[2][2];
623
        result.setItem(3, Py::Vector(v));
624

625
        result.setItem(4, Py::Float(mobox.Extent[0]));
626
        result.setItem(5, Py::Float(mobox.Extent[1]));
627
        result.setItem(6, Py::Float(mobox.Extent[2]));
628

629
        return result;  // NOLINT
630
    }
631
};
632

633
PyObject* initModule()
634
{
635
    return Base::Interpreter().addModule(new Module);
636
}
637

638
}  // namespace Mesh
639

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

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

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

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