Mesh: use PropertyMaterial in view provider

This commit is contained in:
wmayer
2022-10-23 23:31:04 +02:00
parent 48de48ea4b
commit f3440f403f
3 changed files with 107 additions and 66 deletions

View File

@@ -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<unsigned int>(size);
}

View File

@@ -24,7 +24,6 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <algorithm>
# include <cstdlib>
# include <QAction>
# include <QMenu>
@@ -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<Mesh::Feature*>(pcObject)->Mesh;
const Mesh::MeshObject& mesh = meshProp.getValue();
int numPoints = static_cast<int>(mesh.countPoints());
int numFacets = static_cast<int>(mesh.countFacets());
const Mesh::PropertyMeshKernel& meshProp = static_cast<Mesh::Feature*>(pcObject)->Mesh;
const Mesh::MeshObject& mesh = meshProp.getValue();
int numPoints = static_cast<int>(mesh.countPoints());
int numFacets = static_cast<int>(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<App::Color>& val = prop->getValues();
pcShapeMaterial->diffuseColor.setNum(val.size());
SbColor* col = pcShapeMaterial->diffuseColor.startEditing();
std::size_t i=0;
for (std::vector<App::Color>::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<App::Color>& val = prop->getValues();
setDiffuseColor(prop->getValues());
}
pcShapeMaterial->diffuseColor.setNum(val.size());
SbColor* col = pcShapeMaterial->diffuseColor.startEditing();
void ViewProviderMesh::setColorField(const std::vector<App::Color>& val, SoMFColor& field)
{
field.setNum(val.size());
SbColor* col = field.startEditing();
std::size_t i=0;
for (std::vector<App::Color>::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<App::Color>& val)
{
setColorField(val, pcShapeMaterial->ambientColor);
}
void ViewProviderMesh::setDiffuseColor(const std::vector<App::Color>& val)
{
setColorField(val, pcShapeMaterial->diffuseColor);
}
void ViewProviderMesh::setSpecularColor(const std::vector<App::Color>& val)
{
setColorField(val, pcShapeMaterial->specularColor);
}
void ViewProviderMesh::setEmissiveColor(const std::vector<App::Color>& 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<App::PropertyFloatList*>(prop);
return transp;
std::map<std::string,App::Property*> Map;
pcObject->getPropertyMap(Map);
for (std::map<std::string,App::Property*>::iterator it = Map.begin(); it != Map.end(); ++it) {
Base::Type type = it->second->getTypeId();
if (type == Mesh::PropertyMaterial::getClassTypeId()) {
Mesh::PropertyMaterial* material = static_cast<Mesh::PropertyMaterial*>(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<Mesh::Feature*>(pcObject)->Mesh;
const Mesh::MeshObject& mesh = meshProp.getValue();
int numFacets = static_cast<int>(mesh.countFacets());
if (prop->getSize() == numFacets) {
const auto& values = prop->getValue();
std::vector<float> 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<float>(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) {

View File

@@ -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<App::Color>&, SoMFColor&);
void setAmbientColor(const std::vector<App::Color>&);
void setDiffuseColor(const std::vector<App::Color>&);
void setSpecularColor(const std::vector<App::Color>&);
void setEmissiveColor(const std::vector<App::Color>&);
virtual SoShape* getShapeNode() const;
virtual SoNode* getCoordNode() const;