From f3440f403f910bf9d8998b469e8721df59b7095c Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 23 Oct 2022 23:31:04 +0200 Subject: [PATCH] Mesh: use PropertyMaterial in view provider --- src/Mod/Mesh/App/MeshProperties.cpp | 14 +-- src/Mod/Mesh/Gui/ViewProvider.cpp | 146 +++++++++++++++++----------- src/Mod/Mesh/Gui/ViewProvider.h | 13 ++- 3 files changed, 107 insertions(+), 66 deletions(-) diff --git a/src/Mod/Mesh/App/MeshProperties.cpp b/src/Mod/Mesh/App/MeshProperties.cpp index a35a345800..06857f9dc2 100644 --- a/src/Mod/Mesh/App/MeshProperties.cpp +++ b/src/Mod/Mesh/App/MeshProperties.cpp @@ -724,13 +724,13 @@ void PropertyMaterial::Paste(const Property& from) unsigned int PropertyMaterial::getMemSize() const { - auto size = _material.ambientColor.size() + - _material.diffuseColor.size() + - _material.emissiveColor.size() + - _material.shininess.size() + - _material.specularColor.size() + - _material.transparency.size() + - _material.library.size() + sizeof(_material); + auto size = (_material.ambientColor.size() + + _material.diffuseColor.size() + + _material.emissiveColor.size() + + _material.specularColor.size()) * sizeof(App::Color) + + (_material.shininess.size() + + _material.transparency.size()) * sizeof(float) + + _material.library.size() + sizeof(_material); return static_cast(size); } diff --git a/src/Mod/Mesh/Gui/ViewProvider.cpp b/src/Mod/Mesh/Gui/ViewProvider.cpp index 8b906739ff..0a1ef78adf 100644 --- a/src/Mod/Mesh/Gui/ViewProvider.cpp +++ b/src/Mod/Mesh/Gui/ViewProvider.cpp @@ -24,7 +24,6 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include # include # include # include @@ -383,7 +382,6 @@ void ViewProviderMesh::onChanged(const App::Property* prop) } else if (prop == &Coloring) { tryColorPerVertexOrFace(Coloring.getValue()); - tryTransparency(Coloring.getValue()); } else if (prop == &SelectionStyle) { pcHighlight->style = SelectionStyle.getValue() ? Gui::SoFCSelection::BOX @@ -492,7 +490,7 @@ void ViewProviderMesh::attach(App::DocumentObject *pcFeat) pcFlatWireRoot->addChild(pcShapeGroup); addDisplayMaskMode(pcFlatWireRoot, "Flat Lines"); - if (getColorProperty()) { + if (getColorProperty() || getMaterialProperty()) { Coloring.setStatus(App::Property::Hidden, false); } } @@ -505,6 +503,9 @@ void ViewProviderMesh::updateData(const App::Property* prop) if (prop->getTypeId() == App::PropertyColorList::getClassTypeId()) { Coloring.setStatus(App::Property::Hidden, false); } + else if (prop->getTypeId() == Mesh::PropertyMaterial::getClassTypeId()) { + Coloring.setStatus(App::Property::Hidden, false); + } } QIcon ViewProviderMesh::getIcon() const @@ -533,13 +534,12 @@ App::PropertyColorList* ViewProviderMesh::getColorProperty() const void ViewProviderMesh::tryColorPerVertexOrFace(bool on) { if (on) { - App::PropertyColorList* colors = getColorProperty(); - if (colors) { - const Mesh::PropertyMeshKernel& meshProp = static_cast(pcObject)->Mesh; - const Mesh::MeshObject& mesh = meshProp.getValue(); - int numPoints = static_cast(mesh.countPoints()); - int numFacets = static_cast(mesh.countFacets()); + const Mesh::PropertyMeshKernel& meshProp = static_cast(pcObject)->Mesh; + const Mesh::MeshObject& mesh = meshProp.getValue(); + int numPoints = static_cast(mesh.countPoints()); + int numFacets = static_cast(mesh.countFacets()); + if (App::PropertyColorList* colors = getColorProperty()) { if (colors->getSize() == numPoints) { setColorPerVertex(colors); } @@ -547,87 +547,119 @@ void ViewProviderMesh::tryColorPerVertexOrFace(bool on) setColorPerFace(colors); } } + else if (Mesh::PropertyMaterial* material = getMaterialProperty()) { + auto bind = material->getBinding(); + if (bind == MeshCore::MeshIO::Binding::OVERALL) { + pcMatBinding->value = SoMaterialBinding::OVERALL; + + if (!material->getDiffuseColor().empty()) { + auto c = material->getDiffuseColor()[0]; + pcShapeMaterial->diffuseColor.setValue(c.r, c.g, c.b); + } + if (!material->getTransparency().empty()) { + pcShapeMaterial->transparency.setValue(material->getTransparency()[0]); + } + } + else if (bind == MeshCore::MeshIO::Binding::PER_VERTEX) { + if (material->getDiffuseColor().size() == std::size_t(numPoints)) { + pcMatBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED; + setDiffuseColor(material->getDiffuseColor()); + } + } + else if (bind == MeshCore::MeshIO::Binding::PER_FACE) { + if (material->getAmbientColor().size() == std::size_t(numFacets)) { + pcMatBinding->value = SoMaterialBinding::PER_FACE; + setAmbientColor(material->getAmbientColor()); + } + if (material->getDiffuseColor().size() == std::size_t(numFacets)) { + pcMatBinding->value = SoMaterialBinding::PER_FACE; + setDiffuseColor(material->getDiffuseColor()); + } + if (material->getEmissiveColor().size() == std::size_t(numFacets)) { + pcMatBinding->value = SoMaterialBinding::PER_FACE; + setEmissiveColor(material->getEmissiveColor()); + } + if (material->getSpecularColor().size() == std::size_t(numFacets)) { + pcMatBinding->value = SoMaterialBinding::PER_FACE; + setSpecularColor(material->getSpecularColor()); + } + if (material->getTransparency().size() == std::size_t(numFacets)) { + pcMatBinding->value = SoMaterialBinding::PER_FACE; + setFacetTransparency(material->getTransparency()); + } + } + } } else { pcMatBinding->value = SoMaterialBinding::OVERALL; const App::Color& c = ShapeColor.getValue(); pcShapeMaterial->diffuseColor.setValue(c.r,c.g,c.b); + pcShapeMaterial->transparency.setValue(Transparency.getValue()/100.0f); } } void ViewProviderMesh::setColorPerVertex(const App::PropertyColorList* prop) { pcMatBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED; - const std::vector& val = prop->getValues(); - - pcShapeMaterial->diffuseColor.setNum(val.size()); - SbColor* col = pcShapeMaterial->diffuseColor.startEditing(); - - std::size_t i=0; - for (std::vector::const_iterator it = val.begin(); it != val.end(); ++it) { - col[i++].setValue(it->r, it->g, it->b); - } - - pcShapeMaterial->diffuseColor.finishEditing(); + setDiffuseColor(prop->getValues()); } void ViewProviderMesh::setColorPerFace(const App::PropertyColorList* prop) { pcMatBinding->value = SoMaterialBinding::PER_FACE; - const std::vector& val = prop->getValues(); + setDiffuseColor(prop->getValues()); +} - pcShapeMaterial->diffuseColor.setNum(val.size()); - SbColor* col = pcShapeMaterial->diffuseColor.startEditing(); +void ViewProviderMesh::setColorField(const std::vector& val, SoMFColor& field) +{ + field.setNum(val.size()); + SbColor* col = field.startEditing(); std::size_t i=0; for (std::vector::const_iterator it = val.begin(); it != val.end(); ++it) { col[i++].setValue(it->r, it->g, it->b); } - pcShapeMaterial->diffuseColor.finishEditing(); + field.finishEditing(); } -App::PropertyFloatList* ViewProviderMesh::getTransparencyProperty() const +void ViewProviderMesh::setAmbientColor(const std::vector& val) +{ + setColorField(val, pcShapeMaterial->ambientColor); +} + +void ViewProviderMesh::setDiffuseColor(const std::vector& val) +{ + setColorField(val, pcShapeMaterial->diffuseColor); +} + +void ViewProviderMesh::setSpecularColor(const std::vector& val) +{ + setColorField(val, pcShapeMaterial->specularColor); +} + +void ViewProviderMesh::setEmissiveColor(const std::vector& val) +{ + setColorField(val, pcShapeMaterial->emissiveColor); +} + +Mesh::PropertyMaterial* ViewProviderMesh::getMaterialProperty() const { if (pcObject) { - App::Property* prop = pcObject->getPropertyByName("Transparency"); - if (prop && prop->getTypeId() == App::PropertyFloatList::getClassTypeId()) { - App::PropertyFloatList* transp = static_cast(prop); - return transp; + std::map Map; + pcObject->getPropertyMap(Map); + for (std::map::iterator it = Map.begin(); it != Map.end(); ++it) { + Base::Type type = it->second->getTypeId(); + if (type == Mesh::PropertyMaterial::getClassTypeId()) { + Mesh::PropertyMaterial* material = static_cast(it->second); + return material; + } } } return nullptr; // no such property found } -void ViewProviderMesh::tryTransparency(bool on) -{ - if (on) { - App::PropertyFloatList* prop = getTransparencyProperty(); - if (prop) { - const Mesh::PropertyMeshKernel& meshProp = static_cast(pcObject)->Mesh; - const Mesh::MeshObject& mesh = meshProp.getValue(); - int numFacets = static_cast(mesh.countFacets()); - - if (prop->getSize() == numFacets) { - const auto& values = prop->getValue(); - std::vector transp; - transp.reserve(values.size()); - std::transform(values.cbegin(), values.cend(), std::back_inserter(transp), [](double v) -> float { - // force values in range [0, 1] - return std::clamp(v, 0.0f, 1.0f); - }); - setFacetTransparency(transp); - } - } - } - else { - pcMatBinding->value = SoMaterialBinding::OVERALL; - float trans = Transparency.getValue()/100.0f; - pcShapeMaterial->transparency.setValue(trans); - } -} - void ViewProviderMesh::setDisplayMode(const char* ModeName) { if (strcmp("Shaded",ModeName)==0) { diff --git a/src/Mod/Mesh/Gui/ViewProvider.h b/src/Mod/Mesh/Gui/ViewProvider.h index a9afed61f2..e0e4990452 100644 --- a/src/Mod/Mesh/Gui/ViewProvider.h +++ b/src/Mod/Mesh/Gui/ViewProvider.h @@ -43,6 +43,7 @@ class SoCoordinate3; class SoIndexedFaceSet; class SoShapeHints; class SoMaterialBinding; +class SoMFColor; class SoCamera; class SoAction; class SbViewportRegion; @@ -70,6 +71,9 @@ namespace MeshCore { struct Material; } +namespace Mesh { +class PropertyMaterial; +} namespace MeshGui { class SoFCMeshObjectNode; @@ -196,11 +200,16 @@ protected: void highlightColors(); bool canHighlightColors() const; App::PropertyColorList* getColorProperty() const; - App::PropertyFloatList* getTransparencyProperty() const; + Mesh::PropertyMaterial* getMaterialProperty() const; void tryColorPerVertexOrFace(bool); void setColorPerVertex(const App::PropertyColorList*); void setColorPerFace(const App::PropertyColorList*); - void tryTransparency(bool); + + void setColorField(const std::vector&, SoMFColor&); + void setAmbientColor(const std::vector&); + void setDiffuseColor(const std::vector&); + void setSpecularColor(const std::vector&); + void setEmissiveColor(const std::vector&); virtual SoShape* getShapeNode() const; virtual SoNode* getCoordNode() const;