Skip to content

Commit

Permalink
Merge pull request #13495 from wwmayer/material_colors
Browse files Browse the repository at this point in the history
Support to customize all material colors
  • Loading branch information
chennes committed Apr 22, 2024
2 parents 689a135 + d075a51 commit 2326d3c
Show file tree
Hide file tree
Showing 10 changed files with 549 additions and 70 deletions.
40 changes: 29 additions & 11 deletions src/App/Color.cpp
Expand Up @@ -82,20 +82,38 @@ Color& Color::setPackedValue(uint32_t rgba)
uint32_t Color::getPackedValue() const
{
// clang-format off
return (static_cast<uint32_t>(r * 255.0F + 0.5F) << 24 |
static_cast<uint32_t>(g * 255.0F + 0.5F) << 16 |
static_cast<uint32_t>(b * 255.0F + 0.5F) << 8 |
static_cast<uint32_t>(a * 255.0F + 0.5F));
return (static_cast<uint32_t>(std::lround(r * 255.0F)) << 24 |
static_cast<uint32_t>(std::lround(g * 255.0F)) << 16 |
static_cast<uint32_t>(std::lround(b * 255.0F)) << 8 |
static_cast<uint32_t>(std::lround(a * 255.0F)));
// clang-format on
}

void Color::setPackedRGB(uint32_t rgb)
{
// clang-format off
this->set(static_cast<float>((rgb >> 24) & 0xff) / 255.0F,
static_cast<float>((rgb >> 16) & 0xff) / 255.0F,
static_cast<float>((rgb >> 8) & 0xff) / 255.0F);
// clang-format on
}

uint32_t Color::getPackedRGB() const
{
// clang-format off
return (static_cast<uint32_t>(std::lround(r * 255.0F)) << 24 |
static_cast<uint32_t>(std::lround(g * 255.0F)) << 16 |
static_cast<uint32_t>(std::lround(b * 255.0F)) << 8);
// clang-format on
}

uint32_t Color::getPackedARGB() const
{
// clang-format off
return (static_cast<uint32_t>(a * 255.0F + 0.5F) << 24 |
static_cast<uint32_t>(r * 255.0F + 0.5F) << 16 |
static_cast<uint32_t>(g * 255.0F + 0.5F) << 8 |
static_cast<uint32_t>(b * 255.0F + 0.5F));
return (static_cast<uint32_t>(std::lround(a * 255.0F)) << 24 |
static_cast<uint32_t>(std::lround(r * 255.0F)) << 16 |
static_cast<uint32_t>(std::lround(g * 255.0F)) << 8 |
static_cast<uint32_t>(std::lround(b * 255.0F)));
// clang-format on
}

Expand All @@ -113,9 +131,9 @@ std::string Color::asHexString() const
{
std::stringstream ss;
ss << "#" << std::hex << std::uppercase << std::setfill('0')
<< std::setw(2) << int(r * 255.0F)
<< std::setw(2) << int(g * 255.0F)
<< std::setw(2) << int(b * 255.0F);
<< std::setw(2) << int(std::lround(r * 255.0F))
<< std::setw(2) << int(std::lround(g * 255.0F))
<< std::setw(2) << int(std::lround(b * 255.0F));
return ss.str();
}

Expand Down
18 changes: 16 additions & 2 deletions src/App/Color.h
Expand Up @@ -27,6 +27,7 @@
#ifdef __GNUC__
# include <cstdint>
#endif
#include <cmath>
#include <string>

#include <FCGlobal.h>
Expand Down Expand Up @@ -79,6 +80,14 @@ class AppExport Color
* \sa setPackedValue().
*/
uint32_t getPackedValue() const;
/**
* Returns color as a 32 bit packed unsigned int in the form 0xRRGGBB.
*/
uint32_t getPackedRGB() const;
/**
* Sets color as a 32 bit packed unsigned int in the form 0xRRGGBB.
*/
void setPackedRGB(uint32_t);
/**
* Returns color as a 32 bit packed unsigned int in the form 0xAARRGGBB.
*/
Expand Down Expand Up @@ -119,8 +128,13 @@ class AppExport Color
*
*/
template <typename T>
inline T asValue() const {
return(T(int(r*255.0f),int(g*255.0f),int(b*255.0f)));
inline T asValue() const
{
// clang-format off
return(T(int(std::lround(r * 255.0F)),
int(std::lround(g * 255.0F)),
int(std::lround(b * 255.0F))));
// clang-format on
}
/**
* returns color as hex color "#RRGGBB"
Expand Down
86 changes: 56 additions & 30 deletions src/Gui/ViewProviderGeometryObject.cpp
Expand Up @@ -23,6 +23,7 @@
#include "PreCompiled.h"

#ifndef _PreComp_
#include <random>
#include <Inventor/SoPickedPoint.h>
#include <Inventor/actions/SoRayPickAction.h>
#include <Inventor/actions/SoSearchAction.h>
Expand Down Expand Up @@ -70,10 +71,8 @@ const App::PropertyIntegerConstraint::Constraints intPercent = {0, 100, 5};

ViewProviderGeometryObject::ViewProviderGeometryObject()
{
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");

int initialTransparency = hGrp->GetInt("DefaultShapeTransparency", 0);
App::Material mat = getDefaultMaterial();
long initialTransparency = toPercent(mat.transparency);

static const char* dogroup = "Display Options";
static const char* sgroup = "Selection";
Expand All @@ -86,28 +85,6 @@ ViewProviderGeometryObject::ViewProviderGeometryObject()
"Set object transparency");
Transparency.setConstraints(&intPercent);

App::Material mat(App::Material::DEFAULT);
// This is handled in the material code when using the object appearance
bool randomColor = hGrp->GetBool("RandomColor", false);
float red {};
float green {};
float blue {};

if (randomColor) {
auto fMax = (float)RAND_MAX;
red = (float)rand() / fMax;
green = (float)rand() / fMax;
blue = (float)rand() / fMax;
}
else {
// Color = (204, 204, 230)
unsigned long shcol = hGrp->GetUnsigned("DefaultShapeColor", 3435980543UL);
red = ((shcol >> 24) & 0xff) / 255.0F;
green = ((shcol >> 16) & 0xff) / 255.0F;
blue = ((shcol >> 8) & 0xff) / 255.0F;
}
mat.diffuseColor = App::Color(red, green, blue);

ADD_PROPERTY_TYPE(ShapeAppearance, (mat), osgroup, App::Prop_None, "Shape appearrance");
ADD_PROPERTY_TYPE(BoundingBox, (false), dogroup, App::Prop_None, "Display object bounding box");
ADD_PROPERTY_TYPE(Selectable,
Expand All @@ -116,8 +93,7 @@ ViewProviderGeometryObject::ViewProviderGeometryObject()
App::Prop_None,
"Set if the object is selectable in the 3d view");

bool enableSel = hGrp->GetBool("EnableSelection", true);
Selectable.setValue(enableSel);
Selectable.setValue(isSelectionEnabled());

pcShapeMaterial = new SoMaterial;
setSoMaterial(mat);
Expand All @@ -139,6 +115,56 @@ ViewProviderGeometryObject::~ViewProviderGeometryObject()
pcBoundColor->unref();
}

App::Material ViewProviderGeometryObject::getDefaultMaterial() const
{
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");

auto getColor = [hGrp](const char* parameter, App::Color& color) {
uint32_t packed = color.getPackedRGB();
packed = hGrp->GetUnsigned(parameter, packed);
color.setPackedRGB(packed);
};
auto intRandom = [] (int min, int max) -> int {
static std::mt19937 generator;
std::uniform_int_distribution<int> distribution(min, max);
return distribution(generator);
};

App::Material mat(App::Material::DEFAULT);
mat.transparency = fromPercent(hGrp->GetInt("DefaultShapeTransparency", 0));
long shininess = toPercent(mat.shininess);
mat.shininess = fromPercent(hGrp->GetInt("DefaultShapeShininess", shininess));

// This is handled in the material code when using the object appearance
bool randomColor = hGrp->GetBool("RandomColor", false);

// diffuse color
if (randomColor) {
float red = static_cast<float>(intRandom(0, 255)) / 255.0F;
float green = static_cast<float>(intRandom(0, 255)) / 255.0F;
float blue = static_cast<float>(intRandom(0, 255)) / 255.0F;
mat.diffuseColor = App::Color(red, green, blue);
}
else {
// Color = (204, 204, 230) = 3435980543UL
getColor("DefaultShapeColor", mat.diffuseColor);
}

getColor("DefaultAmbientColor", mat.ambientColor);
getColor("DefaultEmissiveColor", mat.emissiveColor);
getColor("DefaultSpecularColor", mat.specularColor);

return mat;
}

bool ViewProviderGeometryObject::isSelectionEnabled() const
{
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
return hGrp->GetBool("EnableSelection", true);
}

void ViewProviderGeometryObject::onChanged(const App::Property* prop)
{
// Actually, the properties 'ShapeColor' and 'Transparency' are part of the property
Expand Down Expand Up @@ -257,8 +283,8 @@ unsigned long ViewProviderGeometryObject::getBoundColor() const
{
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
unsigned long bbcol =
hGrp->GetUnsigned("BoundingBoxColor", 4294967295UL); // white (255,255,255)
// white (255,255,255)
unsigned long bbcol = hGrp->GetUnsigned("BoundingBoxColor", 4294967295UL);
return bbcol;
}

Expand Down
6 changes: 5 additions & 1 deletion src/Gui/ViewProviderGeometryObject.h
Expand Up @@ -104,11 +104,15 @@ class GuiExport ViewProviderGeometryObject: public ViewProviderDragger

virtual unsigned long getBoundColor() const;

void setSoMaterial(const App::Material& source);
void handleChangedPropertyName(Base::XMLReader& reader,
const char* TypeName,
const char* PropName) override;

private:
void setSoMaterial(const App::Material& source);
App::Material getDefaultMaterial() const;
bool isSelectionEnabled() const;

protected:
SoMaterial* pcShapeMaterial {nullptr};
SoFCBoundingBox* pcBoundingBox {nullptr};
Expand Down
47 changes: 35 additions & 12 deletions src/Mod/Material/App/MaterialManager.cpp
Expand Up @@ -21,6 +21,7 @@

#include "PreCompiled.h"
#ifndef _PreComp_
#include <random>
#endif

#include <QDirIterator>
Expand Down Expand Up @@ -116,30 +117,52 @@ std::shared_ptr<Material> MaterialManager::defaultMaterial()

ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");

auto getColor = [hGrp](const char* parameter, App::Color& color) {
uint32_t packed = color.getPackedRGB();
packed = hGrp->GetUnsigned(parameter, packed);
color.setPackedRGB(packed);
};
auto intRandom = [] (int min, int max) -> int {
static std::mt19937 generator;
std::uniform_int_distribution<int> distribution(min, max);
return distribution(generator);
};

App::Material mat(App::Material::DEFAULT);
bool randomColor = hGrp->GetBool("RandomColor", false);
float r, g, b;

if (randomColor) {
auto fMax = (float)RAND_MAX;
r = (float)rand() / fMax;
g = (float)rand() / fMax;
b = (float)rand() / fMax;
float red = static_cast<float>(intRandom(0, 255)) / 255.0F;
float green = static_cast<float>(intRandom(0, 255)) / 255.0F;
float blue = static_cast<float>(intRandom(0, 255)) / 255.0F;
mat.diffuseColor = App::Color(red, green, blue);
}
else {
unsigned long shcol = hGrp->GetUnsigned("DefaultShapeColor", 3435980543UL);
r = ((shcol >> 24) & 0xff) / 255.0;
g = ((shcol >> 16) & 0xff) / 255.0;
b = ((shcol >> 8) & 0xff) / 255.0;
getColor("DefaultShapeColor", mat.diffuseColor);
}

int initialTransparency = hGrp->GetInt("DefaultShapeTransparency", 0);
getColor("DefaultAmbientColor", mat.ambientColor);
getColor("DefaultEmissiveColor", mat.emissiveColor);
getColor("DefaultSpecularColor", mat.specularColor);

long initialTransparency = hGrp->GetInt("DefaultShapeTransparency", 0);
long initialShininess = hGrp->GetInt("DefaultShapeShininess", 90);

auto material = manager.getMaterial(defaultMaterialUUID());
if (material->hasAppearanceModel(ModelUUIDs::ModelUUID_Rendering_Basic)) {
material->getAppearanceProperty(QString::fromLatin1("DiffuseColor"))
->setColor(App::Color(r, g, b));
->setColor(mat.diffuseColor);
material->getAppearanceProperty(QString::fromLatin1("AmbientColor"))
->setColor(mat.ambientColor);
material->getAppearanceProperty(QString::fromLatin1("EmissiveColor"))
->setColor(mat.emissiveColor);
material->getAppearanceProperty(QString::fromLatin1("SpecularColor"))
->setColor(mat.specularColor);
material->getAppearanceProperty(QString::fromLatin1("Transparency"))
->setFloat((float)initialTransparency / 100.0f);
->setFloat((float)initialTransparency / 100.0F);
material->getAppearanceProperty(QString::fromLatin1("Shininess"))
->setFloat((float)initialShininess / 100.0F);
}

return material;
Expand Down
1 change: 1 addition & 0 deletions src/Mod/Material/App/PreCompiled.h
Expand Up @@ -50,6 +50,7 @@
#include <fstream>
#include <map>
#include <memory>
#include <random>
#include <sstream>
#include <string>
#include <vector>
Expand Down
8 changes: 8 additions & 0 deletions src/Mod/Part/Gui/DlgSettingsObjectColor.cpp
Expand Up @@ -51,8 +51,12 @@ void DlgSettingsObjectColor::saveSettings()
{
// Part
ui->DefaultShapeColor->onSave();
ui->DefaultAmbientColor->onSave();
ui->DefaultEmissiveColor->onSave();
ui->DefaultSpecularColor->onSave();
ui->checkRandomColor->onSave();
ui->DefaultShapeTransparency->onSave();
ui->DefaultShapeShininess->onSave();
ui->DefaultShapeLineColor->onSave();
ui->DefaultShapeLineWidth->onSave();
ui->DefaultShapeVertexColor->onSave();
Expand All @@ -68,8 +72,12 @@ void DlgSettingsObjectColor::loadSettings()
{
// Part
ui->DefaultShapeColor->onRestore();
ui->DefaultAmbientColor->onRestore();
ui->DefaultEmissiveColor->onRestore();
ui->DefaultSpecularColor->onRestore();
ui->checkRandomColor->onRestore();
ui->DefaultShapeTransparency->onRestore();
ui->DefaultShapeShininess->onRestore();
ui->DefaultShapeLineColor->onRestore();
ui->DefaultShapeLineWidth->onRestore();
ui->DefaultShapeVertexColor->onRestore();
Expand Down

0 comments on commit 2326d3c

Please sign in to comment.