Materials: Correct DiffuseColor custom attribute

Custom attributes were modified to maintain the behaviour of setting
transparencies using the DiffuseColor alpha channels
This commit is contained in:
David Carter
2024-10-01 01:15:16 -04:00
committed by Chris Hennes
parent eab82038ba
commit d876e18808
8 changed files with 127 additions and 3 deletions

View File

@@ -3099,6 +3099,16 @@ float PropertyMaterialList::getTransparency(int index) const
return _lValueList[index].transparency;
}
std::vector<float> PropertyMaterialList::getTransparencies() const
{
std::vector<float> list;
for (auto& material : _lValueList) {
list.push_back(material.transparency);
}
return list;
}
Material PropertyMaterialList::getPyValue(PyObject* value) const
{
if (PyObject_TypeCheck(value, &(MaterialPy::Type))) {

View File

@@ -1176,6 +1176,7 @@ public:
float getTransparency() const;
float getTransparency(int index) const;
std::vector<float> getTransparencies() const;
PyObject* getPyObject() override;

View File

@@ -10,6 +10,7 @@ SET(MaterialScripts_Files
importFCMat.py
MaterialEditor.py
TestMaterialsApp.py
TestMaterialsGui.py
Templatematerial.yml
)
@@ -292,6 +293,7 @@ set(MaterialTest_Files
materialtests/TestModels.py
materialtests/TestMaterials.py
materialtests/TestMaterialCreation.py
materialtests/TestMaterialDocument.py
materialtests/TestMaterialFilter.py
)

View File

@@ -45,3 +45,5 @@ class MaterialWorkbench(Gui.Workbench):
Gui.addWorkbench(MaterialWorkbench())
FreeCAD.__unit_test__ += [ "TestMaterialsGui" ]

View File

@@ -0,0 +1,23 @@
#**************************************************************************
# Copyright (c) 2023 David Carter <dcarter@davidcarter.ca> *
# *
# This file is part of the FreeCAD CAx development system. *
# *
# This program is free software; you can redistribute it and/or modify *
# it under the terms of the GNU Lesser General Public License (LGPL) *
# as published by the Free Software Foundation; either version 2 of *
# the License, or (at your option) any later version. *
# for detail see the LICENCE text file. *
# *
# FreeCAD is distributed in the hope that it will be useful, *
# but WITHOUT ANY WARRANTY; without even the implied warranty of *
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# GNU Library General Public License for more details. *
# *
# You should have received a copy of the GNU Library General Public *
# License along with FreeCAD; if not, write to the Free Software *
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# USA *
#**************************************************************************
from materialtests.TestMaterialDocument import DocumentTestCases

View File

@@ -0,0 +1,69 @@
# ***************************************************************************
# * *
# * Copyright (c) 2024 FreeCAD Project Association *
# * *
# * This file is part of FreeCAD. *
# * *
# * FreeCAD is free software: you can redistribute it and/or modify it *
# * under the terms of the GNU Lesser General Public License as *
# * published by the Free Software Foundation, either version 2.1 of the *
# * License, or (at your option) any later version. *
# * *
# * FreeCAD is distributed in the hope that it will be useful, but *
# * WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
# * Lesser General Public License for more details. *
# * *
# * You should have received a copy of the GNU Lesser General Public *
# * License along with FreeCAD. If not, see *
# * <https://www.gnu.org/licenses/>. *
# * *
# ***************************************************************************
import unittest
import FreeCAD
class DocumentTestCases(unittest.TestCase):
"""
Test class for FreeCAD material tests that need a document
"""
def setUp(self):
self.doc = FreeCAD.newDocument()
def tearDown(self):
FreeCAD.closeDocument(self.doc.Name)
def testApplyDiffuseColorCheckShapeAppearance(self):
""" Test that applying a DiffuseColor with transparency results in a correct ShapeAppearance """
dif_col_1 = (1.0, 1.0, 0.0, 0.0) # yellow 0% transparent
dif_col_2 = (1.0, 0.0, 0.0, 0.5) # red 50% transparent
dif_col = [dif_col_1] + [dif_col_2] + 4 * [dif_col_1]
obj = self.doc.addObject("Part::Box")
vobj = obj.ViewObject
vobj.DiffuseColor = dif_col
self.assertEqual(
[m.DiffuseColor[:3] + (m.Transparency, ) for m in vobj.ShapeAppearance],
vobj.DiffuseColor
)
def testApplyShapeAppearanceCheckDiffuseColor(self):
""" Test that applying a ShapeAppearance with transparency results in a correct DiffuseColor """
sapp_1 = FreeCAD.Material()
sapp_1.DiffuseColor = (0.0, 1.0, 1.0, 1.0) # cyan
sapp_1.Transparency = 0.0 # 0% transparent
sapp_2 = FreeCAD.Material()
sapp_2.DiffuseColor = (0.0, 1.0, 0.0, 1.0) # green
sapp_2.Transparency = 0.3 # 30% transparent
sapp = [sapp_1] + [sapp_2] + 4 * [sapp_1]
obj = self.doc.addObject("Part::Box")
vobj = obj.ViewObject
vobj.ShapeAppearance = sapp
self.assertEqual(
[m.DiffuseColor[:3] + (m.Transparency, ) for m in vobj.ShapeAppearance],
vobj.DiffuseColor
)

View File

@@ -346,7 +346,6 @@ void ViewProviderPartExt::onChanged(const App::Property* prop)
std::vector<float> transparencies;
transparencies.resize(static_cast<int>(colors.size()));
for (int i = 0; i < static_cast<int>(colors.size()); i++) {
Base::Console().Log("%d: %f\n", i, colors[i].a);
transparencies[i] = colors[i].a;
colors[i].a = 1.0;
}

View File

@@ -51,7 +51,15 @@ PyObject* ViewProviderPartExtPy::getCustomAttributes(const char* attr) const
if (strcmp(attr, "DiffuseColor") == 0) {
// Get the color properties
App::PropertyColorList prop;
prop.setValues(vp->ShapeAppearance.getDiffuseColors());
// v0.21 used the alpha channel to store transparency values
std::vector<App::Color> colors = vp->ShapeAppearance.getDiffuseColors();
std::vector<float> transparencies = vp->ShapeAppearance.getTransparencies();
for (int i = 0; i < static_cast<int>(colors.size()); i++) {
colors[i].a = transparencies[i];
}
prop.setValues(colors);
return prop.getPyObject();
}
return nullptr;
@@ -64,7 +72,17 @@ int ViewProviderPartExtPy::setCustomAttributes(const char* attr, PyObject* obj)
// Set the color properties
App::PropertyColorList prop;
prop.setPyObject(obj);
vp->ShapeAppearance.setDiffuseColors(prop.getValues());
// v0.21 used the alpha channel to store transparency values
std::vector<App::Color> colors = prop.getValues();
std::vector<float> transparencies;
transparencies.resize(static_cast<int>(colors.size()));
for (int i = 0; i < static_cast<int>(colors.size()); i++) {
transparencies[i] = colors[i].a;
colors[i].a = 1.0;
}
vp->ShapeAppearance.setDiffuseColors(colors);
vp->ShapeAppearance.setTransparencies(transparencies);
return 1;
}
return 0;