23
#include "PreCompiled.h"
25
#include <Base/Converter.h>
26
#include <Base/Exception.h>
27
#include <Base/Reader.h>
28
#include <Base/Stream.h>
29
#include <Base/VectorPy.h>
30
#include <Base/Writer.h>
32
#include "Core/Iterator.h"
33
#include "Core/MeshKernel.h"
34
#include "Core/MeshIO.h"
36
#include "MeshProperties.h"
43
TYPESYSTEM_SOURCE(Mesh::PropertyNormalList, App::PropertyLists)
44
TYPESYSTEM_SOURCE(Mesh::PropertyCurvatureList, App::PropertyLists)
45
TYPESYSTEM_SOURCE(Mesh::PropertyMaterial, App::Property)
46
TYPESYSTEM_SOURCE(Mesh::PropertyMeshKernel, App::PropertyComplexGeoData)
48
PropertyNormalList::PropertyNormalList() = default;
50
void PropertyNormalList::setSize(int newSize)
52
_lValueList.resize(newSize);
55
int PropertyNormalList::getSize() const
57
return static_cast<int>(_lValueList.size());
60
void PropertyNormalList::setValue(const Base::Vector3f& lValue)
63
_lValueList.resize(1);
64
_lValueList[0] = lValue;
68
void PropertyNormalList::setValue(float x, float y, float z)
71
_lValueList.resize(1);
72
_lValueList[0].Set(x, y, z);
76
void PropertyNormalList::setValues(const std::vector<Base::Vector3f>& values)
83
PyObject* PropertyNormalList::getPyObject()
85
PyObject* list = PyList_New(getSize());
87
for (int i = 0; i < getSize(); i++) {
88
PyList_SetItem(list, i, new Base::VectorPy(_lValueList[i]));
94
void PropertyNormalList::setPyObject(PyObject* value)
96
if (PyList_Check(value)) {
97
Py_ssize_t nSize = PyList_Size(value);
98
std::vector<Base::Vector3f> values;
101
for (Py_ssize_t i = 0; i < nSize; ++i) {
102
PyObject* item = PyList_GetItem(value, i);
103
App::PropertyVector val;
104
val.setPyObject(item);
105
values[i] = Base::convertTo<Base::Vector3f>(val.getValue());
110
else if (PyObject_TypeCheck(value, &(Base::VectorPy::Type))) {
111
Base::VectorPy* pcObject = static_cast<Base::VectorPy*>(value);
112
Base::Vector3d* val = pcObject->getVectorPtr();
113
setValue(Base::convertTo<Base::Vector3f>(*val));
115
else if (PyTuple_Check(value) && PyTuple_Size(value) == 3) {
116
App::PropertyVector val;
117
val.setPyObject(value);
118
setValue(Base::convertTo<Base::Vector3f>(val.getValue()));
121
std::string error = std::string("type must be 'Vector' or list of 'Vector', not ");
122
error += value->ob_type->tp_name;
123
throw Py::TypeError(error);
127
void PropertyNormalList::Save(Base::Writer& writer) const
129
if (!writer.isForceXML()) {
130
writer.Stream() << writer.ind() << "<VectorList file=\"" << writer.addFile(getName(), this)
131
<< "\"/>" << std::endl;
135
void PropertyNormalList::Restore(Base::XMLReader& reader)
137
reader.readElement("VectorList");
138
std::string file(reader.getAttribute("file"));
142
reader.addFile(file.c_str(), this);
146
void PropertyNormalList::SaveDocFile(Base::Writer& writer) const
148
Base::OutputStream str(writer.Stream());
149
uint32_t uCt = (uint32_t)getSize();
151
for (auto it : _lValueList) {
152
str << it.x << it.y << it.z;
156
void PropertyNormalList::RestoreDocFile(Base::Reader& reader)
158
Base::InputStream str(reader);
161
std::vector<Base::Vector3f> values(uCt);
162
for (auto& it : values) {
163
str >> it.x >> it.y >> it.z;
168
App::Property* PropertyNormalList::Copy() const
170
PropertyNormalList* p = new PropertyNormalList();
171
p->_lValueList = _lValueList;
175
void PropertyNormalList::Paste(const App::Property& from)
178
_lValueList = dynamic_cast<const PropertyNormalList&>(from)._lValueList;
182
unsigned int PropertyNormalList::getMemSize() const
184
return static_cast<unsigned int>(_lValueList.size() * sizeof(Base::Vector3f));
187
void PropertyNormalList::transformGeometry(const Base::Matrix4D& mat)
196
s[0] = sqrt(mat[0][0] * mat[0][0] + mat[0][1] * mat[0][1] + mat[0][2] * mat[0][2]);
197
s[1] = sqrt(mat[1][0] * mat[1][0] + mat[1][1] * mat[1][1] + mat[1][2] * mat[1][2]);
198
s[2] = sqrt(mat[2][0] * mat[2][0] + mat[2][1] * mat[2][1] + mat[2][2] * mat[2][2]);
203
for (unsigned short i = 0; i < 3; i++) {
204
for (unsigned short j = 0; j < 3; j++) {
205
rot[i][j] = mat[i][j] / s[i];
212
for (int ii = 0; ii < getSize(); ii++) {
213
set1Value(ii, rot * operator[](ii));
221
PropertyCurvatureList::PropertyCurvatureList() = default;
223
void PropertyCurvatureList::setValue(const CurvatureInfo& lValue)
226
_lValueList.resize(1);
227
_lValueList[0] = lValue;
231
void PropertyCurvatureList::setValues(const std::vector<CurvatureInfo>& lValues)
234
_lValueList = lValues;
238
std::vector<float> PropertyCurvatureList::getCurvature(int mode) const
240
const std::vector<Mesh::CurvatureInfo>& fCurvInfo = getValues();
241
std::vector<float> fValues;
242
fValues.reserve(fCurvInfo.size());
245
if (mode == MeanCurvature) {
246
for (const auto& it : fCurvInfo) {
247
fValues.push_back(0.5f * (it.fMaxCurvature + it.fMinCurvature));
251
else if (mode == GaussCurvature) {
252
for (const auto& it : fCurvInfo) {
253
fValues.push_back(it.fMaxCurvature * it.fMinCurvature);
257
else if (mode == MaxCurvature) {
258
for (const auto& it : fCurvInfo) {
259
fValues.push_back(it.fMaxCurvature);
263
else if (mode == MinCurvature) {
264
for (const auto& it : fCurvInfo) {
265
fValues.push_back(it.fMinCurvature);
269
else if (mode == AbsCurvature) {
270
for (const auto& it : fCurvInfo) {
271
if (fabs(it.fMaxCurvature) > fabs(it.fMinCurvature)) {
272
fValues.push_back(it.fMaxCurvature);
275
fValues.push_back(it.fMinCurvature);
283
void PropertyCurvatureList::transformGeometry(const Base::Matrix4D& mat)
292
s[0] = sqrt(mat[0][0] * mat[0][0] + mat[0][1] * mat[0][1] + mat[0][2] * mat[0][2]);
293
s[1] = sqrt(mat[1][0] * mat[1][0] + mat[1][1] * mat[1][1] + mat[1][2] * mat[1][2]);
294
s[2] = sqrt(mat[2][0] * mat[2][0] + mat[2][1] * mat[2][1] + mat[2][2] * mat[2][2]);
299
for (unsigned short i = 0; i < 3; i++) {
300
for (unsigned short j = 0; j < 3; j++) {
301
rot[i][j] = mat[i][j] / s[i];
308
for (int ii = 0; ii < getSize(); ii++) {
309
CurvatureInfo ci = operator[](ii);
310
ci.cMaxCurvDir = rot * ci.cMaxCurvDir;
311
ci.cMinCurvDir = rot * ci.cMinCurvDir;
312
_lValueList[ii] = ci;
318
void PropertyCurvatureList::Save(Base::Writer& writer) const
320
if (!writer.isForceXML()) {
321
writer.Stream() << writer.ind() << "<CurvatureList file=\""
322
<< writer.addFile(getName(), this) << "\"/>" << std::endl;
326
void PropertyCurvatureList::Restore(Base::XMLReader& reader)
328
reader.readElement("CurvatureList");
329
std::string file(reader.getAttribute("file"));
333
reader.addFile(file.c_str(), this);
337
void PropertyCurvatureList::SaveDocFile(Base::Writer& writer) const
339
Base::OutputStream str(writer.Stream());
340
uint32_t uCt = (uint32_t)getSize();
342
for (const auto& it : _lValueList) {
343
str << it.fMaxCurvature << it.fMinCurvature;
344
str << it.cMaxCurvDir.x << it.cMaxCurvDir.y << it.cMaxCurvDir.z;
345
str << it.cMinCurvDir.x << it.cMinCurvDir.y << it.cMinCurvDir.z;
349
void PropertyCurvatureList::RestoreDocFile(Base::Reader& reader)
351
Base::InputStream str(reader);
354
std::vector<CurvatureInfo> values(uCt);
355
for (auto& it : values) {
356
str >> it.fMaxCurvature >> it.fMinCurvature;
357
str >> it.cMaxCurvDir.x >> it.cMaxCurvDir.y >> it.cMaxCurvDir.z;
358
str >> it.cMinCurvDir.x >> it.cMinCurvDir.y >> it.cMinCurvDir.z;
364
PyObject* PropertyCurvatureList::getPyObject()
367
for (const auto& it : _lValueList) {
369
tuple.setItem(0, Py::Float(it.fMaxCurvature));
370
tuple.setItem(1, Py::Float(it.fMinCurvature));
372
maxDir.setItem(0, Py::Float(it.cMaxCurvDir.x));
373
maxDir.setItem(1, Py::Float(it.cMaxCurvDir.y));
374
maxDir.setItem(2, Py::Float(it.cMaxCurvDir.z));
375
tuple.setItem(2, maxDir);
377
minDir.setItem(0, Py::Float(it.cMinCurvDir.x));
378
minDir.setItem(1, Py::Float(it.cMinCurvDir.y));
379
minDir.setItem(2, Py::Float(it.cMinCurvDir.z));
380
tuple.setItem(3, minDir);
384
return Py::new_reference_to(list);
387
void PropertyCurvatureList::setPyObject(PyObject* )
389
throw Base::AttributeError(std::string("This attribute is read-only"));
392
App::Property* PropertyCurvatureList::Copy() const
394
PropertyCurvatureList* p = new PropertyCurvatureList();
395
p->_lValueList = _lValueList;
399
void PropertyCurvatureList::Paste(const App::Property& from)
402
_lValueList = dynamic_cast<const PropertyCurvatureList&>(from)._lValueList;
408
const MeshCore::Material& PropertyMaterial::getValue() const
413
MeshCore::MeshIO::Binding PropertyMaterial::getBinding() const
415
return _material.binding;
418
const std::vector<App::Color>& PropertyMaterial::getAmbientColor() const
420
return _material.ambientColor;
423
const std::vector<App::Color>& PropertyMaterial::getDiffuseColor() const
425
return _material.diffuseColor;
428
const std::vector<App::Color>& PropertyMaterial::getSpecularColor() const
430
return _material.specularColor;
433
const std::vector<App::Color>& PropertyMaterial::getEmissiveColor() const
435
return _material.emissiveColor;
438
const std::vector<float>& PropertyMaterial::getShininess() const
440
return _material.shininess;
443
const std::vector<float>& PropertyMaterial::getTransparency() const
445
return _material.transparency;
448
void PropertyMaterial::setValue(const MeshCore::Material& value)
455
void PropertyMaterial::setAmbientColor(const std::vector<App::Color>& value)
458
_material.ambientColor = value;
462
void PropertyMaterial::setDiffuseColor(const std::vector<App::Color>& value)
465
_material.diffuseColor = value;
469
void PropertyMaterial::setSpecularColor(const std::vector<App::Color>& value)
472
_material.specularColor = value;
476
void PropertyMaterial::setEmissiveColor(const std::vector<App::Color>& value)
479
_material.emissiveColor = value;
483
void PropertyMaterial::setShininess(const std::vector<float>& value)
486
_material.shininess = value;
490
void PropertyMaterial::setTransparency(const std::vector<float>& value)
493
_material.transparency = value;
497
void PropertyMaterial::setBinding(MeshCore::MeshIO::Binding bind)
500
_material.binding = bind;
504
PyObject* PropertyMaterial::getPyObject()
506
auto getColorList = [](const std::vector<App::Color>& color) {
508
for (const auto& it : color) {
509
list.append(Py::TupleN(Py::Float(it.r), Py::Float(it.g), Py::Float(it.b)));
514
auto getFloatList = [](const std::vector<float>& value) {
516
for (auto it : value) {
517
list.append(Py::Float(it));
523
dict.setItem("binding", Py::Long(static_cast<int>(_material.binding)));
524
dict.setItem("ambientColor", getColorList(_material.ambientColor));
525
dict.setItem("diffuseColor", getColorList(_material.diffuseColor));
526
dict.setItem("specularColor", getColorList(_material.specularColor));
527
dict.setItem("emissiveColor", getColorList(_material.emissiveColor));
528
dict.setItem("shininess", getFloatList(_material.shininess));
529
dict.setItem("transparency", getFloatList(_material.transparency));
531
return Py::new_reference_to(dict);
534
void PropertyMaterial::setPyObject(PyObject* obj)
536
auto getColorList = [](const Py::Dict& dict, const std::string& key) {
537
std::vector<App::Color> color;
538
if (dict.hasKey(key)) {
539
Py::Sequence list(dict.getItem(key));
540
color.reserve(list.size());
541
for (const auto& it : list) {
542
Py::Sequence tuple(it);
543
float r = static_cast<float>(Py::Float(tuple[0]));
544
float g = static_cast<float>(Py::Float(tuple[1]));
545
float b = static_cast<float>(Py::Float(tuple[2]));
546
color.emplace_back(r, g, b);
552
auto getFloatList = [](const Py::Dict& dict, const std::string& key) {
553
std::vector<float> value;
554
if (dict.hasKey(key)) {
555
Py::Sequence list(dict.getItem(key));
556
value.reserve(list.size());
557
for (const auto& it : list) {
558
value.push_back(static_cast<float>(Py::Float(it)));
565
MeshCore::Material material;
568
if (dict.hasKey("binding")) {
569
Py::Long binding(dict.getItem("binding"));
570
int bind = static_cast<int>(binding);
571
material.binding = static_cast<MeshCore::MeshIO::Binding>(bind);
574
material.ambientColor = getColorList(dict, "ambientColor");
575
material.diffuseColor = getColorList(dict, "diffuseColor");
576
material.specularColor = getColorList(dict, "specularColor");
577
material.emissiveColor = getColorList(dict, "emissiveColor");
578
material.shininess = getFloatList(dict, "shininess");
579
material.transparency = getFloatList(dict, "transparency");
583
catch (Py::Exception& e) {
585
throw Base::TypeError("Not a dict with expected keys");
589
void PropertyMaterial::Save(Base::Writer& writer) const
591
if (!writer.isForceXML()) {
592
writer.Stream() << writer.ind() << "<Material file=\"" << writer.addFile(getName(), this)
593
<< "\"/>" << std::endl;
597
void PropertyMaterial::Restore(Base::XMLReader& reader)
599
reader.readElement("Material");
600
if (reader.hasAttribute("file")) {
601
std::string file(reader.getAttribute("file"));
605
reader.addFile(file.c_str(), this);
610
void PropertyMaterial::SaveDocFile(Base::Writer& writer) const
612
Base::OutputStream str(writer.Stream());
613
auto saveColor = [&str](const std::vector<App::Color>& color) {
614
uint32_t count = static_cast<uint32_t>(color.size());
616
for (const auto& it : color) {
617
str << it.getPackedValue();
621
auto saveFloat = [&str](const std::vector<float>& value) {
622
uint32_t count = static_cast<uint32_t>(value.size());
624
for (const auto& it : value) {
629
uint32_t bind = static_cast<uint32_t>(_material.binding);
632
saveColor(_material.ambientColor);
633
saveColor(_material.diffuseColor);
634
saveColor(_material.specularColor);
635
saveColor(_material.emissiveColor);
636
saveFloat(_material.shininess);
637
saveFloat(_material.transparency);
640
void PropertyMaterial::RestoreDocFile(Base::Reader& reader)
642
Base::InputStream str(reader);
643
auto restoreColor = [&str](std::vector<App::Color>& color) {
647
for (auto& it : color) {
650
it.setPackedValue(value);
654
auto restoreFloat = [&str](std::vector<float>& value) {
658
for (auto& it : value) {
665
MeshCore::Material material;
669
material.binding = static_cast<MeshCore::MeshIO::Binding>(bind);
671
restoreColor(material.ambientColor);
672
restoreColor(material.diffuseColor);
673
restoreColor(material.specularColor);
674
restoreColor(material.emissiveColor);
675
restoreFloat(material.shininess);
676
restoreFloat(material.transparency);
681
const char* PropertyMaterial::getEditorName() const
686
App::Property* PropertyMaterial::Copy() const
688
PropertyMaterial* prop = new PropertyMaterial();
689
prop->_material = _material;
693
void PropertyMaterial::Paste(const Property& from)
696
using ObjectType = std::remove_pointer<decltype(this)>::type;
697
_material = dynamic_cast<const ObjectType&>(from)._material;
701
unsigned int PropertyMaterial::getMemSize() const
703
auto size = (_material.ambientColor.size() + _material.diffuseColor.size()
704
+ _material.emissiveColor.size() + _material.specularColor.size())
706
+ (_material.shininess.size() + _material.transparency.size()) * sizeof(float)
707
+ _material.library.size() + sizeof(_material);
708
return static_cast<unsigned int>(size);
711
bool PropertyMaterial::isSame(const App::Property& other) const
713
if (&other == this) {
716
return getTypeId() == other.getTypeId()
717
&& getValue() == static_cast<decltype(this)>(&other)->getValue();
722
PropertyMeshKernel::PropertyMeshKernel()
723
: _meshObject(new MeshObject())
731
PropertyMeshKernel::~PropertyMeshKernel()
736
meshPyObject->parentProperty = nullptr;
737
Py_DECREF(meshPyObject);
741
void PropertyMeshKernel::setValuePtr(MeshObject* mesh)
745
Base::Reference<MeshObject> tmp(_meshObject);
751
void PropertyMeshKernel::setValue(const MeshObject& mesh)
758
void PropertyMeshKernel::setValue(const MeshCore::MeshKernel& mesh)
761
_meshObject->setKernel(mesh);
765
void PropertyMeshKernel::swapMesh(MeshObject& mesh)
768
_meshObject->swap(mesh);
772
void PropertyMeshKernel::swapMesh(MeshCore::MeshKernel& mesh)
775
_meshObject->swap(mesh);
779
const MeshObject& PropertyMeshKernel::getValue() const
784
const MeshObject* PropertyMeshKernel::getValuePtr() const
786
return static_cast<MeshObject*>(_meshObject);
789
const Data::ComplexGeoData* PropertyMeshKernel::getComplexData() const
791
return static_cast<MeshObject*>(_meshObject);
794
Base::BoundBox3d PropertyMeshKernel::getBoundingBox() const
796
return _meshObject->getBoundBox();
799
unsigned int PropertyMeshKernel::getMemSize() const
801
unsigned int size = 0;
802
size += _meshObject->getMemSize();
807
MeshObject* PropertyMeshKernel::startEditing()
810
return static_cast<MeshObject*>(_meshObject);
813
void PropertyMeshKernel::finishEditing()
818
void PropertyMeshKernel::transformGeometry(const Base::Matrix4D& rclMat)
821
_meshObject->transformGeometry(rclMat);
825
void PropertyMeshKernel::setPointIndices(
826
const std::vector<std::pair<PointIndex, Base::Vector3f>>& inds)
829
MeshCore::MeshKernel& kernel = _meshObject->getKernel();
830
for (const auto& it : inds) {
831
kernel.SetPoint(it.first, it.second);
836
void PropertyMeshKernel::setTransform(const Base::Matrix4D& rclTrf)
838
_meshObject->setTransform(rclTrf);
841
Base::Matrix4D PropertyMeshKernel::getTransform() const
843
return _meshObject->getTransform();
846
PyObject* PropertyMeshKernel::getPyObject()
849
meshPyObject = new MeshPy(
852
meshPyObject->setConst();
853
meshPyObject->parentProperty = this;
856
Py_INCREF(meshPyObject);
860
void PropertyMeshKernel::setPyObject(PyObject* value)
862
if (PyObject_TypeCheck(value, &(MeshPy::Type))) {
863
MeshPy* mesh = static_cast<MeshPy*>(value);
865
if (&(*this->_meshObject) != mesh->getMeshObjectPtr()) {
867
setValue(*(mesh->getMeshObjectPtr()));
870
else if (PyList_Check(value)) {
872
Py::List triangles(value);
873
MeshObject* mesh = MeshObject::createMeshFromList(triangles);
877
std::string error = std::string("type must be 'Mesh', not ");
878
error += value->ob_type->tp_name;
879
throw Base::TypeError(error);
883
void PropertyMeshKernel::Save(Base::Writer& writer) const
885
if (writer.isForceXML()) {
886
writer.Stream() << writer.ind() << "<Mesh>" << std::endl;
887
MeshCore::MeshOutput saver(_meshObject->getKernel());
888
saver.SaveXML(writer);
891
writer.Stream() << writer.ind() << "<Mesh file=\"" << writer.addFile("MeshKernel.bms", this)
892
<< "\"/>" << std::endl;
896
void PropertyMeshKernel::Restore(Base::XMLReader& reader)
898
reader.readElement("Mesh");
899
std::string file(reader.getAttribute("file"));
903
MeshCore::MeshKernel kernel;
904
MeshCore::MeshInput restorer(kernel);
905
restorer.LoadXML(reader);
908
MeshCore::MeshPointArray points;
909
MeshCore::MeshFacetArray facets;
910
kernel.Adopt(points, facets);
913
_meshObject->getKernel().Adopt(points, facets);
918
reader.addFile(file.c_str(), this);
922
void PropertyMeshKernel::SaveDocFile(Base::Writer& writer) const
924
_meshObject->save(writer.Stream());
927
void PropertyMeshKernel::RestoreDocFile(Base::Reader& reader)
930
_meshObject->load(reader);
934
App::Property* PropertyMeshKernel::Copy() const
937
PropertyMeshKernel* prop = new PropertyMeshKernel();
938
*(prop->_meshObject) = *(this->_meshObject);
942
void PropertyMeshKernel::Paste(const App::Property& from)
946
const PropertyMeshKernel& prop = dynamic_cast<const PropertyMeshKernel&>(from);
947
*(this->_meshObject) = *(prop._meshObject);