FreeCAD

Форк
0
/
PropertyGeo.cpp 
1294 строки · 41.7 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de>              *
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

24
#include "PreCompiled.h"
25

26
#include <Base/MatrixPy.h>
27
#include <Base/PlacementPy.h>
28
#include <Base/Reader.h>
29

30
#include <Base/Quantity.h>
31
#include <Base/QuantityPy.h>
32
#include <Base/Rotation.h>
33
#include <Base/RotationPy.h>
34
#include <Base/Stream.h>
35
#include <Base/Tools.h>
36
#include <Base/VectorPy.h>
37
#include <Base/Writer.h>
38

39
#include "ComplexGeoData.h"
40
#include "Document.h"
41
#include "PropertyGeo.h"
42
#include "Placement.h"
43
#include "ObjectIdentifier.h"
44

45

46
using namespace App;
47
using namespace Base;
48
using namespace std;
49

50

51

52

53
//**************************************************************************
54
//**************************************************************************
55
// PropertyVector
56
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
57

58
TYPESYSTEM_SOURCE(App::PropertyVector , App::Property)
59

60
//**************************************************************************
61
// Construction/Destruction
62

63

64
PropertyVector::PropertyVector() = default;
65

66

67
PropertyVector::~PropertyVector() = default;
68

69
//**************************************************************************
70
// Base class implementer
71

72

73
void PropertyVector::setValue(const Base::Vector3d &vec)
74
{
75
    aboutToSetValue();
76
    _cVec=vec;
77
    hasSetValue();
78
}
79

80
void PropertyVector::setValue(double x, double y, double z)
81
{
82
    aboutToSetValue();
83
    _cVec.Set(x,y,z);
84
    hasSetValue();
85
}
86

87
const Base::Vector3d & PropertyVector::getValue()const
88
{
89
    return _cVec;
90
}
91

92
PyObject *PropertyVector::getPyObject()
93
{
94
    return new Base::VectorPy(_cVec);
95
}
96

97
void PropertyVector::setPyObject(PyObject *value)
98
{
99
    if (PyObject_TypeCheck(value, &(Base::VectorPy::Type))) {
100
        Base::VectorPy  *pcObject = static_cast<Base::VectorPy*>(value);
101
        Base::Vector3d* val = pcObject->getVectorPtr();
102
        setValue(*val);
103
    }
104
    else if (PyTuple_Check(value)&&PyTuple_Size(value)==3) {
105
        PyObject* item;
106
        Base::Vector3d cVec;
107
        // x
108
        item = PyTuple_GetItem(value,0);
109
        if (PyFloat_Check(item))
110
            cVec.x = PyFloat_AsDouble(item);
111
        else if (PyLong_Check(item))
112
            cVec.x = (double)PyLong_AsLong(item);
113
        else
114
            throw Base::TypeError("Not allowed type used in tuple (float expected)...");
115
        // y
116
        item = PyTuple_GetItem(value,1);
117
        if (PyFloat_Check(item))
118
            cVec.y = PyFloat_AsDouble(item);
119
        else if (PyLong_Check(item))
120
            cVec.y = (double)PyLong_AsLong(item);
121
        else
122
            throw Base::TypeError("Not allowed type used in tuple (float expected)...");
123
        // z
124
        item = PyTuple_GetItem(value,2);
125
        if (PyFloat_Check(item))
126
            cVec.z = PyFloat_AsDouble(item);
127
        else if (PyLong_Check(item))
128
            cVec.z = (double)PyLong_AsLong(item);
129
        else
130
            throw Base::TypeError("Not allowed type used in tuple (float expected)...");
131
        setValue( cVec );
132
    }
133
    else {
134
        std::string error = std::string("type must be 'Vector' or tuple of three floats, not ");
135
        error += value->ob_type->tp_name;
136
        throw Base::TypeError(error);
137
    }
138
}
139

140
void PropertyVector::Save (Base::Writer &writer) const
141
{
142
    writer.Stream() << writer.ind() << "<PropertyVector valueX=\"" <<  _cVec.x << "\" valueY=\"" <<  _cVec.y << "\" valueZ=\"" <<  _cVec.z <<"\"/>" << endl;
143
}
144

145
void PropertyVector::Restore(Base::XMLReader &reader)
146
{
147
    // read my Element
148
    reader.readElement("PropertyVector");
149
    // get the value of my Attribute
150
    aboutToSetValue();
151
    _cVec.x = reader.getAttributeAsFloat("valueX");
152
    _cVec.y = reader.getAttributeAsFloat("valueY");
153
    _cVec.z = reader.getAttributeAsFloat("valueZ");
154
    hasSetValue();
155
}
156

157

158
Property *PropertyVector::Copy() const
159
{
160
    PropertyVector *p= new PropertyVector();
161
    p->_cVec = _cVec;
162
    return p;
163
}
164

165
void PropertyVector::Paste(const Property &from)
166
{
167
    aboutToSetValue();
168
    _cVec = dynamic_cast<const PropertyVector&>(from)._cVec;
169
    hasSetValue();
170
}
171

172
void PropertyVector::getPaths(std::vector<ObjectIdentifier> &paths) const
173
{
174
    paths.push_back(ObjectIdentifier(*this)
175
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("x")));
176
    paths.push_back(ObjectIdentifier(*this)
177
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("y")));
178
    paths.push_back(ObjectIdentifier(*this)
179
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("z")));
180
}
181

182
const boost::any PropertyVector::getPathValue(const ObjectIdentifier &path) const
183
{
184
    Base::Unit unit = getUnit();
185
    if(!unit.isEmpty()) {
186
        std::string p = path.getSubPathStr();
187
        if (p == ".x" || p == ".y" || p == ".z") {
188
            // Convert double to quantity
189
            return Base::Quantity(boost::any_cast<double>(Property::getPathValue(path)), unit);
190
        }
191
    }
192
    return Property::getPathValue(path);
193
}
194

195
bool PropertyVector::getPyPathValue(const ObjectIdentifier &path, Py::Object &res) const
196
{
197
    Base::Unit unit = getUnit();
198
    if(unit.isEmpty())
199
        return false;
200

201
    std::string p = path.getSubPathStr();
202
    if (p == ".x") {
203
        res = Py::asObject(new QuantityPy(new Quantity(getValue().x,unit)));
204
    } else if(p == ".y") {
205
        res = Py::asObject(new QuantityPy(new Quantity(getValue().y,unit)));
206
    } else if(p == ".z") {
207
        res = Py::asObject(new QuantityPy(new Quantity(getValue().z,unit)));
208
    } else
209
        return false;
210
    return true;
211
}
212

213

214
//**************************************************************************
215
// PropertyVectorDistance
216
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
217

218
TYPESYSTEM_SOURCE(App::PropertyVectorDistance , App::PropertyVector)
219

220
//**************************************************************************
221
// Construction/Destruction
222

223

224
PropertyVectorDistance::PropertyVectorDistance() = default;
225

226
PropertyVectorDistance::~PropertyVectorDistance() = default;
227

228
//**************************************************************************
229
// PropertyPosition
230
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
231

232
TYPESYSTEM_SOURCE(App::PropertyPosition , App::PropertyVector)
233

234
//**************************************************************************
235
// Construction/Destruction
236

237

238
PropertyPosition::PropertyPosition() = default;
239

240
PropertyPosition::~PropertyPosition() = default;
241

242
//**************************************************************************
243
// PropertyPosition
244
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
245

246
TYPESYSTEM_SOURCE(App::PropertyDirection , App::PropertyVector)
247

248
//**************************************************************************
249
// Construction/Destruction
250

251

252
PropertyDirection::PropertyDirection() = default;
253

254
PropertyDirection::~PropertyDirection() = default;
255

256
//**************************************************************************
257
// PropertyVectorList
258
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
259

260
TYPESYSTEM_SOURCE(App::PropertyVectorList , App::PropertyLists)
261

262
//**************************************************************************
263
// Construction/Destruction
264

265
PropertyVectorList::PropertyVectorList() = default;
266

267
PropertyVectorList::~PropertyVectorList() = default;
268

269
//**************************************************************************
270
// Base class implementer
271

272
void PropertyVectorList::setValue(double x, double y, double z)
273
{
274
    setValue(Base::Vector3d(x,y,z));
275
}
276

277
PyObject *PropertyVectorList::getPyObject()
278
{
279
    PyObject* list = PyList_New(getSize());
280

281
    for (int i = 0;i < getSize(); i++)
282
        PyList_SetItem(list, i, new VectorPy(_lValueList[i]));
283

284
    return list;
285
}
286

287
Base::Vector3d PropertyVectorList::getPyValue(PyObject *item) const {
288
    PropertyVector val;
289
    val.setPyObject( item );
290
    return val.getValue();
291
}
292

293
void PropertyVectorList::Save (Base::Writer &writer) const
294
{
295
    if (!writer.isForceXML()) {
296
        writer.Stream() << writer.ind() << "<VectorList file=\"" << writer.addFile(getName(), this) << "\"/>" << std::endl;
297
    }
298
}
299

300
void PropertyVectorList::Restore(Base::XMLReader &reader)
301
{
302
    reader.readElement("VectorList");
303
    std::string file (reader.getAttribute("file") );
304

305
    if (!file.empty()) {
306
        // initiate a file read
307
        reader.addFile(file.c_str(),this);
308
    }
309
}
310

311
void PropertyVectorList::SaveDocFile (Base::Writer &writer) const
312
{
313
    Base::OutputStream str(writer.Stream());
314
    uint32_t uCt = (uint32_t)getSize();
315
    str << uCt;
316
    if (!isSinglePrecision()) {
317
        for (const auto & it : _lValueList) {
318
            str << it.x << it.y << it.z;
319
        }
320
    }
321
    else {
322
        for (const auto & it : _lValueList) {
323
            float x = (float)it.x;
324
            float y = (float)it.y;
325
            float z = (float)it.z;
326
            str << x << y << z;
327
        }
328
    }
329
}
330

331
void PropertyVectorList::RestoreDocFile(Base::Reader &reader)
332
{
333
    Base::InputStream str(reader);
334
    uint32_t uCt=0;
335
    str >> uCt;
336
    std::vector<Base::Vector3d> values(uCt);
337
    if (!isSinglePrecision()) {
338
        for (auto & it : values) {
339
            str >> it.x >> it.y >> it.z;
340
        }
341
    }
342
    else {
343
        float x,y,z;
344
        for (auto & it : values) {
345
            str >> x >> y >> z;
346
            it.Set(x, y, z);
347
        }
348
    }
349
    setValues(values);
350
}
351

352
Property *PropertyVectorList::Copy() const
353
{
354
    PropertyVectorList *p= new PropertyVectorList();
355
    p->_lValueList = _lValueList;
356
    return p;
357
}
358

359
void PropertyVectorList::Paste(const Property &from)
360
{
361
    setValues(dynamic_cast<const PropertyVectorList&>(from)._lValueList);
362
}
363

364
unsigned int PropertyVectorList::getMemSize () const
365
{
366
    return static_cast<unsigned int>(_lValueList.size() * sizeof(Base::Vector3d));
367
}
368

369
//**************************************************************************
370
//**************************************************************************
371
// PropertyMatrix
372
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
373

374
TYPESYSTEM_SOURCE(App::PropertyMatrix , App::Property)
375

376
//**************************************************************************
377
// Construction/Destruction
378

379

380
PropertyMatrix::PropertyMatrix() = default;
381

382

383
PropertyMatrix::~PropertyMatrix() = default;
384

385
//**************************************************************************
386
// Base class implementer
387

388

389
void PropertyMatrix::setValue(const Base::Matrix4D &mat)
390
{
391
    aboutToSetValue();
392
    _cMat=mat;
393
    hasSetValue();
394
}
395

396

397
const Base::Matrix4D & PropertyMatrix::getValue()const
398
{
399
    return _cMat;
400
}
401

402
PyObject *PropertyMatrix::getPyObject()
403
{
404
    return new Base::MatrixPy(_cMat);
405
}
406

407
void PropertyMatrix::setPyObject(PyObject *value)
408
{
409
    if (PyObject_TypeCheck(value, &(Base::MatrixPy::Type))) {
410
        Base::MatrixPy  *pcObject = static_cast<Base::MatrixPy*>(value);
411
        setValue( pcObject->value() );
412
    }
413
    else if (PyTuple_Check(value)&&PyTuple_Size(value)==16) {
414
        PyObject* item;
415
        Base::Matrix4D cMatrix;
416

417
        for (int x=0; x<4;x++) {
418
            for (int y=0; y<4;y++) {
419
                item = PyTuple_GetItem(value,x+y*4);
420
                if (PyFloat_Check(item))
421
                    cMatrix[x][y] = PyFloat_AsDouble(item);
422
                else if (PyLong_Check(item))
423
                    cMatrix[x][y] = (double)PyLong_AsLong(item);
424
                else
425
                    throw Base::TypeError("Not allowed type used in matrix tuple (a number expected)...");
426
            }
427
        }
428

429
        setValue( cMatrix );
430
    }
431
    else {
432
        std::string error = std::string("type must be 'Matrix' or tuple of 16 float or int, not ");
433
        error += value->ob_type->tp_name;
434
        throw Base::TypeError(error);
435
    }
436
}
437

438
void PropertyMatrix::Save (Base::Writer &writer) const
439
{
440
    writer.Stream() << writer.ind() << "<PropertyMatrix";
441
    writer.Stream() << " a11=\"" <<  _cMat[0][0] << "\" a12=\"" <<  _cMat[0][1] << "\" a13=\"" <<  _cMat[0][2] << "\" a14=\"" <<  _cMat[0][3] << "\"";
442
    writer.Stream() << " a21=\"" <<  _cMat[1][0] << "\" a22=\"" <<  _cMat[1][1] << "\" a23=\"" <<  _cMat[1][2] << "\" a24=\"" <<  _cMat[1][3] << "\"";
443
    writer.Stream() << " a31=\"" <<  _cMat[2][0] << "\" a32=\"" <<  _cMat[2][1] << "\" a33=\"" <<  _cMat[2][2] << "\" a34=\"" <<  _cMat[2][3] << "\"";
444
    writer.Stream() << " a41=\"" <<  _cMat[3][0] << "\" a42=\"" <<  _cMat[3][1] << "\" a43=\"" <<  _cMat[3][2] << "\" a44=\"" <<  _cMat[3][3] << "\"";
445
    writer.Stream() <<"/>" << endl;
446
}
447

448
void PropertyMatrix::Restore(Base::XMLReader &reader)
449
{
450
    // read my Element
451
    reader.readElement("PropertyMatrix");
452
    // get the value of my Attribute
453
    aboutToSetValue();
454
    _cMat[0][0] = reader.getAttributeAsFloat("a11");
455
    _cMat[0][1] = reader.getAttributeAsFloat("a12");
456
    _cMat[0][2] = reader.getAttributeAsFloat("a13");
457
    _cMat[0][3] = reader.getAttributeAsFloat("a14");
458

459
    _cMat[1][0] = reader.getAttributeAsFloat("a21");
460
    _cMat[1][1] = reader.getAttributeAsFloat("a22");
461
    _cMat[1][2] = reader.getAttributeAsFloat("a23");
462
    _cMat[1][3] = reader.getAttributeAsFloat("a24");
463

464
    _cMat[2][0] = reader.getAttributeAsFloat("a31");
465
    _cMat[2][1] = reader.getAttributeAsFloat("a32");
466
    _cMat[2][2] = reader.getAttributeAsFloat("a33");
467
    _cMat[2][3] = reader.getAttributeAsFloat("a34");
468

469
    _cMat[3][0] = reader.getAttributeAsFloat("a41");
470
    _cMat[3][1] = reader.getAttributeAsFloat("a42");
471
    _cMat[3][2] = reader.getAttributeAsFloat("a43");
472
    _cMat[3][3] = reader.getAttributeAsFloat("a44");
473
    hasSetValue();
474
}
475

476

477
Property *PropertyMatrix::Copy() const
478
{
479
    PropertyMatrix *p= new PropertyMatrix();
480
    p->_cMat = _cMat;
481
    return p;
482
}
483

484
void PropertyMatrix::Paste(const Property &from)
485
{
486
    aboutToSetValue();
487
    _cMat = dynamic_cast<const PropertyMatrix&>(from)._cMat;
488
    hasSetValue();
489
}
490

491
//**************************************************************************
492
//**************************************************************************
493
// PropertyPlacement
494
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
495

496
TYPESYSTEM_SOURCE(App::PropertyPlacement , App::Property)
497

498
//**************************************************************************
499
// Construction/Destruction
500

501

502
PropertyPlacement::PropertyPlacement() = default;
503

504

505
PropertyPlacement::~PropertyPlacement() = default;
506

507
//**************************************************************************
508
// Base class implementer
509

510

511
void PropertyPlacement::setValue(const Base::Placement &pos)
512
{
513
    aboutToSetValue();
514
    _cPos=pos;
515
    hasSetValue();
516
}
517

518
bool PropertyPlacement::setValueIfChanged(const Base::Placement &pos,double tol,double atol)
519
{
520
    if(_cPos.getPosition().IsEqual(pos.getPosition(),tol)
521
            && _cPos.getRotation().isSame(pos.getRotation(),atol))
522
    {
523
        return false;
524
    }
525
    setValue(pos);
526
    return true;
527
}
528

529

530
const Base::Placement & PropertyPlacement::getValue()const
531
{
532
    return _cPos;
533
}
534

535
void PropertyPlacement::getPaths(std::vector<ObjectIdentifier> &paths) const
536
{
537
    paths.push_back(ObjectIdentifier(*this)
538
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Base"))
539
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("x")));
540
    paths.push_back(ObjectIdentifier(*this)
541
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Base"))
542
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("y")));
543
    paths.push_back(ObjectIdentifier(*this)
544
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Base"))
545
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("z")));
546
    paths.push_back(ObjectIdentifier(*this)
547
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Rotation"))
548
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Angle")));
549
    paths.push_back(ObjectIdentifier(*this)
550
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Rotation"))
551
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
552
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("x")));
553
    paths.push_back(ObjectIdentifier(*this)
554
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Rotation"))
555
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
556
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("y")));
557
    paths.push_back(ObjectIdentifier(*this)
558
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Rotation"))
559
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
560
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("z")));
561
}
562

563
namespace {
564
double toDouble(const boost::any &value)
565
{
566
    double avalue{};
567

568
    if (value.type() == typeid(Base::Quantity))
569
        avalue = boost::any_cast<Base::Quantity>(value).getValue();
570
    else if (value.type() == typeid(double))
571
        avalue = boost::any_cast<double>(value);
572
    else if (value.type() == typeid(int))
573
        avalue =  boost::any_cast<int>(value);
574
    else if (value.type() == typeid(unsigned int))
575
        avalue =  boost::any_cast<unsigned int >(value);
576
    else if (value.type() == typeid(short))
577
        avalue =  boost::any_cast<short>(value);
578
    else if (value.type() == typeid(unsigned short))
579
        avalue =  boost::any_cast<unsigned short>(value);
580
    else if (value.type() == typeid(long))
581
        avalue =  boost::any_cast<long>(value);
582
    else if (value.type() == typeid(unsigned long))
583
        avalue =  boost::any_cast<unsigned long>(value);
584
    else
585
        throw std::bad_cast();
586
    return avalue;
587
}
588
}
589

590
void PropertyPlacement::setPathValue(const ObjectIdentifier &path, const boost::any &value)
591
{
592
    auto updateAxis = [=](int index, double coord) {
593
        Base::Vector3d axis;
594
        double angle;
595
        Base::Vector3d base = _cPos.getPosition();
596
        Base::Rotation rot = _cPos.getRotation();
597
        rot.getRawValue(axis, angle);
598
        axis[index] = coord;
599
        rot.setValue(axis, angle);
600
        Base::Placement plm(base, rot);
601
        setValue(plm);
602
    };
603

604
    auto updateYawPitchRoll = [=](int index, double angle) {
605
        Base::Vector3d base = _cPos.getPosition();
606
        Base::Rotation rot = _cPos.getRotation();
607
        double yaw, pitch, roll;
608
        rot.getYawPitchRoll(yaw, pitch, roll);
609
        if (index == 0) {
610
            if (angle < -180.0 || angle > 180.0)
611
                throw Base::ValueError("Yaw angle is out of range [-180, +180]");
612
            yaw = angle;
613
        }
614
        else if (index == 1) {
615
            if (angle < -90.0 || angle > 90.0)
616
                throw Base::ValueError("Pitch angle is out of range [-90, +90]");
617
            pitch = angle;
618
        }
619
        else if (index == 2) {
620
            if (angle < -180.0 || angle > 180.0)
621
                throw Base::ValueError("Roll angle is out of range [-180, +180]");
622
            roll = angle;
623
        }
624
        rot.setYawPitchRoll(yaw, pitch, roll);
625
        Base::Placement plm(base, rot);
626
        setValue(plm);
627
    };
628

629
    std::string subpath = path.getSubPathStr();
630
    if (subpath == ".Rotation.Angle") {
631
        double avalue = toDouble(value);
632
        Property::setPathValue(path, Base::toRadians(avalue));
633
    }
634
    else if (subpath == ".Rotation.Axis.x") {
635
        updateAxis(0, toDouble(value));
636
    }
637
    else if (subpath == ".Rotation.Axis.y") {
638
        updateAxis(1, toDouble(value));
639
    }
640
    else if (subpath == ".Rotation.Axis.z") {
641
        updateAxis(2, toDouble(value));
642
    }
643
    else if (subpath == ".Rotation.Yaw") {
644
        updateYawPitchRoll(0, toDouble(value));
645
    }
646
    else if (subpath == ".Rotation.Pitch") {
647
        updateYawPitchRoll(1, toDouble(value));
648
    }
649
    else if (subpath == ".Rotation.Roll") {
650
        updateYawPitchRoll(2, toDouble(value));
651
    }
652
    else {
653
        Property::setPathValue(path, value);
654
    }
655
}
656

657
const boost::any PropertyPlacement::getPathValue(const ObjectIdentifier &path) const
658
{
659
    auto getAxis = [](const Base::Placement& plm) {
660
        Base::Vector3d axis;
661
        double angle;
662
        const Base::Rotation& rot = plm.getRotation();
663
        rot.getRawValue(axis, angle);
664
        return axis;
665
    };
666

667
    auto getYawPitchRoll = [](const Base::Placement& plm) {
668
        Base::Vector3d ypr;
669
        const Base::Rotation& rot = plm.getRotation();
670
        rot.getYawPitchRoll(ypr.x, ypr.y, ypr.z);
671
        return ypr;
672
    };
673

674
    std::string p = path.getSubPathStr();
675

676
    if (p == ".Rotation.Angle") {
677
        // Convert angle to degrees
678
        return Base::Quantity(Base::toDegrees(boost::any_cast<double>(Property::getPathValue(path))), Unit::Angle);
679
    }
680
    else if (p == ".Base.x" || p == ".Base.y" || p == ".Base.z") {
681
        // Convert double to quantity
682
        return Base::Quantity(boost::any_cast<double>(Property::getPathValue(path)), Unit::Length);
683
    }
684
    else if (p == ".Rotation.Axis.x") {
685
        return getAxis(_cPos).x;
686
    }
687
    else if (p == ".Rotation.Axis.y") {
688
        return getAxis(_cPos).y;
689
    }
690
    else if (p == ".Rotation.Axis.z") {
691
        return getAxis(_cPos).z;
692
    }
693
    else if (p == ".Rotation.Yaw") {
694
        return getYawPitchRoll(_cPos).x;
695
    }
696
    else if (p == ".Rotation.Pitch") {
697
        return getYawPitchRoll(_cPos).y;
698
    }
699
    else if (p == ".Rotation.Roll") {
700
        return getYawPitchRoll(_cPos).z;
701
    }
702
    else {
703
        return Property::getPathValue(path);
704
    }
705
}
706

707
bool PropertyPlacement::getPyPathValue(const ObjectIdentifier &path, Py::Object &res) const
708
{
709
    auto getAxis = [](const Base::Placement& plm) {
710
        Base::Vector3d axis;
711
        double angle;
712
        const Base::Rotation& rot = plm.getRotation();
713
        rot.getRawValue(axis, angle);
714
        return axis;
715
    };
716

717
    auto getYawPitchRoll = [](const Base::Placement& plm) {
718
        Base::Vector3d ypr;
719
        const Base::Rotation& rot = plm.getRotation();
720
        rot.getYawPitchRoll(ypr.x, ypr.y, ypr.z);
721
        return ypr;
722
    };
723

724
    std::string p = path.getSubPathStr();
725
    if (p == ".Rotation.Angle") {
726
        Base::Vector3d axis; double angle;
727
        _cPos.getRotation().getValue(axis,angle);
728
        res = Py::asObject(new QuantityPy(new Quantity(Base::toDegrees(angle),Unit::Angle)));
729
        return true;
730
    }
731
    else if (p == ".Base.x") {
732
        res = Py::asObject(new QuantityPy(new Quantity(_cPos.getPosition().x,Unit::Length)));
733
        return true;
734
    }
735
    else if (p == ".Base.y") {
736
        res = Py::asObject(new QuantityPy(new Quantity(_cPos.getPosition().y,Unit::Length)));
737
        return true;
738
    }
739
    else if (p == ".Base.z") {
740
        res = Py::asObject(new QuantityPy(new Quantity(_cPos.getPosition().z,Unit::Length)));
741
        return true;
742
    }
743
    else if (p == ".Rotation.Axis.x") {
744
        res = Py::Float(getAxis(_cPos).x);
745
        return true;
746
    }
747
    else if (p == ".Rotation.Axis.y") {
748
        res = Py::Float(getAxis(_cPos).y);
749
        return true;
750
    }
751
    else if (p == ".Rotation.Axis.z") {
752
        res = Py::Float(getAxis(_cPos).z);
753
        return true;
754
    }
755
    else if (p == ".Rotation.Yaw") {
756
        res = Py::Float(getYawPitchRoll(_cPos).x);
757
        return true;
758
    }
759
    else if (p == ".Rotation.Pitch") {
760
        res = Py::Float(getYawPitchRoll(_cPos).y);
761
        return true;
762
    }
763
    else if (p == ".Rotation.Roll") {
764
        res = Py::Float(getYawPitchRoll(_cPos).z);
765
        return true;
766
    }
767

768
    return false;
769
}
770

771
PyObject *PropertyPlacement::getPyObject()
772
{
773
    return new Base::PlacementPy(new Base::Placement(_cPos));
774
}
775

776
void PropertyPlacement::setPyObject(PyObject *value)
777
{
778
    if (PyObject_TypeCheck(value, &(Base::MatrixPy::Type))) {
779
        Base::MatrixPy  *pcObject = static_cast<Base::MatrixPy*>(value);
780
        Base::Matrix4D mat = pcObject->value();
781
        Base::Placement p;
782
        p.fromMatrix(mat);
783
        setValue(p);
784
    }
785
    else if (PyObject_TypeCheck(value, &(Base::PlacementPy::Type))) {
786
        setValue(*static_cast<Base::PlacementPy*>(value)->getPlacementPtr());
787
    }
788
    else {
789
        std::string error = std::string("type must be 'Matrix' or 'Placement', not ");
790
        error += value->ob_type->tp_name;
791
        throw Base::TypeError(error);
792
    }
793
}
794

795
void PropertyPlacement::Save (Base::Writer &writer) const
796
{
797
    writer.Stream() << writer.ind() << "<PropertyPlacement";
798
    writer.Stream() << " Px=\"" <<  _cPos.getPosition().x 
799
                    << "\" Py=\"" <<  _cPos.getPosition().y
800
                    << "\" Pz=\"" <<  _cPos.getPosition().z << "\"";
801

802
    writer.Stream() << " Q0=\"" <<  _cPos.getRotation()[0]
803
                    << "\" Q1=\"" <<  _cPos.getRotation()[1]
804
                    << "\" Q2=\"" <<  _cPos.getRotation()[2]
805
                    << "\" Q3=\"" <<  _cPos.getRotation()[3] << "\"";
806
    Vector3d axis;
807
    double rfAngle;
808
    _cPos.getRotation().getRawValue(axis, rfAngle);
809
    writer.Stream() << " A=\"" <<  rfAngle
810
                    << "\" Ox=\"" <<  axis.x
811
                    << "\" Oy=\"" <<  axis.y
812
                    << "\" Oz=\"" <<  axis.z << "\"";
813
    writer.Stream() <<"/>" << endl;
814
}
815

816
void PropertyPlacement::Restore(Base::XMLReader &reader)
817
{
818
    // read my Element
819
    reader.readElement("PropertyPlacement");
820
    // get the value of my Attribute
821
    aboutToSetValue();
822

823
    if (reader.hasAttribute("A")) {
824
        _cPos = Base::Placement(Vector3d(reader.getAttributeAsFloat("Px"),
825
                                         reader.getAttributeAsFloat("Py"),
826
                                         reader.getAttributeAsFloat("Pz")),
827
                       Rotation(Vector3d(reader.getAttributeAsFloat("Ox"),
828
                                         reader.getAttributeAsFloat("Oy"),
829
                                         reader.getAttributeAsFloat("Oz")),
830
                                reader.getAttributeAsFloat("A")));
831
    }
832
    else {
833
        _cPos = Base::Placement(Vector3d(reader.getAttributeAsFloat("Px"),
834
                                         reader.getAttributeAsFloat("Py"),
835
                                         reader.getAttributeAsFloat("Pz")),
836
                                Rotation(reader.getAttributeAsFloat("Q0"),
837
                                         reader.getAttributeAsFloat("Q1"),
838
                                         reader.getAttributeAsFloat("Q2"),
839
                                         reader.getAttributeAsFloat("Q3")));
840
    }
841

842
    hasSetValue();
843
}
844

845

846
Property *PropertyPlacement::Copy() const
847
{
848
    PropertyPlacement *p= new PropertyPlacement();
849
    p->_cPos = _cPos;
850
    return p;
851
}
852

853
void PropertyPlacement::Paste(const Property &from)
854
{
855
    aboutToSetValue();
856
    _cPos = dynamic_cast<const PropertyPlacement&>(from)._cPos;
857
    hasSetValue();
858
}
859

860

861
//**************************************************************************
862
// PropertyPlacementList
863
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
864

865
TYPESYSTEM_SOURCE(App::PropertyPlacementList , App::PropertyLists)
866

867
//**************************************************************************
868
// Construction/Destruction
869

870
PropertyPlacementList::PropertyPlacementList() = default;
871

872
PropertyPlacementList::~PropertyPlacementList() = default;
873

874
//**************************************************************************
875
// Base class implementer
876

877
PyObject *PropertyPlacementList::getPyObject()
878
{
879
    PyObject* list = PyList_New( getSize() );
880

881
    for (int i = 0;i<getSize(); i++)
882
        PyList_SetItem( list, i, new Base::PlacementPy(new Base::Placement(_lValueList[i])));
883

884
    return list;
885
}
886

887
Base::Placement PropertyPlacementList::getPyValue(PyObject *item) const {
888
    PropertyPlacement val;
889
    val.setPyObject( item );
890
    return val.getValue();
891
}
892

893
void PropertyPlacementList::Save (Base::Writer &writer) const
894
{
895
    if (!writer.isForceXML()) {
896
        writer.Stream() << writer.ind() << "<PlacementList file=\"" << writer.addFile(getName(), this) << "\"/>" << std::endl;
897
    }
898
}
899

900
void PropertyPlacementList::Restore(Base::XMLReader &reader)
901
{
902
    reader.readElement("PlacementList");
903
    std::string file (reader.getAttribute("file") );
904

905
    if (!file.empty()) {
906
        // initiate a file read
907
        reader.addFile(file.c_str(),this);
908
    }
909
}
910

911
void PropertyPlacementList::SaveDocFile (Base::Writer &writer) const
912
{
913
    Base::OutputStream str(writer.Stream());
914
    uint32_t uCt = (uint32_t)getSize();
915
    str << uCt;
916
    if (!isSinglePrecision()) {
917
        for (const auto & it : _lValueList) {
918
            str << it.getPosition().x << it.getPosition().y << it.getPosition().z
919
                << it.getRotation()[0] << it.getRotation()[1] << it.getRotation()[2] << it.getRotation()[3] ;
920
        }
921
    }
922
    else {
923
        for (const auto & it : _lValueList) {
924
            float x = (float)it.getPosition().x;
925
            float y = (float)it.getPosition().y;
926
            float z = (float)it.getPosition().z;
927
            float q0 = (float)it.getRotation()[0];
928
            float q1 = (float)it.getRotation()[1];
929
            float q2 = (float)it.getRotation()[2];
930
            float q3 = (float)it.getRotation()[3];
931
            str << x << y << z << q0 << q1 << q2 << q3;
932
        }
933
    }
934
}
935

936
void PropertyPlacementList::RestoreDocFile(Base::Reader &reader)
937
{
938
    Base::InputStream str(reader);
939
    uint32_t uCt=0;
940
    str >> uCt;
941
    std::vector<Base::Placement> values(uCt);
942
    if (!isSinglePrecision()) {
943
        for (auto & it : values) {
944
            Base::Vector3d pos;
945
            double q0, q1, q2, q3;
946
            str >> pos.x >> pos.y >> pos.z >> q0 >> q1 >> q2 >> q3;
947
            Base::Rotation rot(q0,q1,q2,q3);
948
            it.setPosition(pos);
949
            it.setRotation(rot);
950
        }
951
    }
952
    else {
953
        float x,y,z,q0,q1,q2,q3;
954
        for (auto & it : values) {
955
            str >> x >> y >> z >> q0 >> q1 >> q2 >> q3;
956
            Base::Vector3d pos(x, y, z);
957
            Base::Rotation rot(q0,q1,q2,q3);
958
            it.setPosition(pos);
959
            it.setRotation(rot);
960
        }
961
    }
962
    setValues(values);
963
}
964

965
Property *PropertyPlacementList::Copy() const
966
{
967
    PropertyPlacementList *p= new PropertyPlacementList();
968
    p->_lValueList = _lValueList;
969
    return p;
970
}
971

972
void PropertyPlacementList::Paste(const Property &from)
973
{
974
    setValues(dynamic_cast<const PropertyPlacementList&>(from)._lValueList);
975
}
976

977
unsigned int PropertyPlacementList::getMemSize () const
978
{
979
    return static_cast<unsigned int>(_lValueList.size() * sizeof(Base::Vector3d));
980
}
981

982

983

984

985
//**************************************************************************
986
//**************************************************************************
987
// PropertyPlacement
988
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
989

990
TYPESYSTEM_SOURCE(App::PropertyPlacementLink , App::PropertyLink)
991

992
//**************************************************************************
993
// Construction/Destruction
994

995

996
PropertyPlacementLink::PropertyPlacementLink() = default;
997

998

999
PropertyPlacementLink::~PropertyPlacementLink() = default;
1000

1001
App::Placement * PropertyPlacementLink::getPlacementObject() const
1002
{
1003
    if (_pcLink->isDerivedFrom<App::Placement>())
1004
        return dynamic_cast<App::Placement*>(_pcLink);
1005
    else
1006
        return nullptr;
1007

1008
}
1009

1010
//**************************************************************************
1011
// Base class implementer
1012

1013
Property *PropertyPlacementLink::Copy() const
1014
{
1015
    PropertyPlacementLink *p= new PropertyPlacementLink();
1016
    p->_pcLink = _pcLink;
1017
    return p;
1018
}
1019

1020
void PropertyPlacementLink::Paste(const Property &from)
1021
{
1022
    aboutToSetValue();
1023
    _pcLink = dynamic_cast<const PropertyPlacementLink&>(from)._pcLink;
1024
    hasSetValue();
1025
}
1026

1027
//**************************************************************************
1028
//**************************************************************************
1029
// PropertyRotation
1030
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1031

1032
TYPESYSTEM_SOURCE(App::PropertyRotation , App::Property)
1033

1034
PropertyRotation::PropertyRotation() = default;
1035

1036

1037
PropertyRotation::~PropertyRotation() = default;
1038

1039
void PropertyRotation::setValue(const Base::Rotation &rot)
1040
{
1041
    aboutToSetValue();
1042
    _rot = rot;
1043
    hasSetValue();
1044
}
1045

1046
bool PropertyRotation::setValueIfChanged(const Base::Rotation &rot, double atol)
1047
{
1048
    if (_rot.isSame(rot, atol)) {
1049
        return false;
1050
    }
1051

1052
    setValue(rot);
1053
    return true;
1054
}
1055

1056

1057
const Base::Rotation & PropertyRotation::getValue() const
1058
{
1059
    return _rot;
1060
}
1061

1062
void PropertyRotation::getPaths(std::vector<ObjectIdentifier> &paths) const
1063
{
1064
    paths.push_back(ObjectIdentifier(*this)
1065
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Angle")));
1066
    paths.push_back(ObjectIdentifier(*this)
1067
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
1068
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("x")));
1069
    paths.push_back(ObjectIdentifier(*this)
1070
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
1071
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("y")));
1072
    paths.push_back(ObjectIdentifier(*this)
1073
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
1074
                    << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("z")));
1075
}
1076

1077
void PropertyRotation::setPathValue(const ObjectIdentifier &path, const boost::any &value)
1078
{
1079
    auto updateAxis = [=](int index, double coord) {
1080
        Base::Vector3d axis;
1081
        double angle;
1082
        _rot.getRawValue(axis, angle);
1083

1084
        axis[index] = coord;
1085
        setValue(Base::Rotation{axis, angle});
1086
    };
1087

1088
    std::string subpath = path.getSubPathStr();
1089
    if (subpath == ".Angle") {
1090
        double avalue = toDouble(value);
1091
        Property::setPathValue(path, Base::toRadians(avalue));
1092
    }
1093
    else if (subpath == ".Axis.x") {
1094
        updateAxis(0, toDouble(value));
1095
    }
1096
    else if (subpath == ".Axis.y") {
1097
        updateAxis(1, toDouble(value));
1098
    }
1099
    else if (subpath == ".Axis.z") {
1100
        updateAxis(2, toDouble(value));
1101
    }
1102
    else {
1103
        Property::setPathValue(path, value);
1104
    }
1105
}
1106

1107
const boost::any PropertyRotation::getPathValue(const ObjectIdentifier &path) const
1108
{
1109
    auto getAxis = [](const Base::Rotation& rot) {
1110
        Base::Vector3d axis;
1111
        double angle;
1112
        rot.getRawValue(axis, angle);
1113
        return axis;
1114
    };
1115
    std::string p = path.getSubPathStr();
1116

1117
    if (p == ".Angle") {
1118
        // Convert angle to degrees
1119
        return Base::Quantity(Base::toDegrees(boost::any_cast<double>(Property::getPathValue(path))), Unit::Angle);
1120
    }
1121
    else if (p == ".Axis.x") {
1122
        return getAxis(_rot).x;
1123
    }
1124
    else if (p == ".Axis.y") {
1125
        return getAxis(_rot).y;
1126
    }
1127
    else if (p == ".Axis.z") {
1128
        return getAxis(_rot).z;
1129
    }
1130
    else {
1131
        return Property::getPathValue(path);
1132
    }
1133
}
1134

1135
bool PropertyRotation::getPyPathValue(const ObjectIdentifier &path, Py::Object &res) const
1136
{
1137
    auto getAxis = [](const Base::Rotation& rot) {
1138
        Base::Vector3d axis;
1139
        double angle;
1140
        rot.getRawValue(axis, angle);
1141
        return axis;
1142
    };
1143

1144
    std::string p = path.getSubPathStr();
1145
    if (p == ".Angle") {
1146
        Base::Vector3d axis; double angle;
1147
        _rot.getValue(axis,angle);
1148
        res = Py::asObject(new QuantityPy(new Quantity(Base::toDegrees(angle),Unit::Angle)));
1149
        return true;
1150
    }
1151
    else if (p == ".Axis.x") {
1152
        res = Py::Float(getAxis(_rot).x);
1153
        return true;
1154
    }
1155
    else if (p == ".Axis.y") {
1156
        res = Py::Float(getAxis(_rot).y);
1157
        return true;
1158
    }
1159
    else if (p == ".Axis.z") {
1160
        res = Py::Float(getAxis(_rot).z);
1161
        return true;
1162
    }
1163

1164
    return false;
1165
}
1166

1167
PyObject *PropertyRotation::getPyObject()
1168
{
1169
    return new Base::RotationPy(new Base::Rotation(_rot));
1170
}
1171

1172
void PropertyRotation::setPyObject(PyObject *value)
1173
{
1174
    if (PyObject_TypeCheck(value, &(Base::MatrixPy::Type))) {
1175
        Base::MatrixPy *object = static_cast<Base::MatrixPy*>(value);
1176
        Base::Matrix4D mat = object->value();
1177
        Base::Rotation p;
1178
        p.setValue(mat);
1179
        setValue(p);
1180
    }
1181
    else if (PyObject_TypeCheck(value, &(Base::RotationPy::Type))) {
1182
        setValue(*static_cast<Base::RotationPy*>(value)->getRotationPtr());
1183
    }
1184
    else {
1185
        std::string error = std::string("type must be 'Matrix' or 'Rotation', not ");
1186
        error += value->ob_type->tp_name;
1187
        throw Base::TypeError(error);
1188
    }
1189
}
1190

1191
void PropertyRotation::Save (Base::Writer &writer) const
1192
{
1193
    Vector3d axis;
1194
    double rfAngle;
1195
    _rot.getRawValue(axis, rfAngle);
1196

1197
    writer.Stream() << writer.ind() << "<PropertyRotation";
1198
    writer.Stream() << " A=\"" <<  rfAngle << "\""
1199
                    << " Ox=\"" <<  axis.x << "\""
1200
                    << " Oy=\"" <<  axis.y << "\""
1201
                    << " Oz=\"" <<  axis.z << "\""
1202
                    << "/>\n";
1203
}
1204

1205
void PropertyRotation::Restore(Base::XMLReader &reader)
1206
{
1207
    reader.readElement("PropertyRotation");
1208
    aboutToSetValue();
1209

1210
    _rot = Rotation(Vector3d(reader.getAttributeAsFloat("Ox"),
1211
                             reader.getAttributeAsFloat("Oy"),
1212
                             reader.getAttributeAsFloat("Oz")),
1213
                             reader.getAttributeAsFloat("A"));
1214
    hasSetValue();
1215
}
1216

1217
Property *PropertyRotation::Copy() const
1218
{
1219
    PropertyRotation *p = new PropertyRotation();
1220
    p->_rot = _rot;
1221
    return p;
1222
}
1223

1224
void PropertyRotation::Paste(const Property &from)
1225
{
1226
    aboutToSetValue();
1227
    _rot = dynamic_cast<const PropertyRotation&>(from)._rot;
1228
    hasSetValue();
1229
}
1230

1231
// ------------------------------------------------------------
1232

1233
TYPESYSTEM_SOURCE_ABSTRACT(App::PropertyGeometry , App::Property)
1234

1235
PropertyGeometry::PropertyGeometry() = default;
1236

1237
PropertyGeometry::~PropertyGeometry() = default;
1238

1239
// ------------------------------------------------------------
1240

1241
TYPESYSTEM_SOURCE_ABSTRACT(App::PropertyComplexGeoData , App::PropertyGeometry)
1242

1243
PropertyComplexGeoData::PropertyComplexGeoData() = default;
1244

1245
PropertyComplexGeoData::~PropertyComplexGeoData() = default;
1246

1247
std::string PropertyComplexGeoData::getElementMapVersion(bool) const {
1248
    auto data = getComplexData();
1249
    if(!data)
1250
        return std::string();
1251
    auto owner = Base::freecad_dynamic_cast<DocumentObject>(getContainer());
1252
    std::ostringstream ss;
1253
    if(owner && owner->getDocument()
1254
        && owner->getDocument()->getStringHasher()==data->Hasher)
1255
        ss << "1.";
1256
    else
1257
        ss << "0.";
1258
    ss << data->getElementMapVersion();
1259
    return ss.str();
1260
}
1261

1262
bool PropertyComplexGeoData::checkElementMapVersion(const char * ver) const
1263
{
1264
    auto data = getComplexData();
1265
    if(!data)
1266
        return false;
1267
    auto owner = Base::freecad_dynamic_cast<DocumentObject>(getContainer());
1268
    std::ostringstream ss;
1269
    const char *prefix;
1270
    if(owner && owner->getDocument()
1271
        && owner->getDocument()->getStringHasher() == data->Hasher)
1272
        prefix = "1.";
1273
    else
1274
        prefix = "0.";
1275
    if (!boost::starts_with(ver, prefix))
1276
        return true;
1277
    return data->checkElementMapVersion(ver+2);
1278
}
1279

1280

1281
void PropertyComplexGeoData::afterRestore()
1282
{
1283
    auto data = getComplexData();
1284
    if (data && data->isRestoreFailed()) {
1285
        data->resetRestoreFailure();
1286
        auto owner = Base::freecad_dynamic_cast<DocumentObject>(getContainer());
1287
        if (owner &&
1288
            owner->getDocument() &&
1289
            !owner->getDocument()->testStatus(App::Document::PartialDoc)) {
1290
            owner->getDocument()->addRecomputeObject(owner);
1291
        }
1292
    }
1293
    PropertyGeometry::afterRestore();
1294
}

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

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

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

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